Files
PLib/src/PLib.Desktop/ViewModels/SortOption.cs
T

46 lines
1.8 KiB
C#

using DynamicData.Binding;
namespace PLib.Desktop.ViewModels;
/// <summary>
/// A sort order, its label, and the comparer DynamicData keeps the bound collection in.
/// </summary>
/// <remarks>
/// Every comparer ends with the identifier so the order is total. Ties would otherwise let
/// DynamicData move equal items around on each refresh, which the user sees as cards
/// twitching while a scan streams in.
/// </remarks>
public sealed record SortOption(string Label, IComparer<VideoCardViewModel> Comparer)
{
public static IReadOnlyList<SortOption> All { get; } =
[
new("Недавно добавленные", SortExpressionComparer<VideoCardViewModel>
.Descending(x => x.AddedAt)
.ThenByAscending(x => x.Id)),
new("По названию", new TitleComparer()),
new("Сначала длинные", SortExpressionComparer<VideoCardViewModel>
.Descending(x => x.RawDuration ?? TimeSpan.Zero)
.ThenByAscending(x => x.Id)),
new("Сначала большие", SortExpressionComparer<VideoCardViewModel>
.Descending(x => x.RawSizeInBytes)
.ThenByAscending(x => x.Id)),
];
/// <summary>
/// Culture-aware, case-insensitive title order. <see cref="SortExpressionComparer{T}"/>
/// would fall back to ordinal comparison, which puts Cyrillic and Latin titles in an
/// order no reader expects.
/// </summary>
private sealed class TitleComparer : IComparer<VideoCardViewModel>
{
public int Compare(VideoCardViewModel? x, VideoCardViewModel? y)
{
var byTitle = string.Compare(x?.Title, y?.Title, StringComparison.CurrentCultureIgnoreCase);
return byTitle != 0 ? byTitle : Comparer<Guid>.Default.Compare(x?.Id ?? Guid.Empty, y?.Id ?? Guid.Empty);
}
}
}