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:
@@ -1,4 +1,6 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NSubstitute;
|
||||
using PLib.Application.Library;
|
||||
using PLib.Desktop.Services;
|
||||
using PLib.Desktop.Settings;
|
||||
@@ -28,11 +30,13 @@ public sealed class AppSettingsStoreTests : IDisposable
|
||||
MaxIndexingConcurrency = 8,
|
||||
MinimumFileSizeInBytes = 2_097_152,
|
||||
Theme = ThemeMode.Light,
|
||||
Volume = 0.35,
|
||||
IsMuted = true,
|
||||
};
|
||||
|
||||
await new JsonAppSettingsStore(_paths).SaveAsync(settings, Token);
|
||||
await CreateStore().SaveAsync(settings, Token);
|
||||
|
||||
var (library, appearance) = Reload();
|
||||
var (library, appearance, playback) = Reload();
|
||||
|
||||
library.Folders.ShouldBe(settings.Folders);
|
||||
library.ThumbnailWidth.ShouldBe(640);
|
||||
@@ -40,12 +44,14 @@ public sealed class AppSettingsStoreTests : IDisposable
|
||||
library.MaxIndexingConcurrency.ShouldBe(8);
|
||||
library.MinimumFileSizeInBytes.ShouldBe(2_097_152);
|
||||
appearance.Theme.ShouldBe(ThemeMode.Light);
|
||||
playback.Volume.ShouldBe(0.35);
|
||||
playback.IsMuted.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Removing_a_folder_actually_shortens_the_stored_list()
|
||||
{
|
||||
var store = new JsonAppSettingsStore(_paths);
|
||||
var store = CreateStore();
|
||||
var settings = Sample with { Folders = [@"C:\a", @"C:\b", @"C:\c"] };
|
||||
|
||||
await store.SaveAsync(settings, Token);
|
||||
@@ -64,7 +70,7 @@ public sealed class AppSettingsStoreTests : IDisposable
|
||||
"""{ "Library": { "VideoExtensions": [ ".mp4" ] }, "Experimental": { "Flag": true } }""",
|
||||
Token);
|
||||
|
||||
await new JsonAppSettingsStore(_paths).SaveAsync(Sample, Token);
|
||||
await CreateStore().SaveAsync(Sample, Token);
|
||||
|
||||
var configuration = Build();
|
||||
configuration["Experimental:Flag"].ShouldBe("True");
|
||||
@@ -93,13 +99,32 @@ public sealed class AppSettingsStoreTests : IDisposable
|
||||
MaxIndexingConcurrency = 4,
|
||||
MinimumFileSizeInBytes = 65_536,
|
||||
Theme = ThemeMode.System,
|
||||
Volume = 0.8,
|
||||
IsMuted = false,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The store composes <see cref="AppSettings.Current"/> from configuration, which these
|
||||
/// tests do not exercise — every case here supplies the snapshot it wants to write.
|
||||
/// </summary>
|
||||
private JsonAppSettingsStore CreateStore() => new(
|
||||
_paths,
|
||||
Monitor(new LibraryOptions()),
|
||||
Monitor(new AppearanceOptions()),
|
||||
Monitor(new PlaybackOptions()));
|
||||
|
||||
private static IOptionsMonitor<T> Monitor<T>(T value)
|
||||
{
|
||||
var monitor = Substitute.For<IOptionsMonitor<T>>();
|
||||
monitor.CurrentValue.Returns(value);
|
||||
return monitor;
|
||||
}
|
||||
|
||||
private IConfigurationRoot Build() => new ConfigurationBuilder()
|
||||
.AddJsonFile(Path.Combine(_paths.DataDirectory, "settings.json"), optional: false)
|
||||
.Build();
|
||||
|
||||
private (LibraryOptions Library, AppearanceOptions Appearance) Reload()
|
||||
private (LibraryOptions Library, AppearanceOptions Appearance, PlaybackOptions Playback) Reload()
|
||||
{
|
||||
var configuration = Build();
|
||||
|
||||
@@ -109,7 +134,10 @@ public sealed class AppSettingsStoreTests : IDisposable
|
||||
var appearance = new AppearanceOptions();
|
||||
configuration.GetSection(AppearanceOptions.SectionName).Bind(appearance);
|
||||
|
||||
return (library, appearance);
|
||||
var playback = new PlaybackOptions();
|
||||
configuration.GetSection(PlaybackOptions.SectionName).Bind(playback);
|
||||
|
||||
return (library, appearance, playback);
|
||||
}
|
||||
|
||||
private sealed class TempPaths : IAppPaths, IDisposable
|
||||
|
||||
Reference in New Issue
Block a user