Enhance video library management in PLib by introducing folder change tracking and improving video item metadata handling. Update IVideoRepository to include a method for loading video items with labels. Revise VideoPlayerViewModel to manage playback progress and integrate new UI elements for displaying watched status and resume options. Update MainWindowViewModel to observe folder changes for automatic rescanning. Enhance README.md to document these new features and usage instructions.
This commit is contained in:
@@ -1,50 +1,54 @@
|
||||
using PLib.Application.Abstractions;
|
||||
using PLib.Application.Library;
|
||||
using PLib.Domain.Videos;
|
||||
|
||||
namespace PLib.Tests.Library;
|
||||
|
||||
/// <summary>
|
||||
/// A hand-written double rather than a mock: the scan logic is all about what ends up in the
|
||||
/// repository, so the tests read better when they can just look at the resulting list.
|
||||
/// </summary>
|
||||
internal sealed class InMemoryVideoRepository : IVideoRepository
|
||||
{
|
||||
private readonly Dictionary<string, VideoItem> _items = new(LibraryPathComparer.Instance);
|
||||
|
||||
public int SaveCount { get; private set; }
|
||||
|
||||
public IReadOnlyCollection<VideoItem> Items => _items.Values;
|
||||
|
||||
public void Seed(params VideoItem[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
_items[item.FullPath] = item;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<IReadOnlyList<VideoItem>> GetAllAsync(CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<IReadOnlyList<VideoItem>>([.. _items.Values]);
|
||||
|
||||
public Task<VideoItem?> FindByPathAsync(string fullPath, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult(_items.GetValueOrDefault(fullPath));
|
||||
|
||||
public Task AddAsync(VideoItem item, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_items[item.FullPath] = item;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task RemoveAsync(VideoItem item, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_items.Remove(item.FullPath);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
SaveCount++;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
using PLib.Application.Abstractions;
|
||||
using PLib.Application.Library;
|
||||
using PLib.Domain.Videos;
|
||||
|
||||
namespace PLib.Tests.Library;
|
||||
|
||||
/// <summary>
|
||||
/// A hand-written double rather than a mock: the scan logic is all about what ends up in the
|
||||
/// repository, so the tests read better when they can just look at the resulting list.
|
||||
/// </summary>
|
||||
internal sealed class InMemoryVideoRepository : IVideoRepository
|
||||
{
|
||||
private readonly Dictionary<string, VideoItem> _items = new(LibraryPathComparer.Instance);
|
||||
|
||||
public int SaveCount { get; private set; }
|
||||
|
||||
public IReadOnlyCollection<VideoItem> Items => _items.Values;
|
||||
|
||||
public void Seed(params VideoItem[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
_items[item.FullPath] = item;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<IReadOnlyList<VideoItem>> GetAllAsync(CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<IReadOnlyList<VideoItem>>([.. _items.Values]);
|
||||
|
||||
public Task<VideoItem?> FindByPathAsync(string fullPath, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult(_items.GetValueOrDefault(fullPath));
|
||||
|
||||
// Labels are held on the entity itself here, so there is nothing extra to load.
|
||||
public Task<VideoItem?> FindWithLabelsAsync(Guid id, CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult(_items.Values.FirstOrDefault(item => item.Id == id));
|
||||
|
||||
public Task AddAsync(VideoItem item, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_items[item.FullPath] = item;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task RemoveAsync(VideoItem item, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_items.Remove(item.FullPath);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
SaveCount++;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user