Files
dnsmasq-webui/src/DnsmasqWebUI/Client/Services/ClientSettingsService.cs
T
alex 92dfa2b170 Refactor: Bootstrap 5.3.8, Bootstrap Icons, Client/Http/Configuration layout
- Update Bootstrap to 5.3.8, add Bootstrap Icons; replace custom SVGs
- Fix settings modal: load editing state only when modal opens (avoid refresh overwrite)
- Home: StatusSection and LogsSection components with own timers
- Move HTTP clients under Client/Http with Abstractions namespace pattern
- Rename Options to Configuration; remove empty Options dir
- Components: Modals/, Home/; consistent Abstractions (Services, Client.Services, Client.Http)
2026-02-01 22:51:05 +10:00

73 lines
2.2 KiB
C#

using System.Text.Json;
using DnsmasqWebUI.Client.Models;
using DnsmasqWebUI.Client.Services.Abstractions;
using Microsoft.JSInterop;
namespace DnsmasqWebUI.Client.Services;
/// <summary>
/// Loads and saves client-side settings to browser local storage via JS interop.
/// Scoped per Blazor circuit; disposes the JS module when the scope is disposed.
/// </summary>
public sealed class ClientSettingsService : IClientSettingsService, IAsyncDisposable
{
private readonly IJSRuntime _jsRuntime;
private IJSObjectReference? _module;
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
WriteIndented = false
};
public ClientSettingsService(IJSRuntime jsRuntime) => _jsRuntime = jsRuntime;
private async Task<IJSObjectReference> GetModuleAsync()
{
if (_module != null) return _module;
_module = await _jsRuntime.InvokeAsync<IJSObjectReference>(
"import", "./js/client-settings-storage.js");
return _module;
}
/// <inheritdoc />
public async Task<ClientSettings> LoadSettingsAsync()
{
var module = await GetModuleAsync();
var json = await module.InvokeAsync<string?>("getItem");
if (string.IsNullOrWhiteSpace(json)) return new ClientSettings();
try
{
return JsonSerializer.Deserialize<ClientSettings>(json, JsonOptions) ?? new ClientSettings();
}
catch
{
return new ClientSettings();
}
}
/// <inheritdoc />
public async Task SaveSettingsAsync(ClientSettings settings)
{
var json = JsonSerializer.Serialize(settings, JsonOptions);
var module = await GetModuleAsync();
await module.InvokeVoidAsync("setItem", json);
}
/// <summary>
/// Disposes the JS module reference. Called when the Blazor circuit scope is disposed.
/// </summary>
public async ValueTask DisposeAsync()
{
if (_module == null) return;
try
{
await _module.DisposeAsync();
}
finally
{
_module = null;
}
}
}