1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-05 10:33:22 +08:00

Fix chat channel listing not being ordered to expectations

- Public channels (and announcements) are now alphabetically ordered.
- Private message channels are now ordered by most recent activity.

Closes https://github.com/ppy/osu/issues/30835.
This commit is contained in:
Dean Herbert 2024-11-22 19:51:55 +09:00
parent c844d65a81
commit 9930922769
No known key found for this signature in database

View File

@ -77,10 +77,10 @@ namespace osu.Game.Overlays.Chat.ChannelList
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
} }
}, },
announceChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitleANNOUNCE.ToUpper()), announceChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitleANNOUNCE.ToUpper(), false),
publicChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitlePUBLIC.ToUpper()), publicChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitlePUBLIC.ToUpper(), false),
selector = new ChannelListItem(ChannelListingChannel), selector = new ChannelListItem(ChannelListingChannel),
privateChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitlePM.ToUpper()), privateChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitlePM.ToUpper(), true),
}, },
}, },
}, },
@ -111,9 +111,9 @@ namespace osu.Game.Overlays.Chat.ChannelList
item.OnRequestSelect += chan => OnRequestSelect?.Invoke(chan); item.OnRequestSelect += chan => OnRequestSelect?.Invoke(chan);
item.OnRequestLeave += chan => OnRequestLeave?.Invoke(chan); item.OnRequestLeave += chan => OnRequestLeave?.Invoke(chan);
FillFlowContainer<ChannelListItem> flow = getFlowForChannel(channel); ChannelGroup group = getGroupFromChannel(channel);
channelMap.Add(channel, item); channelMap.Add(channel, item);
flow.Add(item); group.AddChannel(item);
updateVisibility(); updateVisibility();
} }
@ -123,10 +123,10 @@ namespace osu.Game.Overlays.Chat.ChannelList
if (!channelMap.TryGetValue(channel, out var item)) if (!channelMap.TryGetValue(channel, out var item))
return; return;
FillFlowContainer<ChannelListItem> flow = getFlowForChannel(channel); ChannelGroup group = getGroupFromChannel(channel);
channelMap.Remove(channel); channelMap.Remove(channel);
flow.Remove(item, true); group.RemoveChannel(item);
updateVisibility(); updateVisibility();
} }
@ -141,21 +141,21 @@ namespace osu.Game.Overlays.Chat.ChannelList
public void ScrollChannelIntoView(Channel channel) => scroll.ScrollIntoView(GetItem(channel)); public void ScrollChannelIntoView(Channel channel) => scroll.ScrollIntoView(GetItem(channel));
private FillFlowContainer<ChannelListItem> getFlowForChannel(Channel channel) private ChannelGroup getGroupFromChannel(Channel channel)
{ {
switch (channel.Type) switch (channel.Type)
{ {
case ChannelType.Public: case ChannelType.Public:
return publicChannelGroup.ItemFlow; return publicChannelGroup;
case ChannelType.PM: case ChannelType.PM:
return privateChannelGroup.ItemFlow; return privateChannelGroup;
case ChannelType.Announce: case ChannelType.Announce:
return announceChannelGroup.ItemFlow; return announceChannelGroup;
default: default:
return publicChannelGroup.ItemFlow; return publicChannelGroup;
} }
} }
@ -169,9 +169,9 @@ namespace osu.Game.Overlays.Chat.ChannelList
private partial class ChannelGroup : FillFlowContainer private partial class ChannelGroup : FillFlowContainer
{ {
public readonly FillFlowContainer<ChannelListItem> ItemFlow; public readonly ChannelListItemFlow ItemFlow;
public ChannelGroup(LocalisableString label) public ChannelGroup(LocalisableString label, bool sortByRecent)
{ {
Direction = FillDirection.Vertical; Direction = FillDirection.Vertical;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
@ -186,7 +186,7 @@ namespace osu.Game.Overlays.Chat.ChannelList
Margin = new MarginPadding { Left = 18, Bottom = 5 }, Margin = new MarginPadding { Left = 18, Bottom = 5 },
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold), Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold),
}, },
ItemFlow = new FillFlowContainer<ChannelListItem> ItemFlow = new ChannelListItemFlow(sortByRecent)
{ {
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
@ -194,6 +194,42 @@ namespace osu.Game.Overlays.Chat.ChannelList
}, },
}; };
} }
public partial class ChannelListItemFlow : FillFlowContainer<ChannelListItem>
{
private readonly bool sortByRecent;
public ChannelListItemFlow(bool sortByRecent)
{
this.sortByRecent = sortByRecent;
}
public void Reflow() => InvalidateLayout();
public override IEnumerable<Drawable> FlowingChildren => sortByRecent
? base.FlowingChildren.OfType<ChannelListItem>().OrderByDescending(i => i.Channel.LastMessageId)
: base.FlowingChildren.OfType<ChannelListItem>().OrderBy(i => i.Channel.Name);
}
public void AddChannel(ChannelListItem item)
{
ItemFlow.Add(item);
item.Channel.NewMessagesArrived += newMessagesArrived;
item.Channel.PendingMessageResolved += pendingMessageResolved;
ItemFlow.Reflow();
}
public void RemoveChannel(ChannelListItem item)
{
item.Channel.NewMessagesArrived -= newMessagesArrived;
item.Channel.PendingMessageResolved -= pendingMessageResolved;
ItemFlow.Remove(item, true);
}
private void pendingMessageResolved(LocalEchoMessage _, Message __) => ItemFlow.Reflow();
private void newMessagesArrived(IEnumerable<Message> _) => ItemFlow.Reflow();
} }
private partial class ChannelSearchTextBox : BasicSearchTextBox private partial class ChannelSearchTextBox : BasicSearchTextBox