Refactored drawfolders function of CompactUI

This commit is contained in:
CakeAndBanana
2025-09-26 05:14:39 +02:00
parent c182d10a0a
commit f6784fdf28

View File

@@ -141,7 +141,7 @@ public class CompactUi : WindowMediatorSubscriberBase
},
};
_drawFolders = [.. GetDrawFolders()];
_drawFolders = [.. DrawFolders];
#if DEBUG
string dev = "Dev Build";
@@ -158,7 +158,7 @@ public class CompactUi : WindowMediatorSubscriberBase
Mediator.Subscribe<CutsceneEndMessage>(this, (_) => UiSharedService_GposeEnd());
Mediator.Subscribe<DownloadStartedMessage>(this, (msg) => _currentDownloads[msg.DownloadId] = msg.DownloadStatus);
Mediator.Subscribe<DownloadFinishedMessage>(this, (msg) => _currentDownloads.TryRemove(msg.DownloadId, out _));
Mediator.Subscribe<RefreshUiMessage>(this, (msg) => _drawFolders = GetDrawFolders().ToList());
Mediator.Subscribe<RefreshUiMessage>(this, (msg) => _drawFolders = DrawFolders.ToList());
Flags |= ImGuiWindowFlags.NoDocking;
@@ -612,164 +612,165 @@ public class CompactUi : WindowMediatorSubscriberBase
}
}
private IEnumerable<IDrawFolder> GetDrawFolders()
private IEnumerable<IDrawFolder> DrawFolders
{
List<IDrawFolder> drawFolders = [];
var allPairs = _pairManager.PairsWithGroups
.ToDictionary(k => k.Key, k => k.Value);
var filteredPairs = allPairs
.Where(p =>
{
if (_tabMenu.Filter.IsNullOrEmpty()) return true;
return p.Key.UserData.AliasOrUID.Contains(_tabMenu.Filter, StringComparison.OrdinalIgnoreCase) ||
(p.Key.GetNote()?.Contains(_tabMenu.Filter, StringComparison.OrdinalIgnoreCase) ?? false) ||
(p.Key.PlayerName?.Contains(_tabMenu.Filter, StringComparison.OrdinalIgnoreCase) ?? false);
})
.ToDictionary(k => k.Key, k => k.Value);
string? AlphabeticalSort(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
=> (_configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.Key.PlayerName)
? (_configService.Current.PreferNotesOverNamesForVisible ? u.Key.GetNote() : u.Key.PlayerName)
: (u.Key.GetNote() ?? u.Key.UserData.AliasOrUID));
bool FilterOnlineOrPausedSelf(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
=> (u.Key.IsOnline || (!u.Key.IsOnline && !_configService.Current.ShowOfflineUsersSeparately)
|| u.Key.UserPair.OwnPermissions.IsPaused());
Dictionary<Pair, List<GroupFullInfoDto>> BasicSortedDictionary(IEnumerable<KeyValuePair<Pair, List<GroupFullInfoDto>>> u)
=> u.OrderByDescending(u => u.Key.IsVisible)
.ThenByDescending(u => u.Key.IsOnline)
.ThenBy(AlphabeticalSort, StringComparer.OrdinalIgnoreCase)
.ToDictionary(u => u.Key, u => u.Value);
ImmutableList<Pair> ImmutablePairList(IEnumerable<KeyValuePair<Pair, List<GroupFullInfoDto>>> u)
=> u.Select(k => k.Key).ToImmutableList();
bool FilterVisibleUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
=> u.Key.IsVisible
&& (_configService.Current.ShowSyncshellUsersInVisible || !(!_configService.Current.ShowSyncshellUsersInVisible && !u.Key.IsDirectlyPaired));
bool FilterTagUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u, string tag)
=> u.Key.IsDirectlyPaired && !u.Key.IsOneSidedPair && _tagHandler.HasPairTag(u.Key.UserData.UID, tag);
bool FilterGroupUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u, GroupFullInfoDto group)
=> u.Value.Exists(g => string.Equals(g.GID, group.GID, StringComparison.Ordinal));
bool FilterNotTaggedUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
=> u.Key.IsDirectlyPaired && !u.Key.IsOneSidedPair && !_tagHandler.HasAnyPairTag(u.Key.UserData.UID);
bool FilterNotTaggedSyncshells(GroupFullInfoDto group)
=> !_tagHandler.HasAnySyncshellTag(group.GID) || _configService.Current.ShowGroupedSyncshellsInAll;
bool FilterOfflineUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
=> ((u.Key.IsDirectlyPaired && _configService.Current.ShowSyncshellOfflineUsersSeparately)
|| !_configService.Current.ShowSyncshellOfflineUsersSeparately)
&& (!u.Key.IsOneSidedPair || u.Value.Any()) && !u.Key.IsOnline && !u.Key.UserPair.OwnPermissions.IsPaused();
bool FilterOfflineSyncshellUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
=> (!u.Key.IsDirectlyPaired && !u.Key.IsOnline && !u.Key.UserPair.OwnPermissions.IsPaused());
if (_configService.Current.ShowVisibleUsersSeparately)
get
{
var allVisiblePairs = ImmutablePairList(allPairs
.Where(FilterVisibleUsers));
var filteredVisiblePairs = BasicSortedDictionary(filteredPairs
.Where(FilterVisibleUsers));
var drawFolders = new List<IDrawFolder>();
var filter = _tabMenu.Filter;
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomVisibleTag, filteredVisiblePairs, allVisiblePairs));
}
var allPairs = _pairManager.PairsWithGroups.ToDictionary(k => k.Key, k => k.Value);
var filteredPairs = allPairs.Where(p => PassesFilter(p.Key, filter)).ToDictionary(k => k.Key, k => k.Value);
List<IDrawFolder> groupFolders = new();
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase))
{
GetGroups(allPairs, filteredPairs, group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
if (FilterNotTaggedSyncshells(group))
//Filter of online/visible pairs
if (_configService.Current.ShowVisibleUsersSeparately)
{
groupFolders.Add(_drawEntityFactory.CreateDrawGroupFolder(group, filteredGroupPairs, allGroupPairs));
var allVisiblePairs = ImmutablePairList(allPairs.Where(p => FilterVisibleUsers(p.Key)));
var filteredVisiblePairs = BasicSortedDictionary(filteredPairs.Where(p => FilterVisibleUsers(p.Key)));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomVisibleTag, filteredVisiblePairs, allVisiblePairs));
}
}
if (_configService.Current.GroupUpSyncshells)
drawFolders.Add(new DrawGroupedGroupFolder(groupFolders, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, ""));
else
drawFolders.AddRange(groupFolders);
var tags = _tagHandler.GetAllPairTagsSorted();
foreach (var tag in tags)
{
var allTagPairs = ImmutablePairList(allPairs
.Where(u => FilterTagUsers(u, tag)));
var filteredTagPairs = BasicSortedDictionary(filteredPairs
.Where(u => FilterTagUsers(u, tag) && FilterOnlineOrPausedSelf(u)));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(tag, filteredTagPairs, allTagPairs));
}
var syncshellTags = _tagHandler.GetAllSyncshellTagsSorted();
foreach (var syncshelltag in syncshellTags)
{
List<IDrawFolder> syncshellFolderTags = [];
//Filter of not foldered syncshells
var groupFolders = new List<IDrawFolder>();
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase))
{
if (_tagHandler.HasSyncshellTag(group.GID, syncshelltag))
GetGroups(allPairs, filteredPairs, group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
if (FilterNotTaggedSyncshells(group))
{
GetGroups(allPairs, filteredPairs, group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
syncshellFolderTags.Add(_drawEntityFactory.CreateDrawGroupFolder($"tag_{group.GID}", group, filteredGroupPairs, allGroupPairs));
groupFolders.Add(_drawEntityFactory.CreateDrawGroupFolder(group, filteredGroupPairs, allGroupPairs));
}
}
drawFolders.Add(new DrawGroupedGroupFolder(syncshellFolderTags, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, syncshelltag));
}
var allOnlineNotTaggedPairs = ImmutablePairList(allPairs
.Where(FilterNotTaggedUsers));
var onlineNotTaggedPairs = BasicSortedDictionary(filteredPairs
.Where(u => FilterNotTaggedUsers(u) && FilterOnlineOrPausedSelf(u)));
//Filter of grouped up syncshells (All Syncshells Folder)
if (_configService.Current.GroupUpSyncshells)
drawFolders.Add(new DrawGroupedGroupFolder(groupFolders, _tagHandler, _uiSharedService,
_selectSyncshellForTagUi, _renameSyncshellTagUi, ""));
else
drawFolders.AddRange(groupFolders);
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder((_configService.Current.ShowOfflineUsersSeparately ? TagHandler.CustomOnlineTag : TagHandler.CustomAllTag),
onlineNotTaggedPairs, allOnlineNotTaggedPairs));
if (_configService.Current.ShowOfflineUsersSeparately)
{
var allOfflinePairs = ImmutablePairList(allPairs
.Where(FilterOfflineUsers));
var filteredOfflinePairs = BasicSortedDictionary(filteredPairs
.Where(FilterOfflineUsers));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineTag, filteredOfflinePairs, allOfflinePairs));
if (_configService.Current.ShowSyncshellOfflineUsersSeparately)
//Filter of grouped/foldered pairs
foreach (var tag in _tagHandler.GetAllPairTagsSorted())
{
var allOfflineSyncshellUsers = ImmutablePairList(allPairs
.Where(FilterOfflineSyncshellUsers));
var filteredOfflineSyncshellUsers = BasicSortedDictionary(filteredPairs
.Where(FilterOfflineSyncshellUsers));
var allTagPairs = ImmutablePairList(allPairs.Where(p => FilterTagUsers(p.Key, tag)));
var filteredTagPairs = BasicSortedDictionary(filteredPairs.Where(p => FilterTagUsers(p.Key, tag) && FilterOnlineOrPausedSelf(p.Key)));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineSyncshellTag,
filteredOfflineSyncshellUsers,
allOfflineSyncshellUsers));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(tag, filteredTagPairs, allTagPairs));
}
}
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomUnpairedTag,
BasicSortedDictionary(filteredPairs.Where(u => u.Key.IsOneSidedPair)),
ImmutablePairList(allPairs.Where(u => u.Key.IsOneSidedPair))));
return drawFolders;
void GetGroups(Dictionary<Pair, List<GroupFullInfoDto>> allPairs, Dictionary<Pair, List<GroupFullInfoDto>> filteredPairs, GroupFullInfoDto group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs)
{
allGroupPairs = ImmutablePairList(allPairs
.Where(u => FilterGroupUsers(u, group)));
filteredGroupPairs = filteredPairs
.Where(u => FilterGroupUsers(u, group) && FilterOnlineOrPausedSelf(u))
.OrderByDescending(u => u.Key.IsOnline)
.ThenBy(u =>
//Filter of grouped/foldered syncshells
foreach (var syncshellTag in _tagHandler.GetAllSyncshellTagsSorted())
{
var syncshellFolderTags = new List<IDrawFolder>();
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase))
{
if (string.Equals(u.Key.UserData.UID, group.OwnerUID, StringComparison.Ordinal)) return 0;
if (group.GroupPairUserInfos.TryGetValue(u.Key.UserData.UID, out var info))
if (_tagHandler.HasSyncshellTag(group.GID, syncshellTag))
{
if (info.IsModerator()) return 1;
if (info.IsPinned()) return 2;
GetGroups(allPairs, filteredPairs, group,
out ImmutableList<Pair> allGroupPairs,
out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
syncshellFolderTags.Add(_drawEntityFactory.CreateDrawGroupFolder($"tag_{group.GID}", group, filteredGroupPairs, allGroupPairs));
}
return u.Key.IsVisible ? 3 : 4;
})
.ThenBy(AlphabeticalSort, StringComparer.OrdinalIgnoreCase)
.ToDictionary(k => k.Key, k => k.Value);
}
drawFolders.Add(new DrawGroupedGroupFolder(syncshellFolderTags, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, syncshellTag));
}
//Filter of offline pairs
var allOnlineNotTaggedPairs = ImmutablePairList(allPairs.Where(p => FilterNotTaggedUsers(p.Key)));
var onlineNotTaggedPairs = BasicSortedDictionary(filteredPairs.Where(p => FilterNotTaggedUsers(p.Key) && FilterOnlineOrPausedSelf(p.Key)));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder((_configService.Current.ShowOfflineUsersSeparately ? TagHandler.CustomOnlineTag : TagHandler.CustomAllTag), onlineNotTaggedPairs, allOnlineNotTaggedPairs));
if (_configService.Current.ShowOfflineUsersSeparately)
{
var allOfflinePairs = ImmutablePairList(allPairs.Where(p => FilterOfflineUsers(p.Key, p.Value)));
var filteredOfflinePairs = BasicSortedDictionary(filteredPairs.Where(p => FilterOfflineUsers(p.Key, p.Value)));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineTag, filteredOfflinePairs, allOfflinePairs));
if (_configService.Current.ShowSyncshellOfflineUsersSeparately)
{
var allOfflineSyncshellUsers = ImmutablePairList(allPairs.Where(p => FilterOfflineSyncshellUsers(p.Key)));
var filteredOfflineSyncshellUsers = BasicSortedDictionary(filteredPairs.Where(p => FilterOfflineSyncshellUsers(p.Key)));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineSyncshellTag, filteredOfflineSyncshellUsers, allOfflineSyncshellUsers));
}
}
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomUnpairedTag,
BasicSortedDictionary(filteredPairs.Where(p => p.Key.IsOneSidedPair)),
ImmutablePairList(allPairs.Where(p => p.Key.IsOneSidedPair))));
return drawFolders;
}
}
private static bool PassesFilter(Pair pair, string filter)
{
if (string.IsNullOrEmpty(filter)) return true;
return pair.UserData.AliasOrUID.Contains(filter, StringComparison.OrdinalIgnoreCase) || (pair.GetNote()?.Contains(filter, StringComparison.OrdinalIgnoreCase) ?? false) || (pair.PlayerName?.Contains(filter, StringComparison.OrdinalIgnoreCase) ?? false);
}
private string AlphabeticalSortKey(Pair pair)
{
if (_configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(pair.PlayerName))
{
return _configService.Current.PreferNotesOverNamesForVisible ? (pair.GetNote() ?? string.Empty) : pair.PlayerName;
}
return pair.GetNote() ?? pair.UserData.AliasOrUID;
}
private bool FilterOnlineOrPausedSelf(Pair pair) => pair.IsOnline || (!pair.IsOnline && !_configService.Current.ShowOfflineUsersSeparately) || pair.UserPair.OwnPermissions.IsPaused();
private bool FilterVisibleUsers(Pair pair) => pair.IsVisible && (_configService.Current.ShowSyncshellUsersInVisible || pair.IsDirectlyPaired);
private bool FilterTagUsers(Pair pair, string tag) => pair.IsDirectlyPaired && !pair.IsOneSidedPair && _tagHandler.HasPairTag(pair.UserData.UID, tag);
private static bool FilterGroupUsers(List<GroupFullInfoDto> groups, GroupFullInfoDto group) => groups.Exists(g => string.Equals(g.GID, group.GID, StringComparison.Ordinal));
private bool FilterNotTaggedUsers(Pair pair) => pair.IsDirectlyPaired && !pair.IsOneSidedPair && !_tagHandler.HasAnyPairTag(pair.UserData.UID);
private bool FilterNotTaggedSyncshells(GroupFullInfoDto group) => !_tagHandler.HasAnySyncshellTag(group.GID) || _configService.Current.ShowGroupedSyncshellsInAll;
private bool FilterOfflineUsers(Pair pair, List<GroupFullInfoDto> groups) => ((pair.IsDirectlyPaired && _configService.Current.ShowSyncshellOfflineUsersSeparately) || !_configService.Current.ShowSyncshellOfflineUsersSeparately) && (!pair.IsOneSidedPair || groups.Count != 0) && !pair.IsOnline && !pair.UserPair.OwnPermissions.IsPaused();
private static bool FilterOfflineSyncshellUsers(Pair pair) => !pair.IsDirectlyPaired && !pair.IsOnline && !pair.UserPair.OwnPermissions.IsPaused();
private Dictionary<Pair, List<GroupFullInfoDto>> BasicSortedDictionary(IEnumerable<KeyValuePair<Pair, List<GroupFullInfoDto>>> pairs) => pairs.OrderByDescending(u => u.Key.IsVisible).ThenByDescending(u => u.Key.IsOnline).ThenBy(u => AlphabeticalSortKey(u.Key), StringComparer.OrdinalIgnoreCase).ToDictionary(u => u.Key, u => u.Value);
private static ImmutableList<Pair> ImmutablePairList(IEnumerable<KeyValuePair<Pair, List<GroupFullInfoDto>>> pairs) => [.. pairs.Select(k => k.Key)];
private void GetGroups(Dictionary<Pair, List<GroupFullInfoDto>> allPairs,
Dictionary<Pair, List<GroupFullInfoDto>> filteredPairs,
GroupFullInfoDto group,
out ImmutableList<Pair> allGroupPairs,
out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs)
{
allGroupPairs = ImmutablePairList(allPairs
.Where(u => FilterGroupUsers(u.Value, group)));
filteredGroupPairs = filteredPairs
.Where(u => FilterGroupUsers( u.Value, group) && FilterOnlineOrPausedSelf(u.Key))
.OrderByDescending(u => u.Key.IsOnline)
.ThenBy(u =>
{
if (string.Equals(u.Key.UserData.UID, group.OwnerUID, StringComparison.Ordinal)) return 0;
if (group.GroupPairUserInfos.TryGetValue(u.Key.UserData.UID, out var info))
{
if (info.IsModerator()) return 1;
if (info.IsPinned()) return 2;
}
return u.Key.IsVisible ? 3 : 4;
})
.ThenBy(u => AlphabeticalSortKey(u.Key), StringComparer.OrdinalIgnoreCase)
.ToDictionary(k => k.Key, k => k.Value);
}
private string GetServerError()
{
return _apiController.ServerState switch