Refactor PLib video library manager to use ReactiveUI, replacing CommunityToolkit.Mvvm. Update dependencies, enhance thumbnail caching logic, and improve UI responsiveness with reactive commands. Remove obsolete PLib.slnx file and update README.md to reflect changes.
This commit is contained in:
@@ -1,21 +1,45 @@
|
||||
using DynamicData.Binding;
|
||||
|
||||
namespace PLib.Desktop.ViewModels;
|
||||
|
||||
public enum LibrarySort
|
||||
{
|
||||
RecentlyAdded,
|
||||
TitleAscending,
|
||||
LongestFirst,
|
||||
LargestFirst,
|
||||
}
|
||||
|
||||
/// <summary>A sort order together with the label the combo box shows for it.</summary>
|
||||
public sealed record SortOption(LibrarySort Sort, string Label)
|
||||
/// <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(LibrarySort.RecentlyAdded, "Недавно добавленные"),
|
||||
new(LibrarySort.TitleAscending, "По названию"),
|
||||
new(LibrarySort.LongestFirst, "Сначала длинные"),
|
||||
new(LibrarySort.LargestFirst, "Сначала большие"),
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user