Implement theme management and settings dialog in PLib video library manager. Add theme service for light/dark/system themes, integrate settings dialog for user preferences, and update app configuration to include appearance options. Enhance thumbnail caching with new methods for cache size and clearing. Update README.md to reflect new features and settings.
This commit is contained in:
+78
-69
@@ -1,69 +1,78 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PLib.Desktop.Imaging;
|
||||
using PLib.Desktop.Services;
|
||||
using PLib.Desktop.ViewModels;
|
||||
using PLib.Infrastructure;
|
||||
using PLib.Infrastructure.Storage;
|
||||
using Serilog;
|
||||
|
||||
namespace PLib.Desktop;
|
||||
|
||||
/// <summary>
|
||||
/// Composition root. Everything the application is made of is wired up here and nowhere else.
|
||||
/// </summary>
|
||||
internal static class AppHost
|
||||
{
|
||||
public static IHost Create(string[] args)
|
||||
{
|
||||
// The paths are needed to locate the user settings file, which is itself a
|
||||
// configuration source — so they are built before the container exists and then
|
||||
// handed to it as an instance.
|
||||
var paths = new AppPaths();
|
||||
|
||||
// A desktop app is launched from arbitrary working directories, so the content root
|
||||
// has to be the folder the executable lives in rather than Environment.CurrentDirectory.
|
||||
var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
|
||||
{
|
||||
Args = args,
|
||||
ContentRootPath = AppContext.BaseDirectory,
|
||||
});
|
||||
|
||||
builder.Configuration.AddJsonFile(
|
||||
Path.Combine(paths.DataDirectory, "settings.json"),
|
||||
optional: true,
|
||||
reloadOnChange: true);
|
||||
|
||||
ConfigureLogging(builder, paths);
|
||||
|
||||
builder.Services.AddSingleton<IAppPaths>(paths);
|
||||
builder.Services.AddPLibInfrastructure(builder.Configuration);
|
||||
|
||||
builder.Services.AddSingleton<ThumbnailCache>();
|
||||
builder.Services.AddSingleton<IThumbnailLoader>(sp => sp.GetRequiredService<ThumbnailCache>());
|
||||
builder.Services.AddSingleton<ILibrarySettingsStore, JsonLibrarySettingsStore>();
|
||||
builder.Services.AddSingleton<IFolderPicker, StorageProviderFolderPicker>();
|
||||
builder.Services.AddSingleton<ISystemShell, SystemShell>();
|
||||
builder.Services.AddSingleton<IThemeService, ThemeService>();
|
||||
builder.Services.AddSingleton<MainWindowViewModel>();
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
private static void ConfigureLogging(HostApplicationBuilder builder, IAppPaths paths)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Information()
|
||||
.WriteTo.Console()
|
||||
.WriteTo.File(
|
||||
Path.Combine(paths.DataDirectory, "logs", "plib-.log"),
|
||||
rollingInterval: RollingInterval.Day,
|
||||
retainedFileCountLimit: 7)
|
||||
.CreateLogger();
|
||||
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Logging.AddSerilog(Log.Logger, dispose: true);
|
||||
}
|
||||
}
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PLib.Desktop.Imaging;
|
||||
using PLib.Desktop.Services;
|
||||
using PLib.Desktop.Settings;
|
||||
using PLib.Desktop.ViewModels;
|
||||
using PLib.Infrastructure;
|
||||
using PLib.Infrastructure.Storage;
|
||||
using Serilog;
|
||||
|
||||
namespace PLib.Desktop;
|
||||
|
||||
/// <summary>
|
||||
/// Composition root. Everything the application is made of is wired up here and nowhere else.
|
||||
/// </summary>
|
||||
internal static class AppHost
|
||||
{
|
||||
public static IHost Create(string[] args)
|
||||
{
|
||||
// The paths are needed to locate the user settings file, which is itself a
|
||||
// configuration source — so they are built before the container exists and then
|
||||
// handed to it as an instance.
|
||||
var paths = new AppPaths();
|
||||
|
||||
// A desktop app is launched from arbitrary working directories, so the content root
|
||||
// has to be the folder the executable lives in rather than Environment.CurrentDirectory.
|
||||
var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
|
||||
{
|
||||
Args = args,
|
||||
ContentRootPath = AppContext.BaseDirectory,
|
||||
});
|
||||
|
||||
builder.Configuration.AddJsonFile(
|
||||
Path.Combine(paths.DataDirectory, "settings.json"),
|
||||
optional: true,
|
||||
reloadOnChange: true);
|
||||
|
||||
ConfigureLogging(builder, paths);
|
||||
|
||||
builder.Services.AddSingleton<IAppPaths>(paths);
|
||||
|
||||
builder.Services.AddOptions<AppearanceOptions>()
|
||||
.Bind(builder.Configuration.GetSection(AppearanceOptions.SectionName));
|
||||
builder.Services.AddPLibInfrastructure(builder.Configuration);
|
||||
|
||||
builder.Services.AddSingleton<ThumbnailCache>();
|
||||
builder.Services.AddSingleton<IThumbnailLoader>(sp => sp.GetRequiredService<ThumbnailCache>());
|
||||
builder.Services.AddSingleton<IAppSettingsStore, JsonAppSettingsStore>();
|
||||
builder.Services.AddSingleton<IDialogService, DialogService>();
|
||||
builder.Services.AddSingleton<IFolderPicker, StorageProviderFolderPicker>();
|
||||
builder.Services.AddSingleton<ISystemShell, SystemShell>();
|
||||
builder.Services.AddSingleton<IThemeService, ThemeService>();
|
||||
builder.Services.AddSingleton<MainWindowViewModel>();
|
||||
|
||||
// Scoped, not singleton: the settings dialog edits a working copy, so each opening
|
||||
// gets its own model and a cancelled edit never leaks into the next one.
|
||||
builder.Services.AddScoped<SettingsViewModel>();
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
private static void ConfigureLogging(HostApplicationBuilder builder, IAppPaths paths)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Information()
|
||||
.WriteTo.Console()
|
||||
.WriteTo.File(
|
||||
Path.Combine(paths.DataDirectory, "logs", "plib-.log"),
|
||||
rollingInterval: RollingInterval.Day,
|
||||
retainedFileCountLimit: 7)
|
||||
.CreateLogger();
|
||||
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Logging.AddSerilog(Log.Logger, dispose: true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user