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 #if DEBUG
string dev = "Dev Build"; string dev = "Dev Build";
@@ -158,7 +158,7 @@ public class CompactUi : WindowMediatorSubscriberBase
Mediator.Subscribe<CutsceneEndMessage>(this, (_) => UiSharedService_GposeEnd()); Mediator.Subscribe<CutsceneEndMessage>(this, (_) => UiSharedService_GposeEnd());
Mediator.Subscribe<DownloadStartedMessage>(this, (msg) => _currentDownloads[msg.DownloadId] = msg.DownloadStatus); Mediator.Subscribe<DownloadStartedMessage>(this, (msg) => _currentDownloads[msg.DownloadId] = msg.DownloadStatus);
Mediator.Subscribe<DownloadFinishedMessage>(this, (msg) => _currentDownloads.TryRemove(msg.DownloadId, out _)); 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; Flags |= ImGuiWindowFlags.NoDocking;
@@ -612,148 +612,150 @@ public class CompactUi : WindowMediatorSubscriberBase
} }
} }
private IEnumerable<IDrawFolder> GetDrawFolders() private IEnumerable<IDrawFolder> DrawFolders
{ {
List<IDrawFolder> drawFolders = []; get
var allPairs = _pairManager.PairsWithGroups
.ToDictionary(k => k.Key, k => k.Value);
var filteredPairs = allPairs
.Where(p =>
{ {
if (_tabMenu.Filter.IsNullOrEmpty()) return true; var drawFolders = new List<IDrawFolder>();
return p.Key.UserData.AliasOrUID.Contains(_tabMenu.Filter, StringComparison.OrdinalIgnoreCase) || var filter = _tabMenu.Filter;
(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());
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);
//Filter of online/visible pairs
if (_configService.Current.ShowVisibleUsersSeparately) if (_configService.Current.ShowVisibleUsersSeparately)
{ {
var allVisiblePairs = ImmutablePairList(allPairs var allVisiblePairs = ImmutablePairList(allPairs.Where(p => FilterVisibleUsers(p.Key)));
.Where(FilterVisibleUsers)); var filteredVisiblePairs = BasicSortedDictionary(filteredPairs.Where(p => FilterVisibleUsers(p.Key)));
var filteredVisiblePairs = BasicSortedDictionary(filteredPairs
.Where(FilterVisibleUsers));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomVisibleTag, filteredVisiblePairs, allVisiblePairs)); drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomVisibleTag, filteredVisiblePairs, allVisiblePairs));
} }
List<IDrawFolder> groupFolders = new(); //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)) 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); GetGroups(allPairs, filteredPairs, group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
if (FilterNotTaggedSyncshells(group)) if (FilterNotTaggedSyncshells(group))
{ {
groupFolders.Add(_drawEntityFactory.CreateDrawGroupFolder(group, filteredGroupPairs, allGroupPairs)); groupFolders.Add(_drawEntityFactory.CreateDrawGroupFolder(group, filteredGroupPairs, allGroupPairs));
} }
} }
//Filter of grouped up syncshells (All Syncshells Folder)
if (_configService.Current.GroupUpSyncshells) if (_configService.Current.GroupUpSyncshells)
drawFolders.Add(new DrawGroupedGroupFolder(groupFolders, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, "")); drawFolders.Add(new DrawGroupedGroupFolder(groupFolders, _tagHandler, _uiSharedService,
_selectSyncshellForTagUi, _renameSyncshellTagUi, ""));
else else
drawFolders.AddRange(groupFolders); drawFolders.AddRange(groupFolders);
var tags = _tagHandler.GetAllPairTagsSorted(); //Filter of grouped/foldered pairs
foreach (var tag in tags) foreach (var tag in _tagHandler.GetAllPairTagsSorted())
{ {
var allTagPairs = ImmutablePairList(allPairs var allTagPairs = ImmutablePairList(allPairs.Where(p => FilterTagUsers(p.Key, tag)));
.Where(u => FilterTagUsers(u, tag))); var filteredTagPairs = BasicSortedDictionary(filteredPairs.Where(p => FilterTagUsers(p.Key, tag) && FilterOnlineOrPausedSelf(p.Key)));
var filteredTagPairs = BasicSortedDictionary(filteredPairs
.Where(u => FilterTagUsers(u, tag) && FilterOnlineOrPausedSelf(u)));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(tag, filteredTagPairs, allTagPairs)); drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(tag, filteredTagPairs, allTagPairs));
} }
var syncshellTags = _tagHandler.GetAllSyncshellTagsSorted(); //Filter of grouped/foldered syncshells
foreach (var syncshelltag in syncshellTags) foreach (var syncshellTag in _tagHandler.GetAllSyncshellTagsSorted())
{ {
List<IDrawFolder> syncshellFolderTags = []; var syncshellFolderTags = new List<IDrawFolder>();
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase)) foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase))
{ {
if (_tagHandler.HasSyncshellTag(group.GID, syncshelltag)) if (_tagHandler.HasSyncshellTag(group.GID, syncshellTag))
{ {
GetGroups(allPairs, filteredPairs, group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs); GetGroups(allPairs, filteredPairs, group,
out ImmutableList<Pair> allGroupPairs,
out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
syncshellFolderTags.Add(_drawEntityFactory.CreateDrawGroupFolder($"tag_{group.GID}", group, filteredGroupPairs, allGroupPairs)); syncshellFolderTags.Add(_drawEntityFactory.CreateDrawGroupFolder($"tag_{group.GID}", group, filteredGroupPairs, allGroupPairs));
} }
} }
drawFolders.Add(new DrawGroupedGroupFolder(syncshellFolderTags, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, syncshelltag));
drawFolders.Add(new DrawGroupedGroupFolder(syncshellFolderTags, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, syncshellTag));
} }
var allOnlineNotTaggedPairs = ImmutablePairList(allPairs //Filter of offline pairs
.Where(FilterNotTaggedUsers)); var allOnlineNotTaggedPairs = ImmutablePairList(allPairs.Where(p => FilterNotTaggedUsers(p.Key)));
var onlineNotTaggedPairs = BasicSortedDictionary(filteredPairs var onlineNotTaggedPairs = BasicSortedDictionary(filteredPairs.Where(p => FilterNotTaggedUsers(p.Key) && FilterOnlineOrPausedSelf(p.Key)));
.Where(u => FilterNotTaggedUsers(u) && FilterOnlineOrPausedSelf(u)));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder((_configService.Current.ShowOfflineUsersSeparately ? TagHandler.CustomOnlineTag : TagHandler.CustomAllTag), drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder((_configService.Current.ShowOfflineUsersSeparately ? TagHandler.CustomOnlineTag : TagHandler.CustomAllTag), onlineNotTaggedPairs, allOnlineNotTaggedPairs));
onlineNotTaggedPairs, allOnlineNotTaggedPairs));
if (_configService.Current.ShowOfflineUsersSeparately) if (_configService.Current.ShowOfflineUsersSeparately)
{ {
var allOfflinePairs = ImmutablePairList(allPairs var allOfflinePairs = ImmutablePairList(allPairs.Where(p => FilterOfflineUsers(p.Key, p.Value)));
.Where(FilterOfflineUsers)); var filteredOfflinePairs = BasicSortedDictionary(filteredPairs.Where(p => FilterOfflineUsers(p.Key, p.Value)));
var filteredOfflinePairs = BasicSortedDictionary(filteredPairs
.Where(FilterOfflineUsers));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineTag, filteredOfflinePairs, allOfflinePairs)); drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineTag, filteredOfflinePairs, allOfflinePairs));
if (_configService.Current.ShowSyncshellOfflineUsersSeparately) if (_configService.Current.ShowSyncshellOfflineUsersSeparately)
{ {
var allOfflineSyncshellUsers = ImmutablePairList(allPairs var allOfflineSyncshellUsers = ImmutablePairList(allPairs.Where(p => FilterOfflineSyncshellUsers(p.Key)));
.Where(FilterOfflineSyncshellUsers)); var filteredOfflineSyncshellUsers = BasicSortedDictionary(filteredPairs.Where(p => FilterOfflineSyncshellUsers(p.Key)));
var filteredOfflineSyncshellUsers = BasicSortedDictionary(filteredPairs
.Where(FilterOfflineSyncshellUsers));
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineSyncshellTag, drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineSyncshellTag, filteredOfflineSyncshellUsers, allOfflineSyncshellUsers));
filteredOfflineSyncshellUsers,
allOfflineSyncshellUsers));
} }
} }
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomUnpairedTag, drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomUnpairedTag,
BasicSortedDictionary(filteredPairs.Where(u => u.Key.IsOneSidedPair)), BasicSortedDictionary(filteredPairs.Where(p => p.Key.IsOneSidedPair)),
ImmutablePairList(allPairs.Where(u => u.Key.IsOneSidedPair)))); ImmutablePairList(allPairs.Where(p => p.Key.IsOneSidedPair))));
return drawFolders; 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) 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 allGroupPairs = ImmutablePairList(allPairs
.Where(u => FilterGroupUsers(u, group))); .Where(u => FilterGroupUsers(u.Value, group)));
filteredGroupPairs = filteredPairs filteredGroupPairs = filteredPairs
.Where(u => FilterGroupUsers(u, group) && FilterOnlineOrPausedSelf(u)) .Where(u => FilterGroupUsers( u.Value, group) && FilterOnlineOrPausedSelf(u.Key))
.OrderByDescending(u => u.Key.IsOnline) .OrderByDescending(u => u.Key.IsOnline)
.ThenBy(u => .ThenBy(u =>
{ {
@@ -765,10 +767,9 @@ public class CompactUi : WindowMediatorSubscriberBase
} }
return u.Key.IsVisible ? 3 : 4; return u.Key.IsVisible ? 3 : 4;
}) })
.ThenBy(AlphabeticalSort, StringComparer.OrdinalIgnoreCase) .ThenBy(u => AlphabeticalSortKey(u.Key), StringComparer.OrdinalIgnoreCase)
.ToDictionary(k => k.Key, k => k.Value); .ToDictionary(k => k.Key, k => k.Value);
} }
}
private string GetServerError() private string GetServerError()
{ {