From b4f3ddce4f7a60fdeadd0f03d3a1845d35841742 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 9 Jun 2026 15:32:40 +0200 Subject: [PATCH] Refactor configuration shortcut data --- .../Components/ConfigurationShortcut.razor | 2 +- .../Components/ConfigurationShortcut.razor.cs | 53 ++++--------------- .../Components/ConfigurationShortcutData.cs | 44 +++++++++++++++ .../Settings/SettingsPanelApp.razor | 2 +- .../Settings/SettingsPanelApp.razor.cs | 11 ++++ 5 files changed, 68 insertions(+), 44 deletions(-) create mode 100644 app/MindWork AI Studio/Components/ConfigurationShortcutData.cs diff --git a/app/MindWork AI Studio/Components/ConfigurationShortcut.razor b/app/MindWork AI Studio/Components/ConfigurationShortcut.razor index 41f3b9a3..67929235 100644 --- a/app/MindWork AI Studio/Components/ConfigurationShortcut.razor +++ b/app/MindWork AI Studio/Components/ConfigurationShortcut.razor @@ -3,7 +3,7 @@ - @if (string.IsNullOrWhiteSpace(this.Shortcut())) + @if (string.IsNullOrWhiteSpace(this.Data.Value())) { @T("No shortcut configured") } diff --git a/app/MindWork AI Studio/Components/ConfigurationShortcut.razor.cs b/app/MindWork AI Studio/Components/ConfigurationShortcut.razor.cs index 1d2abe3c..e717787c 100644 --- a/app/MindWork AI Studio/Components/ConfigurationShortcut.razor.cs +++ b/app/MindWork AI Studio/Components/ConfigurationShortcut.razor.cs @@ -1,5 +1,4 @@ using AIStudio.Dialogs; -using AIStudio.Tools.Rust; using AIStudio.Tools.Services; using Microsoft.AspNetCore.Components; @@ -19,40 +18,10 @@ public partial class ConfigurationShortcut : ConfigurationBaseCore private RustService RustService { get; init; } = null!; /// - /// The current shortcut value. + /// The shortcut binding data. /// [Parameter] - public Func Shortcut { get; set; } = () => string.Empty; - - /// - /// An action that is called when the shortcut was changed. - /// - [Parameter] - public Action ShortcutUpdate { get; set; } = _ => { }; - - /// - /// The optional user-facing shortcut label. - /// - [Parameter] - public Func ShortcutDisplayName { get; set; } = () => string.Empty; - - /// - /// The canonical shortcut value the optional user-facing label belongs to. - /// - [Parameter] - public Func ShortcutDisplaySource { get; set; } = () => string.Empty; - - /// - /// An action that is called when the user-facing shortcut label was changed. - /// - [Parameter] - public Action ShortcutDisplayUpdate { get; set; } = (_, _) => { }; - - /// - /// The name/identifier of the shortcut (used for conflict detection and registration). - /// - [Parameter] - public Shortcut ShortcutId { get; init; } + public ConfigurationShortcutData Data { get; set; } = ConfigurationShortcutData.Empty; /// /// The icon to display. @@ -78,12 +47,12 @@ public partial class ConfigurationShortcut : ConfigurationBaseCore private string GetDisplayShortcut() { - var shortcut = this.Shortcut(); + var shortcut = this.Data.Value(); if (string.IsNullOrWhiteSpace(shortcut)) return string.Empty; - var shortcutDisplayName = this.ShortcutDisplayName(); - var shortcutDisplaySource = this.ShortcutDisplaySource(); + var shortcutDisplayName = this.Data.DisplayName(); + var shortcutDisplaySource = this.Data.DisplaySource(); if (!string.IsNullOrWhiteSpace(shortcutDisplayName) && string.Equals(shortcutDisplaySource, shortcut, StringComparison.Ordinal)) { @@ -106,8 +75,8 @@ public partial class ConfigurationShortcut : ConfigurationBaseCore { var dialogParameters = new DialogParameters { - { x => x.InitialShortcut, this.Shortcut() }, - { x => x.ShortcutId, this.ShortcutId }, + { x => x.InitialShortcut, this.Data.Value() }, + { x => x.ShortcutId, this.Data.Id }, }; var dialogReference = await this.DialogService.ShowAsync( @@ -121,15 +90,15 @@ public partial class ConfigurationShortcut : ConfigurationBaseCore if (dialogResult.Data is ShortcutDialogResult shortcutResult) { - this.ShortcutUpdate(shortcutResult.Shortcut); - this.ShortcutDisplayUpdate(shortcutResult.DisplayName, shortcutResult.DisplaySource); + this.Data.ValueUpdate(shortcutResult.Shortcut); + this.Data.DisplayUpdate(shortcutResult.DisplayName, shortcutResult.DisplaySource); await this.SettingsManager.StoreSettings(); await this.InformAboutChange(); } else if (dialogResult.Data is string newShortcut) { - this.ShortcutUpdate(newShortcut); - this.ShortcutDisplayUpdate(string.Empty, string.Empty); + this.Data.ValueUpdate(newShortcut); + this.Data.DisplayUpdate(string.Empty, string.Empty); await this.SettingsManager.StoreSettings(); await this.InformAboutChange(); } diff --git a/app/MindWork AI Studio/Components/ConfigurationShortcutData.cs b/app/MindWork AI Studio/Components/ConfigurationShortcutData.cs new file mode 100644 index 00000000..70541788 --- /dev/null +++ b/app/MindWork AI Studio/Components/ConfigurationShortcutData.cs @@ -0,0 +1,44 @@ +using AIStudio.Tools.Rust; + +namespace AIStudio.Components; + +/// +/// UI binding data for a configurable keyboard shortcut. +/// +public sealed class ConfigurationShortcutData +{ + /// + /// Empty shortcut binding. + /// + public static ConfigurationShortcutData Empty { get; } = new(); + + /// + /// The name/identifier of the shortcut, used for conflict detection and registration. + /// + public Shortcut Id { get; init; } = Shortcut.NONE; + + /// + /// The current shortcut value. + /// + public Func Value { get; init; } = () => string.Empty; + + /// + /// An action that is called when the shortcut was changed. + /// + public Action ValueUpdate { get; init; } = _ => { }; + + /// + /// The optional user-facing shortcut label. + /// + public Func DisplayName { get; init; } = () => string.Empty; + + /// + /// The canonical shortcut value the optional user-facing label belongs to. + /// + public Func DisplaySource { get; init; } = () => string.Empty; + + /// + /// An action that is called when the user-facing shortcut label was changed. + /// + public Action DisplayUpdate { get; init; } = (_, _) => { }; +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor b/app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor index 4fc867ea..7d2b6801 100644 --- a/app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor +++ b/app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor @@ -37,7 +37,7 @@ @if (PreviewFeatures.PRE_SPEECH_TO_TEXT_2026.IsEnabled(this.SettingsManager)) { - + } @if (this.SettingsManager.ConfigurationData.App.ShowAdminSettings) diff --git a/app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor.cs b/app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor.cs index 63350644..04022738 100644 --- a/app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor.cs +++ b/app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor.cs @@ -1,11 +1,22 @@ using AIStudio.Provider; using AIStudio.Settings; using AIStudio.Settings.DataModel; +using AIStudio.Tools.Rust; namespace AIStudio.Components.Settings; public partial class SettingsPanelApp : SettingsPanelBase { + private ConfigurationShortcutData VoiceRecordingShortcut => new() + { + Id = Shortcut.VOICE_RECORDING_TOGGLE, + Value = () => this.SettingsManager.ConfigurationData.App.ShortcutVoiceRecording, + ValueUpdate = shortcut => this.SettingsManager.ConfigurationData.App.ShortcutVoiceRecording = shortcut, + DisplayName = () => this.SettingsManager.ConfigurationData.App.ShortcutVoiceRecordingDisplayName, + DisplaySource = () => this.SettingsManager.ConfigurationData.App.ShortcutVoiceRecordingDisplaySource, + DisplayUpdate = this.UpdateShortcutVoiceRecordingDisplay, + }; + private async Task GenerateEncryptionSecret() { var secret = EnterpriseEncryption.GenerateSecret();