Skip to content

Commit

Permalink
Fix chat channel listing not being ordered to expectations
Browse files Browse the repository at this point in the history
- Public channels (and announcements) are now alphabetically ordered.
- Private message channels are now ordered by most recent activity.
  • Loading branch information
peppy committed Nov 22, 2024
1 parent c844d65 commit 7d343db
Showing 1 changed file with 51 additions and 15 deletions.
66 changes: 51 additions & 15 deletions osu.Game/Overlays/Chat/ChannelList/ChannelList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ private void load(OverlayColourProvider colourProvider)
RelativeSizeAxes = Axes.X,
}
},
announceChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitleANNOUNCE.ToUpper()),
publicChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitlePUBLIC.ToUpper()),
announceChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitleANNOUNCE.ToUpper(), false),
publicChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitlePUBLIC.ToUpper(), false),
selector = new ChannelListItem(ChannelListingChannel),
privateChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitlePM.ToUpper()),
privateChannelGroup = new ChannelGroup(ChatStrings.ChannelsListTitlePM.ToUpper(), true),
},
},
},
Expand Down Expand Up @@ -111,9 +111,9 @@ public void AddChannel(Channel channel)
item.OnRequestSelect += chan => OnRequestSelect?.Invoke(chan);
item.OnRequestLeave += chan => OnRequestLeave?.Invoke(chan);

FillFlowContainer<ChannelListItem> flow = getFlowForChannel(channel);
ChannelGroup group = getGroupFromChannel(channel);
channelMap.Add(channel, item);
flow.Add(item);
group.AddChannel(item);

updateVisibility();
}
Expand All @@ -123,10 +123,10 @@ public void RemoveChannel(Channel channel)
if (!channelMap.TryGetValue(channel, out var item))
return;

FillFlowContainer<ChannelListItem> flow = getFlowForChannel(channel);
ChannelGroup group = getGroupFromChannel(channel);

channelMap.Remove(channel);
flow.Remove(item, true);
group.RemoveChannel(item);

updateVisibility();
}
Expand All @@ -141,21 +141,21 @@ public ChannelListItem GetItem(Channel channel)

public void ScrollChannelIntoView(Channel channel) => scroll.ScrollIntoView(GetItem(channel));

private FillFlowContainer<ChannelListItem> getFlowForChannel(Channel channel)
private ChannelGroup getGroupFromChannel(Channel channel)
{
switch (channel.Type)
{
case ChannelType.Public:
return publicChannelGroup.ItemFlow;
return publicChannelGroup;

case ChannelType.PM:
return privateChannelGroup.ItemFlow;
return privateChannelGroup;

case ChannelType.Announce:
return announceChannelGroup.ItemFlow;
return announceChannelGroup;

default:
return publicChannelGroup.ItemFlow;
return publicChannelGroup;
}
}

Expand All @@ -169,9 +169,9 @@ private void updateVisibility()

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;
RelativeSizeAxes = Axes.X;
Expand All @@ -186,14 +186,50 @@ public ChannelGroup(LocalisableString label)
Margin = new MarginPadding { Left = 18, Bottom = 5 },
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold),
},
ItemFlow = new FillFlowContainer<ChannelListItem>
ItemFlow = new ChannelListItemFlow(sortByRecent)
{
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
},
};
}

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
Expand Down

0 comments on commit 7d343db

Please sign in to comment.