From 9045624105b0db070aea384b0480ca46586be0a1 Mon Sep 17 00:00:00 2001 From: lincube Date: Tue, 31 Mar 2026 01:16:53 +0800 Subject: [PATCH] 0.8.0.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 自习功能可关闭 --- LanMountainDesktop/Localization/en-US.json | 4 +++ LanMountainDesktop/Localization/zh-CN.json | 4 +++ .../Models/AppSettingsSnapshot.cs | 2 ++ .../ViewModels/SettingsViewModels.cs | 35 +++++++++++++++++++ .../StudyDeductionReasonsWidget.axaml.cs | 19 ++++++++-- .../StudyEnvironmentWidget.axaml.cs | 20 +++++++++++ .../StudyInterruptDensityWidget.axaml.cs | 21 ++++++++++- .../Components/StudyNoiseCurveWidget.axaml.cs | 18 ++++++++++ .../StudyNoiseDistributionWidget.axaml.cs | 21 ++++++++++- .../StudyScoreOverviewWidget.axaml.cs | 21 ++++++++++- .../StudySessionControlWidget.axaml.cs | 21 ++++++++++- .../StudySessionHistoryWidget.axaml.cs | 15 ++++++++ .../SettingsPages/StudySettingsPage.axaml | 24 ++++++++++--- 13 files changed, 215 insertions(+), 10 deletions(-) diff --git a/LanMountainDesktop/Localization/en-US.json b/LanMountainDesktop/Localization/en-US.json index f0de867..186d835 100644 --- a/LanMountainDesktop/Localization/en-US.json +++ b/LanMountainDesktop/Localization/en-US.json @@ -205,6 +205,8 @@ "settings.weather.footer_hint": "Desktop weather widgets will reuse the location and alert exclusion settings configured here.", "settings.study.title": "Study", "settings.study.description": "Configure study environment monitoring, focus timer, and alert settings.", + "settings.study.master_switch_header": "Study Feature", + "settings.study.master_switch_desc": "Enable study environment monitoring and focus timer. When disabled, related components will not collect any data.", "settings.study.noise_header": "Noise Monitoring", "settings.study.noise_description": "Configure microphone sampling rate and noise scoring sensitivity.", "settings.study.sampling_rate_label": "Sampling Rate", @@ -883,6 +885,8 @@ "recording.widget.hint.saved_format": "Saved {0}", "recording.widget.save_picker_title": "Save recording file", "recording.widget.save_picker_type": "WAV audio", + "study.widget.disabled_title": "Study Feature Disabled", + "study.widget.disabled_hint": "Please enable in Settings", "study.environment.status_label": "Environment", "study.environment.status.initializing": "Initializing", "study.environment.status.ready": "Ready", diff --git a/LanMountainDesktop/Localization/zh-CN.json b/LanMountainDesktop/Localization/zh-CN.json index 7f82812..2452692 100644 --- a/LanMountainDesktop/Localization/zh-CN.json +++ b/LanMountainDesktop/Localization/zh-CN.json @@ -208,6 +208,8 @@ "settings.weather.location_saved_format": "天气位置已保存:{0}", "settings.study.title": "自习", "settings.study.description": "配置自习环境监测、专注计时和提醒设置。", + "settings.study.master_switch_header": "自习功能", + "settings.study.master_switch_desc": "启用自习环境监测和专注计时功能。关闭后,相关组件将不会采集任何数据。", "settings.study.noise_header": "噪音监测", "settings.study.noise_description": "配置麦克风采集频率和噪音评分敏感度。", "settings.study.sampling_rate_label": "采集频率", @@ -876,6 +878,8 @@ "recording.widget.hint.saved_format": "已保存 {0}", "recording.widget.save_picker_title": "保存录音文件", "recording.widget.save_picker_type": "WAV 音频", + "study.widget.disabled_title": "自习功能未启用", + "study.widget.disabled_hint": "请在设置中开启", "study.environment.status_label": "环境状态", "study.environment.status.initializing": "初始化中", "study.environment.status.ready": "待机", diff --git a/LanMountainDesktop/Models/AppSettingsSnapshot.cs b/LanMountainDesktop/Models/AppSettingsSnapshot.cs index de2634f..78de6c8 100644 --- a/LanMountainDesktop/Models/AppSettingsSnapshot.cs +++ b/LanMountainDesktop/Models/AppSettingsSnapshot.cs @@ -120,6 +120,8 @@ public sealed class AppSettingsSnapshot #region Study Settings + public bool StudyEnabled { get; set; } = true; + public int? StudyFrameMs { get; set; } public double? StudyScoreThresholdDbfs { get; set; } diff --git a/LanMountainDesktop/ViewModels/SettingsViewModels.cs b/LanMountainDesktop/ViewModels/SettingsViewModels.cs index 95ced56..01ff0b5 100644 --- a/LanMountainDesktop/ViewModels/SettingsViewModels.cs +++ b/LanMountainDesktop/ViewModels/SettingsViewModels.cs @@ -2342,6 +2342,27 @@ public sealed partial class StudySettingsPageViewModel : ViewModelBase _isInitializing = false; } + #region Properties - Master Switch + + [ObservableProperty] + private string _masterSwitchHeader = string.Empty; + + [ObservableProperty] + private string _masterSwitchDescription = string.Empty; + + [ObservableProperty] + private bool _studyEnabled = true; + + partial void OnStudyEnabledChanged(bool value) + { + if (!_isInitializing) + { + SaveMasterSwitch(); + } + } + + #endregion + #region Properties - Noise Monitoring [ObservableProperty] @@ -2686,6 +2707,9 @@ public sealed partial class StudySettingsPageViewModel : ViewModelBase { var appSnapshot = _settingsFacade.Settings.LoadSnapshot(SettingsScope.App); + // Master switch + StudyEnabled = appSnapshot.StudyEnabled; + // Noise settings SamplingRateMs = appSnapshot.StudyFrameMs is > 0 ? appSnapshot.StudyFrameMs.Value : 50; NoiseSensitivityDbfs = appSnapshot.StudyScoreThresholdDbfs ?? -50; @@ -2718,6 +2742,14 @@ public sealed partial class StudySettingsPageViewModel : ViewModelBase UpdateAvgWindowSecText(); } + private void SaveMasterSwitch() + { + var appSnapshot = _settingsFacade.Settings.LoadSnapshot(SettingsScope.App); + appSnapshot.StudyEnabled = StudyEnabled; + _settingsFacade.Settings.SaveSnapshot(SettingsScope.App, appSnapshot, + changedKeys: [nameof(AppSettingsSnapshot.StudyEnabled)]); + } + private void SaveNoiseSettings() { var appSnapshot = _settingsFacade.Settings.LoadSnapshot(SettingsScope.App); @@ -2796,6 +2828,9 @@ public sealed partial class StudySettingsPageViewModel : ViewModelBase private void RefreshLocalizedText() { + MasterSwitchHeader = L("settings.study.master_switch_header", "自习功能"); + MasterSwitchDescription = L("settings.study.master_switch_desc", "启用自习环境监测和专注计时功能。关闭后,相关组件将不会采集任何数据。"); + NoiseMonitoringHeader = L("settings.study.noise_header", "噪音监测"); NoiseMonitoringDescription = L("settings.study.noise_description", "配置麦克风采集频率和噪音评分敏感度。"); SamplingRateLabel = L("settings.study.sampling_rate_label", "采集频率"); diff --git a/LanMountainDesktop/Views/Components/StudyDeductionReasonsWidget.axaml.cs b/LanMountainDesktop/Views/Components/StudyDeductionReasonsWidget.axaml.cs index a15f35b..45ef965 100644 --- a/LanMountainDesktop/Views/Components/StudyDeductionReasonsWidget.axaml.cs +++ b/LanMountainDesktop/Views/Components/StudyDeductionReasonsWidget.axaml.cs @@ -53,6 +53,7 @@ public partial class StudyDeductionReasonsWidget : UserControl, IDesktopComponen private bool _isOnActivePage = true; private bool _isCompactMode; private bool _isUltraCompactMode; + private bool _studyEnabled = true; private string _languageCode = "zh-CN"; private readonly record struct DeductionMetrics( @@ -98,7 +99,10 @@ public partial class StudyDeductionReasonsWidget : UserControl, IDesktopComponen { _isAttached = true; ReloadLanguageCode(); - _ = _studyAnalyticsService.StartOrResumeMonitoring(); + if (_studyEnabled) + { + _ = _studyAnalyticsService.StartOrResumeMonitoring(); + } UpdateTimerState(); RefreshVisual(); } @@ -142,10 +146,20 @@ public partial class StudyDeductionReasonsWidget : UserControl, IDesktopComponen private void RefreshVisual() { - var snapshot = _studyAnalyticsService.GetSnapshot(); var panelColor = ResolvePanelBackgroundColor(); ApplyTypographyByBackground(panelColor); + if (!_studyEnabled) + { + ModeTextBlock.Text = L("study.widget.disabled_hint", "请在设置中开启"); + ApplyModeBadgeColor(panelColor, Color.Parse("#FF9AA0A6")); + ApplyLocalizedLabels(); + ApplyUnavailableMetrics(); + return; + } + + var snapshot = _studyAnalyticsService.GetSnapshot(); + var isSessionRunning = snapshot.Session.State == StudySessionRuntimeState.Running; var isSessionReport = snapshot.DataMode == StudyDataMode.SessionReport && snapshot.LastSessionReport is not null; var isSessionView = isSessionRunning || isSessionReport; @@ -595,6 +609,7 @@ public partial class StudyDeductionReasonsWidget : UserControl, IDesktopComponen { var snapshot = _settingsService.Load(); _languageCode = _localizationService.NormalizeLanguageCode(snapshot.LanguageCode); + _studyEnabled = snapshot.StudyEnabled; } private void ApplyVariableFontFamily() diff --git a/LanMountainDesktop/Views/Components/StudyEnvironmentWidget.axaml.cs b/LanMountainDesktop/Views/Components/StudyEnvironmentWidget.axaml.cs index 5381d80..9212264 100644 --- a/LanMountainDesktop/Views/Components/StudyEnvironmentWidget.axaml.cs +++ b/LanMountainDesktop/Views/Components/StudyEnvironmentWidget.axaml.cs @@ -30,6 +30,7 @@ public partial class StudyEnvironmentWidget : UserControl, IDesktopComponentWidg private bool _isAttached; private bool _isOnActivePage = true; private bool _isDisposed; + private bool _studyEnabled = true; private IDisposable? _monitoringLease; public StudyEnvironmentWidget() @@ -132,6 +133,13 @@ public partial class StudyEnvironmentWidget : UserControl, IDesktopComponentWidg private void UpdateMonitoringLeaseState() { + if (!_studyEnabled) + { + _monitoringLease?.Dispose(); + _monitoringLease = null; + return; + } + if (_isAttached) { _monitoringLease ??= _monitoringLeaseCoordinator.AcquireLease(); @@ -147,6 +155,7 @@ public partial class StudyEnvironmentWidget : UserControl, IDesktopComponentWidg var appSnapshot = _appSettingsService.Load(); var componentSnapshot = _componentSettingsService.Load(); _languageCode = _localizationService.NormalizeLanguageCode(appSnapshot.LanguageCode); + _studyEnabled = appSnapshot.StudyEnabled; _showDisplayDb = componentSnapshot.StudyEnvironmentShowDisplayDb; _showDbfs = componentSnapshot.StudyEnvironmentShowDbfs; _componentColorScheme = componentSnapshot.ColorSchemeSource; @@ -158,6 +167,17 @@ public partial class StudyEnvironmentWidget : UserControl, IDesktopComponentWidg private void RefreshVisual() { + if (!_studyEnabled) + { + StatusTitleTextBlock.Text = L("study.widget.disabled_title", "自习功能未启用"); + StatusValueTextBlock.Text = L("study.widget.disabled_hint", "请在设置中开启"); + StatusValueTextBlock.Foreground = TryResolveThemeBrush("AdaptiveTextSecondaryBrush", "#FF9AA0A6"); + NoiseValueTextBlock.Text = "--"; + NoiseSubValueTextBlock.IsVisible = false; + UpdateAdaptiveLayout(); + return; + } + var snapshot = _studyAnalyticsService.GetSnapshot(); var isSessionReport = snapshot.DataMode == StudyDataMode.SessionReport && snapshot.LastSessionReport is not null; diff --git a/LanMountainDesktop/Views/Components/StudyInterruptDensityWidget.axaml.cs b/LanMountainDesktop/Views/Components/StudyInterruptDensityWidget.axaml.cs index 9d01ef1..20fcf62 100644 --- a/LanMountainDesktop/Views/Components/StudyInterruptDensityWidget.axaml.cs +++ b/LanMountainDesktop/Views/Components/StudyInterruptDensityWidget.axaml.cs @@ -53,6 +53,7 @@ public partial class StudyInterruptDensityWidget : UserControl, IDesktopComponen private bool _isOnActivePage = true; private bool _isCompactMode; private bool _isUltraCompactMode; + private bool _studyEnabled = true; private string _languageCode = "zh-CN"; private IDisposable? _monitoringLease; @@ -151,6 +152,13 @@ public partial class StudyInterruptDensityWidget : UserControl, IDesktopComponen private void UpdateMonitoringLeaseState() { + if (!_studyEnabled) + { + _monitoringLease?.Dispose(); + _monitoringLease = null; + return; + } + var shouldMonitor = _isAttached && _isOnActivePage; if (shouldMonitor) { @@ -164,11 +172,21 @@ public partial class StudyInterruptDensityWidget : UserControl, IDesktopComponen private void RefreshVisual() { - var snapshot = _studyAnalyticsService.GetSnapshot(); var panelColor = ResolvePanelBackgroundColor(); ApplyTypographyByBackground(panelColor); ApplyLocalizedLabels(); + if (!_studyEnabled) + { + ModeTextBlock.Text = L("study.widget.disabled_hint", "请在设置中开启"); + ApplyModeBadgeColor(panelColor, Color.Parse("#FF9AA0A6")); + DensityValueTextBlock.Text = "--"; + DensityUnitTextBlock.Text = ""; + return; + } + + var snapshot = _studyAnalyticsService.GetSnapshot(); + var isSessionRunning = snapshot.Session.State == StudySessionRuntimeState.Running; var isSessionReport = snapshot.DataMode == StudyDataMode.SessionReport && snapshot.LastSessionReport is not null; var isSessionView = isSessionRunning || isSessionReport; @@ -528,6 +546,7 @@ public partial class StudyInterruptDensityWidget : UserControl, IDesktopComponen { var snapshot = _settingsService.Load(); _languageCode = _localizationService.NormalizeLanguageCode(snapshot.LanguageCode); + _studyEnabled = snapshot.StudyEnabled; } private void ApplyVariableFontFamily() diff --git a/LanMountainDesktop/Views/Components/StudyNoiseCurveWidget.axaml.cs b/LanMountainDesktop/Views/Components/StudyNoiseCurveWidget.axaml.cs index 8dfe619..fd40738 100644 --- a/LanMountainDesktop/Views/Components/StudyNoiseCurveWidget.axaml.cs +++ b/LanMountainDesktop/Views/Components/StudyNoiseCurveWidget.axaml.cs @@ -70,6 +70,7 @@ public partial class StudyNoiseCurveWidget : UserControl, IDesktopComponentWidge private bool _isOnActivePage = true; private bool _isSubscribed; private bool _isDisposed; + private bool _studyEnabled = true; private int _framesSinceCompaction; private IDisposable? _monitoringLease; @@ -263,6 +264,13 @@ public partial class StudyNoiseCurveWidget : UserControl, IDesktopComponentWidge private void UpdateMonitoringLeaseState() { + if (!_studyEnabled) + { + _monitoringLease?.Dispose(); + _monitoringLease = null; + return; + } + if (_isAttached) { _monitoringLease ??= _monitoringLeaseCoordinator.AcquireLease(); @@ -278,6 +286,15 @@ public partial class StudyNoiseCurveWidget : UserControl, IDesktopComponentWidge var panelColor = ResolvePanelBackgroundColor(); ApplyTypographyByBackground(panelColor); + if (!_studyEnabled) + { + StatusTextBlock.Text = L("study.widget.disabled_title", "自习功能未启用"); + RealtimeValueTextBlock.Text = L("study.widget.disabled_hint", "请在设置中开启"); + ApplyStatusBadgeStyle(StatusVisualKind.Default, panelColor); + ChartControl.UpdateSeries([]); + return; + } + var isSessionReport = snapshot.DataMode == StudyDataMode.SessionReport && snapshot.LastSessionReport is not null; if (isSessionReport && snapshot.LastSessionReport is not null) { @@ -578,6 +595,7 @@ public partial class StudyNoiseCurveWidget : UserControl, IDesktopComponentWidge { var snapshot = _settingsService.Load(); _languageCode = _localizationService.NormalizeLanguageCode(snapshot.LanguageCode); + _studyEnabled = snapshot.StudyEnabled; } private string L(string key, string fallback) diff --git a/LanMountainDesktop/Views/Components/StudyNoiseDistributionWidget.axaml.cs b/LanMountainDesktop/Views/Components/StudyNoiseDistributionWidget.axaml.cs index d35016a..2a63357 100644 --- a/LanMountainDesktop/Views/Components/StudyNoiseDistributionWidget.axaml.cs +++ b/LanMountainDesktop/Views/Components/StudyNoiseDistributionWidget.axaml.cs @@ -56,6 +56,7 @@ public partial class StudyNoiseDistributionWidget : UserControl, IDesktopCompone private bool _isDisposed; private bool _isCompactMode; private bool _isUltraCompactMode; + private bool _studyEnabled = true; private IDisposable? _monitoringLease; private readonly record struct DistributionStats( @@ -157,6 +158,13 @@ public partial class StudyNoiseDistributionWidget : UserControl, IDesktopCompone private void UpdateMonitoringLeaseState() { + if (!_studyEnabled) + { + _monitoringLease?.Dispose(); + _monitoringLease = null; + return; + } + if (_isAttached) { _monitoringLease ??= _monitoringLeaseCoordinator.AcquireLease(); @@ -169,13 +177,23 @@ public partial class StudyNoiseDistributionWidget : UserControl, IDesktopCompone private void RefreshVisual() { - var snapshot = _studyAnalyticsService.GetSnapshot(); var panelColor = ResolvePanelBackgroundColor(); ApplyTypographyByBackground(panelColor); TitleTextBlock.Text = L("study.noise_distribution.title", "Noise Level Distribution"); ApplyLocalizedAxisLabels(); + if (!_studyEnabled) + { + ModeTextBlock.Text = L("study.widget.disabled_hint", "请在设置中开启"); + ApplyModeBadgeColor(panelColor, Color.Parse("#FF9AA0A6")); + ChartControl.UpdateSeries([], 45); + SummaryTextBlock.Text = "--"; + return; + } + + var snapshot = _studyAnalyticsService.GetSnapshot(); + var isSessionRunning = snapshot.Session.State == StudySessionRuntimeState.Running; var isSessionReport = snapshot.DataMode == StudyDataMode.SessionReport && snapshot.LastSessionReport is not null; var isSessionView = isSessionRunning || isSessionReport; @@ -570,6 +588,7 @@ public partial class StudyNoiseDistributionWidget : UserControl, IDesktopCompone { var snapshot = _settingsService.Load(); _languageCode = _localizationService.NormalizeLanguageCode(snapshot.LanguageCode); + _studyEnabled = snapshot.StudyEnabled; } private void ApplyVariableFontFamily() diff --git a/LanMountainDesktop/Views/Components/StudyScoreOverviewWidget.axaml.cs b/LanMountainDesktop/Views/Components/StudyScoreOverviewWidget.axaml.cs index d579724..37dc7b0 100644 --- a/LanMountainDesktop/Views/Components/StudyScoreOverviewWidget.axaml.cs +++ b/LanMountainDesktop/Views/Components/StudyScoreOverviewWidget.axaml.cs @@ -57,6 +57,7 @@ public partial class StudyScoreOverviewWidget : UserControl, IDesktopComponentWi private bool _isCompactMode; private bool _isUltraCompactMode; private bool _isExpandedMode; + private bool _studyEnabled = true; private string _languageCode = "zh-CN"; private IDisposable? _monitoringLease; @@ -140,6 +141,13 @@ public partial class StudyScoreOverviewWidget : UserControl, IDesktopComponentWi private void UpdateMonitoringLeaseState() { + if (!_studyEnabled) + { + _monitoringLease?.Dispose(); + _monitoringLease = null; + return; + } + var shouldMonitor = _isAttached && _isOnActivePage; if (shouldMonitor) { @@ -153,12 +161,22 @@ public partial class StudyScoreOverviewWidget : UserControl, IDesktopComponentWi private void RefreshVisual() { - var snapshot = _studyAnalyticsService.GetSnapshot(); ApplyLocalizedLabels(); var panelColor = ResolvePanelBackgroundColor(); ApplyTypographyByBackground(panelColor); + if (!_studyEnabled) + { + TitleTextBlock.Text = L("study.widget.disabled_title", "自习功能未启用"); + ModeTextBlock.Text = L("study.widget.disabled_hint", "请在设置中开启"); + CurrentScoreTextBlock.Text = "--"; + CurrentLabelTextBlock.Text = ""; + return; + } + + var snapshot = _studyAnalyticsService.GetSnapshot(); + var realtimeScore = ComputeRealtimeScore(snapshot); if (snapshot.DataMode == StudyDataMode.Realtime && realtimeScore is { } score) { @@ -676,6 +694,7 @@ public partial class StudyScoreOverviewWidget : UserControl, IDesktopComponentWi { var snapshot = _settingsService.Load(); _languageCode = _localizationService.NormalizeLanguageCode(snapshot.LanguageCode); + _studyEnabled = snapshot.StudyEnabled; } private void ApplyVariableFontFamily() diff --git a/LanMountainDesktop/Views/Components/StudySessionControlWidget.axaml.cs b/LanMountainDesktop/Views/Components/StudySessionControlWidget.axaml.cs index 613f70e..e826f44 100644 --- a/LanMountainDesktop/Views/Components/StudySessionControlWidget.axaml.cs +++ b/LanMountainDesktop/Views/Components/StudySessionControlWidget.axaml.cs @@ -64,6 +64,7 @@ public partial class StudySessionControlWidget : UserControl, IDesktopComponentW private bool _isDisposed; private bool _isCompactMode; private bool _isUltraCompactMode; + private bool _studyEnabled = true; private IDisposable? _monitoringLease; private string? _transientMessage; private DateTimeOffset _transientMessageExpireAt; @@ -147,6 +148,13 @@ public partial class StudySessionControlWidget : UserControl, IDesktopComponentW private void UpdateMonitoringLeaseState() { + if (!_studyEnabled) + { + _monitoringLease?.Dispose(); + _monitoringLease = null; + return; + } + var shouldMonitor = _isAttached && _isOnActivePage; if (shouldMonitor) { @@ -193,11 +201,21 @@ public partial class StudySessionControlWidget : UserControl, IDesktopComponentW private void RefreshVisual() { - var snapshot = _studyAnalyticsService.GetSnapshot(); var now = DateTimeOffset.UtcNow; var panelColor = ResolvePanelBackgroundColor(); ApplyTypographyByBackground(panelColor); + if (!_studyEnabled) + { + PrimaryTextBlock.Text = L("study.widget.disabled_title", "自习功能未启用"); + SecondaryTextBlock.Text = L("study.widget.disabled_hint", "请在设置中开启"); + ActionIcon.Kind = MaterialIconKind.Settings; + ApplyActionBadgeStyle(panelColor, Color.Parse("#FF9AA0A6")); + return; + } + + var snapshot = _studyAnalyticsService.GetSnapshot(); + if (_transientMessage is not null && now > _transientMessageExpireAt) { _transientMessage = null; @@ -469,6 +487,7 @@ public partial class StudySessionControlWidget : UserControl, IDesktopComponentW { var snapshot = _settingsService.Load(); _languageCode = _localizationService.NormalizeLanguageCode(snapshot.LanguageCode); + _studyEnabled = snapshot.StudyEnabled; } private string L(string key, string fallback) diff --git a/LanMountainDesktop/Views/Components/StudySessionHistoryWidget.axaml.cs b/LanMountainDesktop/Views/Components/StudySessionHistoryWidget.axaml.cs index d93f450..9e0d5eb 100644 --- a/LanMountainDesktop/Views/Components/StudySessionHistoryWidget.axaml.cs +++ b/LanMountainDesktop/Views/Components/StudySessionHistoryWidget.axaml.cs @@ -58,6 +58,7 @@ public partial class StudySessionHistoryWidget : UserControl, IDesktopComponentW private bool _isDisposed; private bool _isCompactMode; private bool _isUltraCompactMode; + private bool _studyEnabled = true; private string? _loadingSessionId; private HistoryDialogMode _dialogMode; private string? _dialogSessionId; @@ -179,6 +180,19 @@ public partial class StudySessionHistoryWidget : UserControl, IDesktopComponentW TitleTextBlock.Text = L("study.session_history.title", "Session History"); TitleTextBlock.Foreground = CreateAdaptiveBrush(panelSamples, PrimaryColorCandidates, MinTextContrast); + if (!_studyEnabled) + { + if (_dialogMode != HistoryDialogMode.None) + { + CloseDialog(); + } + + SessionListPanel.Children.Clear(); + StatusTextBlock.Text = L("study.widget.disabled_hint", "请在设置中开启"); + StatusTextBlock.Foreground = CreateAdaptiveBrush(panelSamples, SecondaryColorCandidates, MinTextContrast); + return; + } + if (_transientStatus is not null && DateTimeOffset.UtcNow > _transientStatusExpireAt) { _transientStatus = null; @@ -581,6 +595,7 @@ public partial class StudySessionHistoryWidget : UserControl, IDesktopComponentW { var snapshot = _settingsService.Load(); _languageCode = _localizationService.NormalizeLanguageCode(snapshot.LanguageCode); + _studyEnabled = snapshot.StudyEnabled; } private void UpdateAdaptiveLayout() diff --git a/LanMountainDesktop/Views/SettingsPages/StudySettingsPage.axaml b/LanMountainDesktop/Views/SettingsPages/StudySettingsPage.axaml index 7a91907..fa367a9 100644 --- a/LanMountainDesktop/Views/SettingsPages/StudySettingsPage.axaml +++ b/LanMountainDesktop/Views/SettingsPages/StudySettingsPage.axaml @@ -8,10 +8,23 @@ + + + + + + + + + + + Description="{Binding NoiseMonitoringDescription}" + IsEnabled="{Binding StudyEnabled}"> @@ -77,7 +90,8 @@ + Description="{Binding FocusTimerDescription}" + IsEnabled="{Binding StudyEnabled}"> @@ -214,7 +228,8 @@ + Description="{Binding AlertDescription}" + IsEnabled="{Binding StudyEnabled}"> @@ -255,7 +270,8 @@ + Description="{Binding DisplayDescription}" + IsEnabled="{Binding StudyEnabled}">