using DynamicData.Binding;
namespace PLib.Desktop.ViewModels;
///
/// A sort order, its label, and the comparer DynamicData keeps the bound collection in.
///
///
/// 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.
///
public sealed record SortOption(string Label, IComparer Comparer)
{
public static IReadOnlyList All { get; } =
[
new("Недавно добавленные", SortExpressionComparer
.Descending(x => x.AddedAt)
.ThenByAscending(x => x.Id)),
new("По названию", new TitleComparer()),
new("Сначала длинные", SortExpressionComparer
.Descending(x => x.RawDuration ?? TimeSpan.Zero)
.ThenByAscending(x => x.Id)),
new("Сначала большие", SortExpressionComparer
.Descending(x => x.RawSizeInBytes)
.ThenByAscending(x => x.Id)),
];
///
/// Culture-aware, case-insensitive title order.
/// would fall back to ordinal comparison, which puts Cyrillic and Latin titles in an
/// order no reader expects.
///
private sealed class TitleComparer : IComparer
{
public int Compare(VideoCardViewModel? x, VideoCardViewModel? y)
{
var byTitle = string.Compare(x?.Title, y?.Title, StringComparison.CurrentCultureIgnoreCase);
return byTitle != 0 ? byTitle : Comparer.Default.Compare(x?.Id ?? Guid.Empty, y?.Id ?? Guid.Empty);
}
}
}