diff --git a/src/TelegramPanel.Web/Components/Layout/MainLayout.razor b/src/TelegramPanel.Web/Components/Layout/MainLayout.razor index ac796b3..7d7fcb5 100644 --- a/src/TelegramPanel.Web/Components/Layout/MainLayout.razor +++ b/src/TelegramPanel.Web/Components/Layout/MainLayout.razor @@ -26,6 +26,9 @@ +@using TelegramPanel.Web.Services +@inject UiPreferencesService UiPreferences + @code { private bool _drawerOpen = true; private bool _isDarkMode = true; @@ -48,13 +51,21 @@ } }; + protected override async Task OnInitializedAsync() + { + // 从配置文件读取用户的主题偏好 + _isDarkMode = await UiPreferences.GetIsDarkModeAsync(); + } + private void ToggleDrawer() { _drawerOpen = !_drawerOpen; } - private void ToggleDarkMode() + private async Task ToggleDarkMode() { _isDarkMode = !_isDarkMode; + // 保存主题偏好到配置文件 + await UiPreferences.SetIsDarkModeAsync(_isDarkMode); } } diff --git a/src/TelegramPanel.Web/Program.cs b/src/TelegramPanel.Web/Program.cs index c3105dc..1cc2aef 100644 --- a/src/TelegramPanel.Web/Program.cs +++ b/src/TelegramPanel.Web/Program.cs @@ -291,6 +291,7 @@ builder.Services.AddTelegramPanelData(connectionString); builder.Services.AddTelegramPanelCore(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); diff --git a/src/TelegramPanel.Web/Services/UiPreferencesService.cs b/src/TelegramPanel.Web/Services/UiPreferencesService.cs new file mode 100644 index 0000000..8a1dbfa --- /dev/null +++ b/src/TelegramPanel.Web/Services/UiPreferencesService.cs @@ -0,0 +1,90 @@ +using System.Text; +using System.Text.Json; +using System.Text.Json.Nodes; +using Microsoft.AspNetCore.Hosting; + +namespace TelegramPanel.Web.Services; + +/// +/// UI 偏好设置服务,用于管理用户界面相关的配置(如主题模式) +/// +public class UiPreferencesService +{ + private readonly IConfiguration _configuration; + private readonly IWebHostEnvironment _environment; + private readonly string _configFilePath; + private readonly SemaphoreSlim _writeLock = new(1, 1); + + public UiPreferencesService(IConfiguration configuration, IWebHostEnvironment environment) + { + _configuration = configuration; + _environment = environment; + _configFilePath = LocalConfigFile.ResolvePath(configuration, environment); + } + + /// + /// 获取当前的深色模式设置 + /// + public async Task GetIsDarkModeAsync() + { + try + { + if (!File.Exists(_configFilePath)) + return true; // 默认使用深色模式 + + var json = await File.ReadAllTextAsync(_configFilePath); + var doc = JsonDocument.Parse(json); + + if (doc.RootElement.TryGetProperty("UI", out var uiSection) && + uiSection.TryGetProperty("IsDarkMode", out var isDarkModeValue)) + { + return isDarkModeValue.GetBoolean(); + } + + return true; // 默认使用深色模式 + } + catch + { + return true; // 出错时默认使用深色模式 + } + } + + /// + /// 设置深色模式 + /// + public async Task SetIsDarkModeAsync(bool isDarkMode) + { + await _writeLock.WaitAsync(); + try + { + // 确保配置文件存在 + await LocalConfigFile.EnsureExistsAsync(_configFilePath); + + // 读取现有配置 + var json = await File.ReadAllTextAsync(_configFilePath); + var jsonObj = JsonNode.Parse(json)?.AsObject() ?? new JsonObject(); + + // 更新 UI 配置 + if (!jsonObj.ContainsKey("UI")) + { + jsonObj["UI"] = new JsonObject(); + } + + var uiSection = jsonObj["UI"]!.AsObject(); + uiSection["IsDarkMode"] = isDarkMode; + + // 写入配置文件 + var options = new JsonSerializerOptions + { + WriteIndented = true, + Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }; + var updatedJson = JsonSerializer.Serialize(jsonObj, options); + await LocalConfigFile.WriteJsonAtomicallyAsync(_configFilePath, updatedJson); + } + finally + { + _writeLock.Release(); + } + } +}