46 lines
1.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|