From b784edb7581b2c9e64349c9895013ac387d7778d Mon Sep 17 00:00:00 2001 From: Repo <47093363+Titian3@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:58:31 +1200 Subject: [PATCH] Fix aHelp menu sorting (#30518) * Keep Pinned status through player status changes. * Fix filtering to be admin optimal. --- .../UI/Bwoink/BwoinkControl.xaml.cs | 41 +++++++++++++++++-- .../CustomControls/PlayerListControl.xaml.cs | 21 +++++++--- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs b/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs index ddd66623bd..18aa02e9d6 100644 --- a/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs +++ b/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs @@ -88,6 +88,10 @@ namespace Content.Client.Administration.UI.Bwoink var ach = AHelpHelper.EnsurePanel(a.SessionId); var bch = AHelpHelper.EnsurePanel(b.SessionId); + // Pinned players first + if (a.IsPinned != b.IsPinned) + return a.IsPinned ? -1 : 1; + // First, sort by unread. Any chat with unread messages appears first. We just sort based on unread // status, not number of unread messages, so that more recent unread messages take priority. var aUnread = ach.Unread > 0; @@ -99,15 +103,31 @@ namespace Content.Client.Administration.UI.Bwoink if (a.Connected != b.Connected) return a.Connected ? -1 : 1; - // Next, group by whether or not the players have participated in this round. - // The ahelp window shows all players that have connected since server restart, this groups them all towards the bottom. - if (a.ActiveThisRound != b.ActiveThisRound) - return a.ActiveThisRound ? -1 : 1; + // Sort connected players by New Player status, then by Antag status + if (a.Connected && b.Connected) + { + var aNewPlayer = a.OverallPlaytime <= TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.NewPlayerThreshold)); + var bNewPlayer = b.OverallPlaytime <= TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.NewPlayerThreshold)); + + if (aNewPlayer != bNewPlayer) + return aNewPlayer ? -1 : 1; + + if (a.Antag != b.Antag) + return a.Antag ? -1 : 1; + } + + // Sort disconnected players by participation in the round + if (!a.Connected && !b.Connected) + { + if (a.ActiveThisRound != b.ActiveThisRound) + return a.ActiveThisRound ? -1 : 1; + } // Finally, sort by the most recent message. return bch.LastMessage.CompareTo(ach.LastMessage); }; + Bans.OnPressed += _ => { if (_currentPlayer is not null) @@ -253,7 +273,20 @@ namespace Content.Client.Administration.UI.Bwoink public void PopulateList() { + // Maintain existing pin statuses + var pinnedPlayers = ChannelSelector.PlayerInfo.Where(p => p.IsPinned).ToDictionary(p => p.SessionId); + ChannelSelector.PopulateList(); + + // Restore pin statuses + foreach (var player in ChannelSelector.PlayerInfo) + { + if (pinnedPlayers.TryGetValue(player.SessionId, out var pinnedPlayer)) + { + player.IsPinned = pinnedPlayer.IsPinned; + } + } + UpdateButtons(); } } diff --git a/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs b/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs index b09cd727ef..c7fbf6c2dc 100644 --- a/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs +++ b/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs @@ -21,11 +21,11 @@ public sealed partial class PlayerListControl : BoxContainer private readonly IEntityManager _entManager; private readonly IUserInterfaceManager _uiManager; - + private PlayerInfo? _selectedPlayer; private List _playerList = new(); - private readonly List _sortedPlayerList = new(); + private List _sortedPlayerList = new(); public Comparison? Comparison; public Func? OverrideText; @@ -110,19 +110,30 @@ public sealed partial class PlayerListControl : BoxContainer if (Comparison != null) _sortedPlayerList.Sort((a, b) => Comparison(a, b)); - // Ensure pinned players are always at the top - _sortedPlayerList.Sort((a, b) => a.IsPinned != b.IsPinned && a.IsPinned ? -1 : 1); - PlayerListContainer.PopulateList(_sortedPlayerList.Select(info => new PlayerListData(info)).ToList()); if (_selectedPlayer != null) PlayerListContainer.Select(new PlayerListData(_selectedPlayer)); } + public void PopulateList(IReadOnlyList? players = null) { + // Maintain existing pin statuses + var pinnedPlayers = _playerList.Where(p => p.IsPinned).ToDictionary(p => p.SessionId); + players ??= _adminSystem.PlayerList; _playerList = players.ToList(); + + // Restore pin statuses + foreach (var player in _playerList) + { + if (pinnedPlayers.TryGetValue(player.SessionId, out var pinnedPlayer)) + { + player.IsPinned = pinnedPlayer.IsPinned; + } + } + if (_selectedPlayer != null && !_playerList.Contains(_selectedPlayer)) _selectedPlayer = null; -- 2.52.0