Enhance playback settings management in PLib video library manager. Introduce PlaybackOptions for volume and mute settings, integrating them into AppSettings and IAppSettingsStore. Update VideoPlayerViewModel to persist playback state and adjust UI bindings in VideoPlayerView for volume control. Revise README.md to document new playback settings functionality.

This commit is contained in:
Leonid Pershin
2026-08-09 06:46:33 +03:00
parent b13d0148df
commit a938a48de9
14 changed files with 399 additions and 251 deletions
+52 -43
View File
@@ -1,43 +1,52 @@
using PLib.Application.Library;
namespace PLib.Desktop.Settings;
/// <summary>
/// The subset of configuration the user can change at runtime, as one snapshot.
/// </summary>
/// <remarks>
/// Everything is written in a single pass rather than key by key: a settings file that is
/// only ever replaced whole cannot end up in a state that never existed in the UI.
/// </remarks>
public sealed record AppSettings
{
public required IReadOnlyList<string> Folders { get; init; }
public required int ThumbnailWidth { get; init; }
public required double ThumbnailPositionRatio { get; init; }
public required int MaxIndexingConcurrency { get; init; }
public required long MinimumFileSizeInBytes { get; init; }
public required ThemeMode Theme { get; init; }
public static AppSettings From(LibraryOptions library, AppearanceOptions appearance) => new()
{
Folders = [.. library.Folders],
ThumbnailWidth = library.ThumbnailWidth,
ThumbnailPositionRatio = library.ThumbnailPositionRatio,
MaxIndexingConcurrency = library.MaxIndexingConcurrency,
MinimumFileSizeInBytes = library.MinimumFileSizeInBytes,
Theme = appearance.Theme,
};
/// <summary>
/// True when the difference between the two snapshots means the library has to be
/// walked again. Cosmetic changes must not trigger a rescan.
/// </summary>
public bool RequiresRescanComparedTo(AppSettings other) =>
!Folders.SequenceEqual(other.Folders, LibraryPathComparer.Instance) ||
MinimumFileSizeInBytes != other.MinimumFileSizeInBytes;
}
using PLib.Application.Library;
namespace PLib.Desktop.Settings;
/// <summary>
/// The subset of configuration the user can change at runtime, as one snapshot.
/// </summary>
/// <remarks>
/// Everything is written in a single pass rather than key by key: a settings file that is
/// only ever replaced whole cannot end up in a state that never existed in the UI.
/// </remarks>
public sealed record AppSettings
{
public required IReadOnlyList<string> Folders { get; init; }
public required int ThumbnailWidth { get; init; }
public required double ThumbnailPositionRatio { get; init; }
public required int MaxIndexingConcurrency { get; init; }
public required long MinimumFileSizeInBytes { get; init; }
public required ThemeMode Theme { get; init; }
public required double Volume { get; init; }
public required bool IsMuted { get; init; }
public static AppSettings From(
LibraryOptions library,
AppearanceOptions appearance,
PlaybackOptions playback) => new()
{
Folders = [.. library.Folders],
ThumbnailWidth = library.ThumbnailWidth,
ThumbnailPositionRatio = library.ThumbnailPositionRatio,
MaxIndexingConcurrency = library.MaxIndexingConcurrency,
MinimumFileSizeInBytes = library.MinimumFileSizeInBytes,
Theme = appearance.Theme,
Volume = playback.Volume,
IsMuted = playback.IsMuted,
};
/// <summary>
/// True when the difference between the two snapshots means the library has to be
/// walked again. Cosmetic changes must not trigger a rescan.
/// </summary>
public bool RequiresRescanComparedTo(AppSettings other) =>
!Folders.SequenceEqual(other.Folders, LibraryPathComparer.Instance) ||
MinimumFileSizeInBytes != other.MinimumFileSizeInBytes;
}