From 837b4872812064edfd3fad7744918b0d5adbd2e3 Mon Sep 17 00:00:00 2001 From: Professor Fartsalot Date: Fri, 5 Sep 2025 17:31:45 -0400 Subject: [PATCH] Several UI enhancements + Added paused user field to main UI + Excluded paused users from online list + Excluded visible users from online list + Fixed an issue where remotely paused users would always show offline + Ensured paused users returns true if EITHER client OR remote paused them. + Made paused users show as Grey + Changed paired icon from check to snowflake + Fixed a bug where clients would have icons for both paired AND visible simultaneously + Fixed a bug where clients would show both online AND visible unnecessarily. + Made paused users render just above offline users. + Changed default ui icon from SS to Snowflake/Flower thingy. --- MareSynchronos/UI/CompactUI.cs | 7 +-- MareSynchronos/UI/Components/DrawUserPair.cs | 21 ++++---- MareSynchronos/UI/Components/PairGroupsUi.cs | 53 +++++++++++++------- MareSynchronos/UI/DtrEntry.cs | 4 +- MareSynchronos/UI/Handlers/TagHandler.cs | 1 + MareSynchronos/UI/SettingsUi.cs | 4 +- 6 files changed, 54 insertions(+), 36 deletions(-) diff --git a/MareSynchronos/UI/CompactUI.cs b/MareSynchronos/UI/CompactUI.cs index d3fddcb..71c9d3a 100644 --- a/MareSynchronos/UI/CompactUI.cs +++ b/MareSynchronos/UI/CompactUI.cs @@ -362,13 +362,14 @@ public class CompactUi : WindowMediatorSubscriberBase : (ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y) - TransferPartHeight - ImGui.GetCursorPosY(); var users = GetFilteredUsers().OrderBy(u => u.GetPairSortKey(), StringComparer.Ordinal); - var onlineUsers = users.Where(u => u.UserPair!.OtherPermissions.IsPaired() && (u.IsOnline || u.UserPair!.OwnPermissions.IsPaused())).Select(c => new DrawUserPair("Online" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); + var onlineUsers = users.Where(u => u.UserPair!.OtherPermissions.IsPaired() && (u.IsOnline && !u.IsVisible && (!u.UserPair!.OtherPermissions.IsPaused() && !u.UserPair!.OwnPermissions.IsPaused()))).Select(c => new DrawUserPair("Online" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); + var pausedUsers = users.Where(u => u.UserPair!.OtherPermissions.IsPaired() && (u.UserPair!.OtherPermissions.IsPaused() || u.UserPair!.OwnPermissions.IsPaused())).Select(c => new DrawUserPair("Paused" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); var visibleUsers = users.Where(u => u.IsVisible).Select(c => new DrawUserPair("Visible" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); - var offlineUsers = users.Where(u => !u.UserPair!.OtherPermissions.IsPaired() || (!u.IsOnline && !u.UserPair!.OwnPermissions.IsPaused())).Select(c => new DrawUserPair("Offline" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); + var offlineUsers = users.Where(u => !u.UserPair!.OtherPermissions.IsPaired() || !u.IsOnline && (!u.UserPair!.OwnPermissions.IsPaused() && !u.UserPair.OtherPermissions.IsPaused())).Select(c => new DrawUserPair("Offline" + c.UserData.UID, c, _uidDisplayHandler, _apiController, Mediator, _selectGroupForPairUi, _uiSharedService, _charaDataManager)).ToList(); ImGui.BeginChild("list", new Vector2(WindowContentWidth, ySize), border: false); - _pairGroupsUi.Draw(visibleUsers, onlineUsers, offlineUsers); + _pairGroupsUi.Draw(visibleUsers, onlineUsers, pausedUsers, offlineUsers); ImGui.EndChild(); } diff --git a/MareSynchronos/UI/Components/DrawUserPair.cs b/MareSynchronos/UI/Components/DrawUserPair.cs index 57b22fb..ac1a46e 100644 --- a/MareSynchronos/UI/Components/DrawUserPair.cs +++ b/MareSynchronos/UI/Components/DrawUserPair.cs @@ -52,23 +52,24 @@ public class DrawUserPair : DrawPairBase { connectionIcon = FontAwesomeIcon.PauseCircle; connectionText = "Pairing status with " + _pair.UserData.AliasOrUID + " is paused"; - connectionColor = ImGuiColors.DalamudYellow; + connectionColor = ImGuiColors.DalamudGrey; } else { - connectionIcon = FontAwesomeIcon.Check; + connectionIcon = FontAwesomeIcon.Snowflake; connectionText = "You are paired with " + _pair.UserData.AliasOrUID; - connectionColor = ImGuiColors.ParsedGreen; + connectionColor = _pair.IsOnline ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudGrey; + } + if (!_pair.IsVisible) + { + ImGui.SetCursorPosY(textPosY); + ImGui.PushFont(UiBuilder.IconFont); + UiSharedService.ColorText(connectionIcon.ToIconString(), connectionColor); + ImGui.PopFont(); + UiSharedService.AttachToolTip(connectionText); } - - ImGui.SetCursorPosY(textPosY); - ImGui.PushFont(UiBuilder.IconFont); - UiSharedService.ColorText(connectionIcon.ToIconString(), connectionColor); - ImGui.PopFont(); - UiSharedService.AttachToolTip(connectionText); if (_pair is { IsOnline: true, IsVisible: true }) { - ImGui.SameLine(); ImGui.SetCursorPosY(textPosY); ImGui.PushFont(UiBuilder.IconFont); UiSharedService.ColorText(FontAwesomeIcon.Eye.ToIconString(), ImGuiColors.ParsedGreen); diff --git a/MareSynchronos/UI/Components/PairGroupsUi.cs b/MareSynchronos/UI/Components/PairGroupsUi.cs index 0778a02..e6d1df7 100644 --- a/MareSynchronos/UI/Components/PairGroupsUi.cs +++ b/MareSynchronos/UI/Components/PairGroupsUi.cs @@ -5,6 +5,8 @@ using MareSynchronos.API.Data.Extensions; using MareSynchronos.MareConfiguration; using MareSynchronos.UI.Handlers; using MareSynchronos.WebAPI; +using Serilog.Core; +using System.Diagnostics; namespace MareSynchronos.UI.Components; @@ -28,15 +30,15 @@ public class PairGroupsUi _uiSharedService = uiSharedService; } - public void Draw(List visibleUsers, List onlineUsers, List offlineUsers) where T : DrawPairBase + public void Draw(List visibleUsers, List onlineUsers, List pausedUsers, List offlineUsers) where T : DrawPairBase { // Only render those tags that actually have pairs in them, otherwise // we can end up with a bunch of useless pair groups var tagsWithPairsInThem = _tagHandler.GetAllTagsSorted(); - var allUsers = onlineUsers.Concat(offlineUsers).ToList(); + var allUsers = onlineUsers.Concat(offlineUsers).Concat(pausedUsers).ToList(); if (typeof(T) == typeof(DrawUserPair)) { - DrawUserPairs(tagsWithPairsInThem, allUsers.Cast().ToList(), visibleUsers.Cast(), onlineUsers.Cast(), offlineUsers.Cast()); + DrawUserPairs(tagsWithPairsInThem, allUsers.Cast().ToList(), visibleUsers.Cast(), onlineUsers.Cast(), pausedUsers.Cast(), offlineUsers.Cast()); } } @@ -91,13 +93,19 @@ public class PairGroupsUi } } - private void DrawCategory(string tag, IEnumerable onlineUsers, IEnumerable allUsers, IEnumerable? visibleUsers = null) + private void DrawCategory(string tag, IEnumerable onlineUsers, IEnumerable pausedUsers, IEnumerable allUsers, IEnumerable? visibleUsers = null) { IEnumerable usersInThisTag; HashSet? otherUidsTaggedWithTag = null; bool isSpecialTag = false; int visibleInThisTag = 0; - if (tag is TagHandler.CustomOfflineTag or TagHandler.CustomOnlineTag or TagHandler.CustomVisibleTag or TagHandler.CustomUnpairedTag) + + if (tag is TagHandler.CustomPausedTag) + { + usersInThisTag = pausedUsers; + isSpecialTag = true; + } + else if (tag is TagHandler.CustomOfflineTag or TagHandler.CustomOnlineTag or TagHandler.CustomVisibleTag or TagHandler.CustomUnpairedTag) { usersInThisTag = onlineUsers; isSpecialTag = true; @@ -113,14 +121,13 @@ public class PairGroupsUi if (isSpecialTag && !usersInThisTag.Any()) return; - DrawName(tag, isSpecialTag, visibleInThisTag, usersInThisTag.Count(), otherUidsTaggedWithTag?.Count); + DrawName(tag, isSpecialTag, visibleInThisTag, usersInThisTag.Count(), pausedUsers.Count(), otherUidsTaggedWithTag?.Count); if (!isSpecialTag) { using (ImRaii.PushId($"group-{tag}-buttons")) DrawButtons(tag, allUsers.Cast().Where(p => otherUidsTaggedWithTag!.Contains(p.UID)).ToList()); } else { - // Avoid uncomfortably close group names if (!_tagHandler.IsTagOpen(tag)) { var size = ImGui.CalcTextSize("").Y + ImGui.GetStyle().FramePadding.Y * 2f; @@ -151,18 +158,19 @@ public class PairGroupsUi UiSharedService.AttachToolTip($"Delete Group {tag} (Will not delete the pairs)" + Environment.NewLine + "Hold CTRL to delete"); } - private void DrawName(string tag, bool isSpecialTag, int visible, int online, int? total) + private void DrawName(string tag, bool isSpecialTag, int visible, int online, int paused, int? total) { string displayedName = tag switch { TagHandler.CustomUnpairedTag => "Unpaired", TagHandler.CustomOfflineTag => "Offline", - TagHandler.CustomOnlineTag => _mareConfig.Current.ShowOfflineUsersSeparately ? "Online/Paused" : "Contacts", + TagHandler.CustomOnlineTag => _mareConfig.Current.ShowOfflineUsersSeparately ? "Online" : "Contacts", + TagHandler.CustomPausedTag => "Paused", TagHandler.CustomVisibleTag => "Visible", _ => tag }; - string resultFolderName = !isSpecialTag ? $"{displayedName} ({visible}/{online}/{total} Pairs)" : $"{displayedName} ({online} Pairs)"; + string resultFolderName = !isSpecialTag ? $"{displayedName} ({visible}/{online}/{paused}/{total} Pairs)" : $"{displayedName} ({online} Pairs)"; // FontAwesomeIcon.CaretSquareDown : FontAwesomeIcon.CaretSquareRight var icon = _tagHandler.IsTagOpen(tag) ? FontAwesomeIcon.CaretSquareDown : FontAwesomeIcon.CaretSquareRight; @@ -184,7 +192,8 @@ public class PairGroupsUi ImGui.TextUnformatted($"Group {tag}"); ImGui.Separator(); ImGui.TextUnformatted($"{visible} Pairs visible"); - ImGui.TextUnformatted($"{online} Pairs online/paused"); + ImGui.TextUnformatted($"{online} Pairs online"); + ImGui.TextUnformatted($"{paused} Pairs paused"); ImGui.TextUnformatted($"{total} Pairs total"); ImGui.EndTooltip(); } @@ -197,39 +206,45 @@ public class PairGroupsUi ImGui.Separator(); } - private void DrawUserPairs(List tagsWithPairsInThem, List allUsers, IEnumerable visibleUsers, IEnumerable onlineUsers, IEnumerable offlineUsers) + private void DrawUserPairs(List tagsWithPairsInThem, List allUsers, IEnumerable visibleUsers, IEnumerable onlineUsers, IEnumerable pausedUsers, IEnumerable offlineUsers) { if (_mareConfig.Current.ShowVisibleUsersSeparately) { - using (ImRaii.PushId("$group-VisibleCustomTag")) DrawCategory(TagHandler.CustomVisibleTag, visibleUsers, allUsers); + using (ImRaii.PushId("$group-VisibleCustomTag")) DrawCategory(TagHandler.CustomVisibleTag, visibleUsers, Enumerable.Empty(), allUsers); } + foreach (var tag in tagsWithPairsInThem) { if (_mareConfig.Current.ShowOfflineUsersSeparately) { - using (ImRaii.PushId($"group-{tag}")) DrawCategory(tag, onlineUsers, allUsers, visibleUsers); + using (ImRaii.PushId($"group-{tag}")) DrawCategory(tag, onlineUsers, pausedUsers, allUsers, visibleUsers); } else { - using (ImRaii.PushId($"group-{tag}")) DrawCategory(tag, allUsers, allUsers, visibleUsers); + using (ImRaii.PushId($"group-{tag}")) DrawCategory(tag, allUsers, Enumerable.Empty(), allUsers, visibleUsers); } } + if (_mareConfig.Current.ShowOfflineUsersSeparately) { using (ImRaii.PushId($"group-OnlineCustomTag")) DrawCategory(TagHandler.CustomOnlineTag, - onlineUsers.Where(u => !_tagHandler.HasAnyTag(u.UID)).ToList(), allUsers); + onlineUsers.Where(u => !_tagHandler.HasAnyTag(u.UID)).ToList(), Enumerable.Empty(), allUsers); + if (pausedUsers.Any()) using (ImRaii.PushId("group-PausedCustomTag")) DrawCategory(TagHandler.CustomPausedTag, + Enumerable.Empty(), pausedUsers, allUsers); using (ImRaii.PushId($"group-OfflineCustomTag")) DrawCategory(TagHandler.CustomOfflineTag, - offlineUsers.Where(u => u.UserPair!.OtherPermissions.IsPaired()).ToList(), allUsers); + offlineUsers.Where(u => u.UserPair!.OtherPermissions.IsPaired()).ToList(), Enumerable.Empty(), allUsers); } else { using (ImRaii.PushId($"group-OnlineCustomTag")) DrawCategory(TagHandler.CustomOnlineTag, - onlineUsers.Concat(offlineUsers.Where(u => u.UserPair!.OtherPermissions.IsPaired())).Where(u => !_tagHandler.HasAnyTag(u.UID)).ToList(), allUsers); + onlineUsers.Concat(offlineUsers.Where(u => u.UserPair!.OtherPermissions.IsPaired())).Where(u => !_tagHandler.HasAnyTag(u.UID)).ToList(), Enumerable.Empty(), allUsers); } + using (ImRaii.PushId($"group-UnpairedCustomTag")) DrawCategory(TagHandler.CustomUnpairedTag, - offlineUsers.Where(u => !u.UserPair!.OtherPermissions.IsPaired()).ToList(), allUsers); + offlineUsers.Where(u => !u.UserPair!.OtherPermissions.IsPaired()).ToList(), Enumerable.Empty(), allUsers); } + private void PauseRemainingPairs(List availablePairs) { foreach (var pairToPause in availablePairs.Where(pair => !pair.UserPair!.OwnPermissions.IsPaused())) diff --git a/MareSynchronos/UI/DtrEntry.cs b/MareSynchronos/UI/DtrEntry.cs index 72b89dc..7bece6a 100644 --- a/MareSynchronos/UI/DtrEntry.cs +++ b/MareSynchronos/UI/DtrEntry.cs @@ -203,10 +203,10 @@ public sealed class DtrEntry : IDisposable, IHostedService DtrStyle.Style4 => $"\xE03A {text}", DtrStyle.Style5 => $"\xE033 {text}", DtrStyle.Style6 => $"\xE038 {text}", - DtrStyle.Style7 => $"\xE05D {text}", + DtrStyle.Style7 => $"\xE044 {text}", DtrStyle.Style8 => $"\xE03C{text}", DtrStyle.Style9 => $"\xE040 {text} \xE041", - _ => $"\uE044 {text}" + _ => $"\uE05D {text}" }; } diff --git a/MareSynchronos/UI/Handlers/TagHandler.cs b/MareSynchronos/UI/Handlers/TagHandler.cs index 11f2d41..b748574 100644 --- a/MareSynchronos/UI/Handlers/TagHandler.cs +++ b/MareSynchronos/UI/Handlers/TagHandler.cs @@ -9,6 +9,7 @@ public class TagHandler public const string CustomOnlineTag = "Mare_Online"; public const string CustomUnpairedTag = "Mare_Unpaired"; public const string CustomVisibleTag = "Mare_Visible"; + public const string CustomPausedTag = "Mare_Paused"; private readonly ServerConfigurationManager _serverConfigurationManager; public TagHandler(ServerConfigurationManager serverConfigurationManager) diff --git a/MareSynchronos/UI/SettingsUi.cs b/MareSynchronos/UI/SettingsUi.cs index a1cf491..11b9bae 100644 --- a/MareSynchronos/UI/SettingsUi.cs +++ b/MareSynchronos/UI/SettingsUi.cs @@ -1083,12 +1083,12 @@ public class SettingsUi : WindowMediatorSubscriberBase _configService.Save(); } _uiShared.DrawHelpText("This will put users using the most VRAM in a syncshell at the top of the list."); - if (ImGui.Checkbox("Show separate Offline group", ref showOfflineSeparate)) + if (ImGui.Checkbox("Group users by connection status", ref showOfflineSeparate)) { _configService.Current.ShowOfflineUsersSeparately = showOfflineSeparate; _configService.Save(); } - _uiShared.DrawHelpText("This will show all currently offline users in a special 'Offline' group in the main UI."); + _uiShared.DrawHelpText("This will categorize users by their connection status in the main UI."); if (ImGui.Checkbox("Show player names", ref showCharacterNames)) {