Fix aHelp menu sorting (#30518)

* Keep Pinned status through player status changes.

* Fix filtering to be admin optimal.
This commit is contained in:
Repo
2024-07-31 13:58:31 +12:00
committed by GitHub
parent 61e87cb43a
commit b784edb758
2 changed files with 53 additions and 9 deletions

View File

@@ -88,6 +88,10 @@ namespace Content.Client.Administration.UI.Bwoink
var ach = AHelpHelper.EnsurePanel(a.SessionId); var ach = AHelpHelper.EnsurePanel(a.SessionId);
var bch = AHelpHelper.EnsurePanel(b.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 // 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. // status, not number of unread messages, so that more recent unread messages take priority.
var aUnread = ach.Unread > 0; var aUnread = ach.Unread > 0;
@@ -99,15 +103,31 @@ namespace Content.Client.Administration.UI.Bwoink
if (a.Connected != b.Connected) if (a.Connected != b.Connected)
return a.Connected ? -1 : 1; return a.Connected ? -1 : 1;
// Next, group by whether or not the players have participated in this round. // Sort connected players by New Player status, then by Antag status
// The ahelp window shows all players that have connected since server restart, this groups them all towards the bottom. 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) if (a.ActiveThisRound != b.ActiveThisRound)
return a.ActiveThisRound ? -1 : 1; return a.ActiveThisRound ? -1 : 1;
}
// Finally, sort by the most recent message. // Finally, sort by the most recent message.
return bch.LastMessage.CompareTo(ach.LastMessage); return bch.LastMessage.CompareTo(ach.LastMessage);
}; };
Bans.OnPressed += _ => Bans.OnPressed += _ =>
{ {
if (_currentPlayer is not null) if (_currentPlayer is not null)
@@ -253,7 +273,20 @@ namespace Content.Client.Administration.UI.Bwoink
public void PopulateList() public void PopulateList()
{ {
// Maintain existing pin statuses
var pinnedPlayers = ChannelSelector.PlayerInfo.Where(p => p.IsPinned).ToDictionary(p => p.SessionId);
ChannelSelector.PopulateList(); ChannelSelector.PopulateList();
// Restore pin statuses
foreach (var player in ChannelSelector.PlayerInfo)
{
if (pinnedPlayers.TryGetValue(player.SessionId, out var pinnedPlayer))
{
player.IsPinned = pinnedPlayer.IsPinned;
}
}
UpdateButtons(); UpdateButtons();
} }
} }

View File

@@ -25,7 +25,7 @@ public sealed partial class PlayerListControl : BoxContainer
private PlayerInfo? _selectedPlayer; private PlayerInfo? _selectedPlayer;
private List<PlayerInfo> _playerList = new(); private List<PlayerInfo> _playerList = new();
private readonly List<PlayerInfo> _sortedPlayerList = new(); private List<PlayerInfo> _sortedPlayerList = new();
public Comparison<PlayerInfo>? Comparison; public Comparison<PlayerInfo>? Comparison;
public Func<PlayerInfo, string, string>? OverrideText; public Func<PlayerInfo, string, string>? OverrideText;
@@ -110,19 +110,30 @@ public sealed partial class PlayerListControl : BoxContainer
if (Comparison != null) if (Comparison != null)
_sortedPlayerList.Sort((a, b) => Comparison(a, b)); _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()); PlayerListContainer.PopulateList(_sortedPlayerList.Select(info => new PlayerListData(info)).ToList());
if (_selectedPlayer != null) if (_selectedPlayer != null)
PlayerListContainer.Select(new PlayerListData(_selectedPlayer)); PlayerListContainer.Select(new PlayerListData(_selectedPlayer));
} }
public void PopulateList(IReadOnlyList<PlayerInfo>? players = null) public void PopulateList(IReadOnlyList<PlayerInfo>? players = null)
{ {
// Maintain existing pin statuses
var pinnedPlayers = _playerList.Where(p => p.IsPinned).ToDictionary(p => p.SessionId);
players ??= _adminSystem.PlayerList; players ??= _adminSystem.PlayerList;
_playerList = players.ToList(); _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)) if (_selectedPlayer != null && !_playerList.Contains(_selectedPlayer))
_selectedPlayer = null; _selectedPlayer = null;