33 lines
1.2 KiB
C#
33 lines
1.2 KiB
C#
namespace VoiceCat.Windows;
|
|||
|
|
|
||
|
|
/// <summary>A channel and its ordered children as displayed by the Windows client.</summary>
|
||
|
|
public sealed record ChannelHierarchyItem(
|
||
|
|
ChannelInfo Channel,
|
||
|
|
IReadOnlyList<ChannelHierarchyItem> Children);
|
||
|
|
|
||
|
|
public static class ChannelHierarchy
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Builds the server-defined channel hierarchy. SortOrder orders siblings; LINQ's stable
|
||
|
|
/// ordering preserves the server's sequence when siblings have the same value.
|
||
|
|
/// </summary>
|
||
|
|
public static IReadOnlyList<ChannelHierarchyItem> Build(IReadOnlyList<ChannelInfo> channels)
|
||
|
|
{
|
||
|
|
var byParent = channels
|
||
|
|
.GroupBy(channel => channel.ParentId)
|
||
|
|
.ToDictionary(group => group.Key, group => group.OrderBy(channel => channel.SortOrder).ToArray());
|
||
|
|
|
||
|
|
IReadOnlyList<ChannelHierarchyItem> AddChildren(uint parentId)
|
||
|
|
{
|
||
|
|
if (!byParent.TryGetValue(parentId, out ChannelInfo[]? children))
|
||
|
|
return [];
|
||
|
|
|
||
|
|
return children
|
||
|
|
.Select(channel => new ChannelHierarchyItem(channel, AddChildren(channel.Id)))
|
||
|
|
.ToArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
return AddChildren(0);
|
||
|
|
}
|
||
|
|
}
|