From b44fb5c45a9b365267e5334544127d673996272b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Kaan=20K=C3=B6se?= Date: Wed, 29 Oct 2025 16:26:46 +0100 Subject: [PATCH] Keyboard shortcuts dialog. --- .../Entities/Shared/KeyboardShortcut.cs | 60 +++++ Wino.Core.Domain/Enums/ModifierKeys.cs | 16 ++ Wino.Core.Domain/Enums/WinoPage.cs | 1 + .../Interfaces/IKeyboardShortcutService.cs | 65 ++++++ .../Interfaces/IMailDialogService.cs | 10 + .../Models/KeyboardShortcutDialogResult.cs | 54 +++++ .../Translations/en_US/resources.json | 18 ++ .../Data/KeyboardShortcutViewModel.cs | 86 +++++++ .../Data/MailOperationViewModel.cs | 42 ++++ .../KeyboardShortcutsPageViewModel.cs | 179 ++++++++++++++ .../SettingOptionsPageViewModel.cs | 1 + Wino.Core.WinUI/CoreUWPContainerSetup.cs | 1 + .../Dialogs/KeyboardShortcutDialog.xaml | 80 +++++++ .../Dialogs/KeyboardShortcutDialog.xaml.cs | 145 ++++++++++++ Wino.Mail.WinUI/Package.appxmanifest | 2 +- Wino.Mail.WinUI/Services/DialogService.cs | 15 ++ Wino.Mail.WinUI/Services/NavigationService.cs | 3 +- .../Services/SettingsBuilderService.cs | 1 + .../Abstract/KeyboardShortuctsPageAbstract.cs | 8 + .../Views/Settings/KeyboardShortcutsPage.xaml | 93 ++++++++ .../Settings/KeyboardShortcutsPage.xaml.cs | 11 + Wino.Mail.WinUI/Wino.Mail.WinUI.csproj | 3 +- Wino.Services/DatabaseService.cs | 3 +- Wino.Services/KeyboardShortcutService.cs | 218 ++++++++++++++++++ Wino.Services/ServicesContainerSetup.cs | 1 + 25 files changed, 1112 insertions(+), 4 deletions(-) create mode 100644 Wino.Core.Domain/Entities/Shared/KeyboardShortcut.cs create mode 100644 Wino.Core.Domain/Enums/ModifierKeys.cs create mode 100644 Wino.Core.Domain/Interfaces/IKeyboardShortcutService.cs create mode 100644 Wino.Core.Domain/Models/KeyboardShortcutDialogResult.cs create mode 100644 Wino.Core.ViewModels/Data/KeyboardShortcutViewModel.cs create mode 100644 Wino.Core.ViewModels/Data/MailOperationViewModel.cs create mode 100644 Wino.Core.ViewModels/KeyboardShortcutsPageViewModel.cs create mode 100644 Wino.Mail.WinUI/Dialogs/KeyboardShortcutDialog.xaml create mode 100644 Wino.Mail.WinUI/Dialogs/KeyboardShortcutDialog.xaml.cs create mode 100644 Wino.Mail.WinUI/Views/Abstract/KeyboardShortuctsPageAbstract.cs create mode 100644 Wino.Mail.WinUI/Views/Settings/KeyboardShortcutsPage.xaml create mode 100644 Wino.Mail.WinUI/Views/Settings/KeyboardShortcutsPage.xaml.cs create mode 100644 Wino.Services/KeyboardShortcutService.cs diff --git a/Wino.Core.Domain/Entities/Shared/KeyboardShortcut.cs b/Wino.Core.Domain/Entities/Shared/KeyboardShortcut.cs new file mode 100644 index 00000000..d89c4952 --- /dev/null +++ b/Wino.Core.Domain/Entities/Shared/KeyboardShortcut.cs @@ -0,0 +1,60 @@ +using System; +using SQLite; +using Wino.Core.Domain.Enums; + +namespace Wino.Core.Domain.Entities.Shared; + +/// +/// Represents a user-defined keyboard shortcut for mail operations. +/// +public class KeyboardShortcut +{ + [PrimaryKey] + public Guid Id { get; set; } + + /// + /// The key combination string (e.g., "D", "Delete", "F1"). + /// + public string Key { get; set; } + + /// + /// The modifier keys for this shortcut. + /// + public ModifierKeys ModifierKeys { get; set; } + + /// + /// The mail operation this shortcut triggers. + /// + public MailOperation MailOperation { get; set; } + + /// + /// Whether this shortcut is enabled. + /// + public bool IsEnabled { get; set; } = true; + + /// + /// When this shortcut was created. + /// + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + /// + /// User-friendly display name for the shortcut. + /// + public string DisplayName + { + get + { + var modifierText = string.Empty; + if (ModifierKeys.HasFlag(ModifierKeys.Control)) + modifierText += "Ctrl+"; + if (ModifierKeys.HasFlag(ModifierKeys.Alt)) + modifierText += "Alt+"; + if (ModifierKeys.HasFlag(ModifierKeys.Shift)) + modifierText += "Shift+"; + if (ModifierKeys.HasFlag(ModifierKeys.Windows)) + modifierText += "Win+"; + + return modifierText + Key; + } + } +} \ No newline at end of file diff --git a/Wino.Core.Domain/Enums/ModifierKeys.cs b/Wino.Core.Domain/Enums/ModifierKeys.cs new file mode 100644 index 00000000..f5d7147d --- /dev/null +++ b/Wino.Core.Domain/Enums/ModifierKeys.cs @@ -0,0 +1,16 @@ +using System; + +namespace Wino.Core.Domain.Enums; + +/// +/// Defines keyboard modifier keys that can be used in keyboard shortcuts. +/// +[Flags] +public enum ModifierKeys +{ + None = 0, + Control = 1, + Alt = 2, + Shift = 4, + Windows = 8 +} \ No newline at end of file diff --git a/Wino.Core.Domain/Enums/WinoPage.cs b/Wino.Core.Domain/Enums/WinoPage.cs index 9bf5347a..8df1526d 100644 --- a/Wino.Core.Domain/Enums/WinoPage.cs +++ b/Wino.Core.Domain/Enums/WinoPage.cs @@ -26,6 +26,7 @@ public enum WinoPage SettingOptionsPage, AliasManagementPage, EditAccountDetailsPage, + KeyboardShortcutsPage, // Calendar CalendarPage, CalendarSettingsPage, diff --git a/Wino.Core.Domain/Interfaces/IKeyboardShortcutService.cs b/Wino.Core.Domain/Interfaces/IKeyboardShortcutService.cs new file mode 100644 index 00000000..1e7098ec --- /dev/null +++ b/Wino.Core.Domain/Interfaces/IKeyboardShortcutService.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Wino.Core.Domain.Entities.Shared; +using Wino.Core.Domain.Enums; + +namespace Wino.Core.Domain.Interfaces; + +/// +/// Service for managing keyboard shortcuts for mail operations. +/// +public interface IKeyboardShortcutService +{ + /// + /// Gets all available keyboard shortcuts. + /// + /// Collection of keyboard shortcuts. + Task> GetKeyboardShortcutsAsync(); + + /// + /// Gets enabled keyboard shortcuts only. + /// + /// Collection of enabled keyboard shortcuts. + Task> GetEnabledKeyboardShortcutsAsync(); + + /// + /// Creates or updates a keyboard shortcut. + /// + /// The keyboard shortcut to save. + /// The saved keyboard shortcut. + Task SaveKeyboardShortcutAsync(KeyboardShortcut shortcut); + + /// + /// Deletes a keyboard shortcut. + /// + /// The ID of the shortcut to delete. + Task DeleteKeyboardShortcutAsync(Guid shortcutId); + + /// + /// Gets the mail operation for the given key combination. + /// + /// The pressed key. + /// The modifier keys pressed. + /// The mail operation if found, otherwise null. + Task GetMailOperationForKeyAsync(string key, ModifierKeys modifierKeys); + + /// + /// Checks if a key combination is already assigned to another shortcut. + /// + /// The key to check. + /// The modifier keys to check. + /// Optional ID to exclude from the check (for updates). + /// True if the combination is already used, false otherwise. + Task IsKeyCombinationInUseAsync(string key, ModifierKeys modifierKeys, Guid? excludeShortcutId = null); + + /// + /// Creates default keyboard shortcuts for common mail operations. + /// + Task CreateDefaultShortcutsAsync(); + + /// + /// Resets all shortcuts to defaults. + /// + Task ResetToDefaultShortcutsAsync(); +} \ No newline at end of file diff --git a/Wino.Core.Domain/Interfaces/IMailDialogService.cs b/Wino.Core.Domain/Interfaces/IMailDialogService.cs index 53050931..988c75d5 100644 --- a/Wino.Core.Domain/Interfaces/IMailDialogService.cs +++ b/Wino.Core.Domain/Interfaces/IMailDialogService.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; +using Wino.Core.Domain.Models; using Wino.Core.Domain.Models.Folders; namespace Wino.Core.Domain.Interfaces; @@ -49,4 +50,13 @@ public interface IMailDialogService : IDialogServiceBase /// Presents a dialog to the user to show email source. /// Task ShowMessageSourceDialogAsync(string messageSource); + + /// + /// Presents a dialog to the user for keyboard shortcut creation/modification. + /// + /// Existing shortcut to edit, or null for new shortcut. + /// Dialog result with shortcut information. +#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. + Task ShowKeyboardShortcutDialogAsync(KeyboardShortcut existingShortcut = null); +#pragma warning restore CS8625 } diff --git a/Wino.Core.Domain/Models/KeyboardShortcutDialogResult.cs b/Wino.Core.Domain/Models/KeyboardShortcutDialogResult.cs new file mode 100644 index 00000000..4c4cab97 --- /dev/null +++ b/Wino.Core.Domain/Models/KeyboardShortcutDialogResult.cs @@ -0,0 +1,54 @@ +using Wino.Core.Domain.Enums; + +namespace Wino.Core.Domain.Models; + +/// +/// Result returned from keyboard shortcut dialog. +/// +public class KeyboardShortcutDialogResult +{ + /// + /// Whether the dialog was completed successfully. + /// + public bool IsSuccess { get; set; } + + /// + /// The key combination entered by the user. + /// + public string Key { get; set; } = string.Empty; + + /// + /// The modifier keys selected by the user. + /// + public ModifierKeys ModifierKeys { get; set; } + + /// + /// The mail operation selected by the user. + /// + public MailOperation MailOperation { get; set; } + + /// + /// Creates a successful result. + /// + public static KeyboardShortcutDialogResult Success(string key, ModifierKeys modifierKeys, MailOperation mailOperation) + { + return new KeyboardShortcutDialogResult + { + IsSuccess = true, + Key = key, + ModifierKeys = modifierKeys, + MailOperation = mailOperation + }; + } + + /// + /// Creates a canceled result. + /// + public static KeyboardShortcutDialogResult Canceled() + { + return new KeyboardShortcutDialogResult + { + IsSuccess = false + }; + } +} \ No newline at end of file diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json index b6464abb..07ea2308 100644 --- a/Wino.Core.Domain/Translations/en_US/resources.json +++ b/Wino.Core.Domain/Translations/en_US/resources.json @@ -229,6 +229,22 @@ "HoverActionOption_MoveJunk": "Move to Junk", "HoverActionOption_ToggleFlag": "Flag / Unflag", "HoverActionOption_ToggleRead": "Read / Unread", + "KeyboardShortcuts_FailedToReset": "Failed to reset keyboard shortcuts.", + "KeyboardShortcuts_FailedToUpdate": "Failed to update keyboard shortcuts", + "KeyboardShortcuts_MailoperationAction": "Action", + "KeyboardShortcuts_FailedToLoad": "Failed to load keyboard shortcuts.", + "KeyboardShortcuts_EnterKeyForShortcut": "Please enter a key for the shortcut.", + "KeyboardShortcuts_SelectOperationForShortcut": "Please an action to perform for the shortcut.", + "KeyboardShortcuts_ShortcutInUse": "This shortcut is already in use by another s hortcut.", + "KeyboardShortcuts_FailedToSave": "Failed to save the shortcut.", + "KeyboardShortcuts_FailedToDelete": "Failed to delete the shortcut.", + "KeyboardShortcuts_PageDescription": "Set up keyboard shortcuts for quick mail operations. Press keys while focused on the key input field to capture shortcuts.", + "KeyboardShortcuts_Add": "Add shortcut", + "KeyboardShortcuts_ResetToDefaults": "Reset to Defaults", + "KeyboardShortcuts_PressKeysHere": "Press keys here...", + "KeyboardShortcuts_KeyCombination": "Key Combination", + "KeyboardShortcuts_FocusArea": "Focus the field above and press the desired key combination", + "KeyboardShortcuts_Modifiers": "Modifier Keys", "ImageRenderingDisabled": "Image rendering is disabled for this message.", "ImapAdvancedSetupDialog_AuthenticationMethod": "Authentication method", "ImapAdvancedSetupDialog_ConnectionSecurity": "Connection security", @@ -465,6 +481,8 @@ "SearchBarPlaceholder": "Search", "SearchingIn": "Searching in", "SearchPivotName": "Results", + "Settings_KeyboardShortcuts_Title": "Keyboard Shortcuts", + "Settings_KeyboardShortcuts_Description": "Manage keyboard shortcuts for quick actions on the mails.", "SettingConfigureSpecialFolders_Button": "Configure", "SettingsEditAccountDetails_IMAPConfiguration_Title": "IMAP/SMTP Configuration", "SettingsEditAccountDetails_IMAPConfiguration_Description": "Change your incoming/outgoing server settings.", diff --git a/Wino.Core.ViewModels/Data/KeyboardShortcutViewModel.cs b/Wino.Core.ViewModels/Data/KeyboardShortcutViewModel.cs new file mode 100644 index 00000000..8c7b6e09 --- /dev/null +++ b/Wino.Core.ViewModels/Data/KeyboardShortcutViewModel.cs @@ -0,0 +1,86 @@ +using System; +using CommunityToolkit.Mvvm.ComponentModel; +using Wino.Core.Domain; +using Wino.Core.Domain.Entities.Shared; +using Wino.Core.Domain.Enums; + +namespace Wino.Core.ViewModels.Data; + +/// +/// ViewModel wrapper for KeyboardShortcut entity. +/// +public partial class KeyboardShortcutViewModel : ObservableObject +{ + [ObservableProperty] + private bool isEnabled; + + public Guid Id { get; } + public string Key { get; } + public ModifierKeys ModifierKeys { get; } + public MailOperation MailOperation { get; } + public DateTime CreatedAt { get; } + + public string DisplayName + { + get + { + var modifierText = string.Empty; + if (ModifierKeys.HasFlag(ModifierKeys.Control)) + modifierText += "Ctrl+"; + if (ModifierKeys.HasFlag(ModifierKeys.Alt)) + modifierText += "Alt+"; + if (ModifierKeys.HasFlag(ModifierKeys.Shift)) + modifierText += "Shift+"; + if (ModifierKeys.HasFlag(ModifierKeys.Windows)) + modifierText += "Win+"; + + return modifierText + Key; + } + } + + public string MailOperationDisplayName + { + get + { + return MailOperation switch + { + MailOperation.Archive => "Archive", + MailOperation.UnArchive => "Unarchive", + MailOperation.SoftDelete => "Delete", + MailOperation.Move => "Move", + MailOperation.MoveToJunk => "Move to Junk", + MailOperation.SetFlag => "Set Flag", + MailOperation.ClearFlag => "Clear Flag", + MailOperation.MarkAsRead => "Mark as Read", + MailOperation.MarkAsUnread => "Mark as Unread", + MailOperation.Reply => "Reply", + MailOperation.ReplyAll => "Reply All", + MailOperation.Forward => "Forward", + _ => MailOperation.ToString() + }; + } + } + + public KeyboardShortcutViewModel(KeyboardShortcut shortcut) + { + Id = shortcut.Id; + Key = shortcut.Key; + ModifierKeys = shortcut.ModifierKeys; + MailOperation = shortcut.MailOperation; + CreatedAt = shortcut.CreatedAt; + IsEnabled = shortcut.IsEnabled; + } + + public KeyboardShortcut ToEntity() + { + return new KeyboardShortcut + { + Id = Id, + Key = Key, + ModifierKeys = ModifierKeys, + MailOperation = MailOperation, + CreatedAt = CreatedAt, + IsEnabled = IsEnabled + }; + } +} diff --git a/Wino.Core.ViewModels/Data/MailOperationViewModel.cs b/Wino.Core.ViewModels/Data/MailOperationViewModel.cs new file mode 100644 index 00000000..5b8067bd --- /dev/null +++ b/Wino.Core.ViewModels/Data/MailOperationViewModel.cs @@ -0,0 +1,42 @@ +using Wino.Core.Domain; +using Wino.Core.Domain.Enums; + +namespace Wino.Core.ViewModels.Data; + +/// +/// ViewModel for displaying mail operations in dropdowns/lists. +/// +public class MailOperationViewModel +{ + public MailOperation Operation { get; } + + public string DisplayName + { + get + { + return Operation switch + { + MailOperation.Archive => "Archive", + MailOperation.UnArchive => "Unarchive", + MailOperation.SoftDelete => "Delete", + MailOperation.Move => "Move", + MailOperation.MoveToJunk => "Move to Junk", + MailOperation.SetFlag => "Set Flag", + MailOperation.ClearFlag => "Clear Flag", + MailOperation.MarkAsRead => "Mark as Read", + MailOperation.MarkAsUnread => "Mark as Unread", + MailOperation.Reply => "Reply", + MailOperation.ReplyAll => "Reply All", + MailOperation.Forward => "Forward", + _ => Operation.ToString() + }; + } + } + + public MailOperationViewModel(MailOperation operation) + { + Operation = operation; + } + + public override string ToString() => DisplayName; +} diff --git a/Wino.Core.ViewModels/KeyboardShortcutsPageViewModel.cs b/Wino.Core.ViewModels/KeyboardShortcutsPageViewModel.cs new file mode 100644 index 00000000..0a2b5757 --- /dev/null +++ b/Wino.Core.ViewModels/KeyboardShortcutsPageViewModel.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.ObjectModel; +using System.Threading.Tasks; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Wino.Core.Domain; +using Wino.Core.Domain.Entities.Shared; +using Wino.Core.Domain.Enums; +using Wino.Core.Domain.Interfaces; +using Wino.Core.Domain.Models.Navigation; +using Wino.Core.ViewModels.Data; + +namespace Wino.Core.ViewModels; + +/// +/// ViewModel for managing keyboard shortcuts settings. +/// +public partial class KeyboardShortcutsPageViewModel : CoreBaseViewModel +{ + private readonly IKeyboardShortcutService _keyboardShortcutService; + private readonly IMailDialogService _dialogService; + + [ObservableProperty] + public partial ObservableCollection Shortcuts { get; set; } = new(); + + public KeyboardShortcutsPageViewModel(IKeyboardShortcutService keyboardShortcutService, + IMailDialogService dialogService) + { + _keyboardShortcutService = keyboardShortcutService; + _dialogService = dialogService; + } + + public override async void OnNavigatedTo(NavigationMode mode, object parameters) + { + base.OnNavigatedTo(mode, parameters); + await LoadShortcutsAsync(); + } + + [RelayCommand] + private async Task LoadShortcutsAsync() + { + try + { + var keyboardShortcuts = await _keyboardShortcutService.GetKeyboardShortcutsAsync(); + + Shortcuts.Clear(); + foreach (var shortcut in keyboardShortcuts) + { + Shortcuts.Add(new KeyboardShortcutViewModel(shortcut)); + } + } + catch (Exception ex) + { + await _dialogService.ShowMessageAsync( + Translator.KeyboardShortcuts_FailedToLoad, + Translator.GeneralTitle_Error, + WinoCustomMessageDialogIcon.Error); + } + } + + [RelayCommand] + private async Task StartAddingShortcutAsync() + { + var result = await _dialogService.ShowKeyboardShortcutDialogAsync(); + if (result.IsSuccess) + { + try + { + // Check if key combination is already in use + var isInUse = await _keyboardShortcutService.IsKeyCombinationInUseAsync(result.Key, result.ModifierKeys, null); + if (isInUse) + { + await _dialogService.ShowMessageAsync(Translator.KeyboardShortcuts_ShortcutInUse, Translator.GeneralTitle_Error, WinoCustomMessageDialogIcon.Error); + return; + } + + // Create new shortcut + var shortcut = new KeyboardShortcut + { + Key = result.Key, + ModifierKeys = result.ModifierKeys, + MailOperation = result.MailOperation, + IsEnabled = true + }; + + await _keyboardShortcutService.SaveKeyboardShortcutAsync(shortcut); + await LoadShortcutsAsync(); + } + catch (Exception ex) + { + await _dialogService.ShowMessageAsync( + Translator.KeyboardShortcuts_FailedToSave, + Translator.GeneralTitle_Error, + WinoCustomMessageDialogIcon.Error); + } + } + } + + [RelayCommand] + private async Task StartEditingShortcutAsync(KeyboardShortcutViewModel shortcut) + { + if (shortcut == null) return; + + var dialogService = _dialogService as IMailDialogService; + if (dialogService == null) return; + + var existingShortcut = shortcut.ToEntity(); + var result = await dialogService.ShowKeyboardShortcutDialogAsync(existingShortcut); + + if (result.IsSuccess) + { + try + { + // Check if key combination is already in use (excluding current shortcut) + var isInUse = await _keyboardShortcutService.IsKeyCombinationInUseAsync(result.Key, result.ModifierKeys, shortcut.Id); + if (isInUse) + { + await _dialogService.ShowMessageAsync(Translator.KeyboardShortcuts_ShortcutInUse, Translator.GeneralTitle_Error, WinoCustomMessageDialogIcon.Error); + return; + } + + // Update existing shortcut + var updatedShortcut = shortcut.ToEntity(); + updatedShortcut.Key = result.Key; + updatedShortcut.ModifierKeys = result.ModifierKeys; + updatedShortcut.MailOperation = result.MailOperation; + + await _keyboardShortcutService.SaveKeyboardShortcutAsync(updatedShortcut); + await LoadShortcutsAsync(); + } + catch (Exception ex) + { + await _dialogService.ShowMessageAsync( + Translator.KeyboardShortcuts_FailedToUpdate, + Translator.GeneralTitle_Error, + WinoCustomMessageDialogIcon.Error); + } + } + } + + + + [RelayCommand] + private async Task DeleteShortcutAsync(KeyboardShortcutViewModel shortcut) + { + if (shortcut == null) return; + + try + { + await _keyboardShortcutService.DeleteKeyboardShortcutAsync(shortcut.Id); + await LoadShortcutsAsync(); + } + catch (Exception ex) + { + await _dialogService.ShowMessageAsync( + Translator.KeyboardShortcuts_FailedToDelete, + Translator.GeneralTitle_Error, + WinoCustomMessageDialogIcon.Error); + } + } + + [RelayCommand] + private async Task ResetToDefaultsAsync() + { + try + { + await _keyboardShortcutService.ResetToDefaultShortcutsAsync(); + await LoadShortcutsAsync(); + } + catch (Exception ex) + { + await _dialogService.ShowMessageAsync( + Translator.KeyboardShortcuts_FailedToReset, + Translator.GeneralTitle_Error, + WinoCustomMessageDialogIcon.Error); + } + } + +} diff --git a/Wino.Core.ViewModels/SettingOptionsPageViewModel.cs b/Wino.Core.ViewModels/SettingOptionsPageViewModel.cs index 09411a1e..8745056f 100644 --- a/Wino.Core.ViewModels/SettingOptionsPageViewModel.cs +++ b/Wino.Core.ViewModels/SettingOptionsPageViewModel.cs @@ -38,6 +38,7 @@ public partial class SettingOptionsPageViewModel : CoreBaseViewModel WinoPage.LanguageTimePage => Translator.SettingsLanguageTime_Title, WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title, WinoPage.CalendarSettingsPage => Translator.SettingsCalendarSettings_Title, + WinoPage.KeyboardShortcutsPage => "Keyboard Shortcuts", _ => throw new NotImplementedException() }; diff --git a/Wino.Core.WinUI/CoreUWPContainerSetup.cs b/Wino.Core.WinUI/CoreUWPContainerSetup.cs index 02f4aeac..4e02fbeb 100644 --- a/Wino.Core.WinUI/CoreUWPContainerSetup.cs +++ b/Wino.Core.WinUI/CoreUWPContainerSetup.cs @@ -40,5 +40,6 @@ public static class CoreUWPContainerSetup services.AddTransient(typeof(AboutPageViewModel)); services.AddTransient(typeof(SettingsPageViewModel)); services.AddTransient(typeof(ManageAccountsPagePageViewModel)); + services.AddTransient(typeof(KeyboardShortcutsPageViewModel)); } } diff --git a/Wino.Mail.WinUI/Dialogs/KeyboardShortcutDialog.xaml b/Wino.Mail.WinUI/Dialogs/KeyboardShortcutDialog.xaml new file mode 100644 index 00000000..fefb648f --- /dev/null +++ b/Wino.Mail.WinUI/Dialogs/KeyboardShortcutDialog.xaml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Wino.Mail.WinUI/Dialogs/KeyboardShortcutDialog.xaml.cs b/Wino.Mail.WinUI/Dialogs/KeyboardShortcutDialog.xaml.cs new file mode 100644 index 00000000..1773ea92 --- /dev/null +++ b/Wino.Mail.WinUI/Dialogs/KeyboardShortcutDialog.xaml.cs @@ -0,0 +1,145 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Input; +using Wino.Core.Domain.Entities.Shared; +using Wino.Core.Domain.Enums; +using Wino.Core.Domain.Models; +using Wino.Core.ViewModels.Data; + +namespace Wino.Dialogs; + +public sealed partial class KeyboardShortcutDialog : ContentDialog +{ + public KeyboardShortcutDialogResult Result { get; private set; } = KeyboardShortcutDialogResult.Canceled(); + + public List AvailableMailOperations { get; } + + public MailOperationViewModel SelectedMailOperation { get; set; } + public bool IsControlPressed { get; set; } + public bool IsAltPressed { get; set; } + public bool IsShiftPressed { get; set; } + public bool IsWindowsPressed { get; set; } + + public KeyboardShortcutDialog() + { + InitializeComponent(); + AvailableMailOperations = GetAvailableMailOperations(); + SelectedMailOperation = AvailableMailOperations.FirstOrDefault(); + } + + public KeyboardShortcutDialog(KeyboardShortcut existingShortcut) : this() + { + if (existingShortcut != null) + { + KeyInputTextBox.Text = existingShortcut.Key; + SelectedMailOperation = AvailableMailOperations.FirstOrDefault(x => x.Operation == existingShortcut.MailOperation); + + var modifiers = existingShortcut.ModifierKeys; + IsControlPressed = modifiers.HasFlag(ModifierKeys.Control); + IsAltPressed = modifiers.HasFlag(ModifierKeys.Alt); + IsShiftPressed = modifiers.HasFlag(ModifierKeys.Shift); + IsWindowsPressed = modifiers.HasFlag(ModifierKeys.Windows); + + Title = "Edit Keyboard Shortcut"; + } + } + + private void SaveClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + // Clear any previous error + ErrorTextBlock.Visibility = Microsoft.UI.Xaml.Visibility.Collapsed; + + // Validate input + if (string.IsNullOrWhiteSpace(KeyInputTextBox.Text)) + { + ShowError("Please enter a key for the shortcut."); + args.Cancel = true; + return; + } + + if (SelectedMailOperation == null || SelectedMailOperation.Operation == MailOperation.None) + { + ShowError("Please select a mail operation for the shortcut."); + args.Cancel = true; + return; + } + + // Get modifier keys + var modifierKeys = GetSelectedModifierKeys(); + + // Create successful result + Result = KeyboardShortcutDialogResult.Success(KeyInputTextBox.Text, modifierKeys, SelectedMailOperation.Operation); + } + + private void KeyInputTextBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e) + { + // Clear error when user starts typing + ErrorTextBlock.Visibility = Microsoft.UI.Xaml.Visibility.Collapsed; + + var key = e.Key.ToString(); + + // Update modifier states based on current key press + IsControlPressed = Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Control).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Down); + IsAltPressed = Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Menu).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Down); + IsShiftPressed = Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Shift).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Down); + IsWindowsPressed = Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.LeftWindows).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Down) || + Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.RightWindows).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Down); + + // Set the key (ignore modifier keys themselves) + if (key != "Control" && key != "Menu" && key != "Shift" && key != "LeftWindows" && key != "RightWindows") + { + KeyInputTextBox.Text = key; + } + + // Prevent the key from being processed further + // e.Handled = true; + } + + private ModifierKeys GetSelectedModifierKeys() + { + var modifiers = ModifierKeys.None; + + if (IsControlPressed) modifiers |= ModifierKeys.Control; + if (IsAltPressed) modifiers |= ModifierKeys.Alt; + if (IsShiftPressed) modifiers |= ModifierKeys.Shift; + if (IsWindowsPressed) modifiers |= ModifierKeys.Windows; + + return modifiers; + } + + private void ShowError(string message) + { + ErrorTextBlock.Text = message; + ErrorTextBlock.Visibility = Microsoft.UI.Xaml.Visibility.Visible; + } + + private static List GetAvailableMailOperations() + { + var operations = new List(); + + // Add commonly used mail operations that make sense for keyboard shortcuts + var validOperations = new[] + { + MailOperation.Archive, + MailOperation.UnArchive, + MailOperation.SoftDelete, + MailOperation.Move, + MailOperation.MoveToJunk, + MailOperation.SetFlag, + MailOperation.ClearFlag, + MailOperation.MarkAsRead, + MailOperation.MarkAsUnread, + MailOperation.Reply, + MailOperation.ReplyAll, + MailOperation.Forward + }; + + foreach (var operation in validOperations) + { + operations.Add(new MailOperationViewModel(operation)); + } + + return operations.OrderBy(x => x.DisplayName).ToList(); + } +} diff --git a/Wino.Mail.WinUI/Package.appxmanifest b/Wino.Mail.WinUI/Package.appxmanifest index 6df5b884..9c49b925 100644 --- a/Wino.Mail.WinUI/Package.appxmanifest +++ b/Wino.Mail.WinUI/Package.appxmanifest @@ -20,7 +20,7 @@ + Version="0.0.4.0" /> diff --git a/Wino.Mail.WinUI/Services/DialogService.cs b/Wino.Mail.WinUI/Services/DialogService.cs index fb4d43d8..63a22ad9 100644 --- a/Wino.Mail.WinUI/Services/DialogService.cs +++ b/Wino.Mail.WinUI/Services/DialogService.cs @@ -10,6 +10,7 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; +using Wino.Core.Domain.Models; using Wino.Core.Domain.Models.Accounts; using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.Synchronization; @@ -194,4 +195,18 @@ public class DialogService : DialogServiceBase, IMailDialogService await HandleDialogPresentationAsync(accountReorderDialog); } + +#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. + public async Task ShowKeyboardShortcutDialogAsync(KeyboardShortcut existingShortcut = null) +#pragma warning restore CS8625 + { + var dialog = new KeyboardShortcutDialog(existingShortcut) + { + RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme() + }; + + await HandleDialogPresentationAsync(dialog); + + return dialog.Result; + } } diff --git a/Wino.Mail.WinUI/Services/NavigationService.cs b/Wino.Mail.WinUI/Services/NavigationService.cs index 90498938..18e839d2 100644 --- a/Wino.Mail.WinUI/Services/NavigationService.cs +++ b/Wino.Mail.WinUI/Services/NavigationService.cs @@ -7,8 +7,8 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Navigation; using Wino.Core.WinUI; -using Wino.Core.WinUI.Services; using Wino.Core.WinUI.Interfaces; +using Wino.Core.WinUI.Services; using Wino.Helpers; using Wino.Mail.ViewModels.Data; using Wino.Mail.ViewModels.Messages; @@ -59,6 +59,7 @@ public class NavigationService : NavigationServiceBase, INavigationService WinoPage.AliasManagementPage => typeof(AliasManagementPage), WinoPage.LanguageTimePage => typeof(LanguageTimePage), WinoPage.EditAccountDetailsPage => typeof(EditAccountDetailsPage), + WinoPage.KeyboardShortcutsPage => typeof(KeyboardShortcutsPage), _ => null, }; } diff --git a/Wino.Mail.WinUI/Services/SettingsBuilderService.cs b/Wino.Mail.WinUI/Services/SettingsBuilderService.cs index 8c2718b5..a289e2a6 100644 --- a/Wino.Mail.WinUI/Services/SettingsBuilderService.cs +++ b/Wino.Mail.WinUI/Services/SettingsBuilderService.cs @@ -15,6 +15,7 @@ public class SettingsBuilderService : ISettingsBuilderService new SettingOption(Translator.SettingsAppPreferences_Title, Translator.SettingsAppPreferences_Description, WinoPage.AppPreferencesPage,"F1 M 15.078125 1.25 C 15.566406 1.25 16.033527 1.349285 16.479492 1.547852 C 16.925455 1.74642 17.31608 2.013348 17.651367 2.348633 C 17.986652 2.68392 18.25358 3.074545 18.452148 3.520508 C 18.650715 3.966473 18.75 4.433594 18.75 4.921875 L 18.75 15.078125 C 18.75 15.566406 18.650715 16.033529 18.452148 16.479492 C 18.25358 16.925455 17.986652 17.31608 17.651367 17.651367 C 17.31608 17.986654 16.925455 18.25358 16.479492 18.452148 C 16.033527 18.650717 15.566406 18.75 15.078125 18.75 L 4.921875 18.75 C 4.433594 18.75 3.966471 18.650717 3.520508 18.452148 C 3.074544 18.25358 2.683919 17.986654 2.348633 17.651367 C 2.013346 17.31608 1.746419 16.925455 1.547852 16.479492 C 1.349284 16.033529 1.25 15.566406 1.25 15.078125 L 1.25 4.921875 C 1.25 4.433594 1.349284 3.966473 1.547852 3.520508 C 1.746419 3.074545 2.013346 2.68392 2.348633 2.348633 C 2.683919 2.013348 3.074544 1.74642 3.520508 1.547852 C 3.966471 1.349285 4.433594 1.25 4.921875 1.25 Z M 4.951172 2.5 C 4.625651 2.5 4.314778 2.566732 4.018555 2.700195 C 3.722331 2.83366 3.461914 3.012695 3.237305 3.237305 C 3.012695 3.461914 2.833659 3.722332 2.700195 4.018555 C 2.566732 4.314779 2.5 4.625651 2.5 4.951172 L 2.5 5 L 17.5 5 L 17.5 4.951172 C 17.5 4.625651 17.433268 4.314779 17.299805 4.018555 C 17.16634 3.722332 16.987305 3.461914 16.762695 3.237305 C 16.538086 3.012695 16.277668 2.83366 15.981445 2.700195 C 15.685221 2.566732 15.374349 2.5 15.048828 2.5 Z M 15.048828 17.5 C 15.374349 17.5 15.685221 17.433268 15.981445 17.299805 C 16.277668 17.166342 16.538086 16.987305 16.762695 16.762695 C 16.987305 16.538086 17.16634 16.27767 17.299805 15.981445 C 17.433268 15.685222 17.5 15.37435 17.5 15.048828 L 17.5 6.25 L 2.5 6.25 L 2.5 15.048828 C 2.5 15.37435 2.566732 15.685222 2.700195 15.981445 C 2.833659 16.27767 3.012695 16.538086 3.237305 16.762695 C 3.461914 16.987305 3.722331 17.166342 4.018555 17.299805 C 4.314778 17.433268 4.625651 17.5 4.951172 17.5 Z M 12.724609 8.935547 C 12.724609 9.195964 12.762044 9.446615 12.836914 9.6875 C 12.911783 9.928386 13.020832 10.151367 13.164062 10.356445 C 13.307291 10.561523 13.476562 10.742188 13.671875 10.898438 C 13.867188 11.054688 14.088541 11.178386 14.335938 11.269531 C 14.348957 11.367188 14.358723 11.466472 14.365234 11.567383 C 14.371744 11.668295 14.375 11.770834 14.375 11.875 C 14.375 11.979167 14.371744 12.081706 14.365234 12.182617 C 14.358723 12.283529 14.348957 12.382812 14.335938 12.480469 C 14.088541 12.571615 13.867188 12.695312 13.671875 12.851562 C 13.476562 13.007812 13.307291 13.188477 13.164062 13.393555 C 13.020832 13.598633 12.911783 13.821615 12.836914 14.0625 C 12.762044 14.303386 12.724609 14.554037 12.724609 14.814453 C 12.724609 14.886068 12.727864 14.960938 12.734375 15.039062 C 12.740885 15.117188 12.75065 15.192058 12.763672 15.263672 C 12.470703 15.511068 12.145182 15.712891 11.787109 15.869141 C 11.546224 15.621745 11.274414 15.43457 10.97168 15.307617 C 10.668945 15.180664 10.345052 15.117188 10 15.117188 C 9.654947 15.117188 9.331055 15.180664 9.02832 15.307617 C 8.725586 15.43457 8.453775 15.621745 8.212891 15.869141 C 7.854817 15.712891 7.529296 15.511068 7.236328 15.263672 C 7.249349 15.192058 7.259114 15.117188 7.265625 15.039062 C 7.272135 14.960938 7.275391 14.886068 7.275391 14.814453 C 7.275391 14.554037 7.237956 14.303386 7.163086 14.0625 C 7.088216 13.821615 6.979167 13.598633 6.835938 13.393555 C 6.692708 13.188477 6.52181 13.007812 6.323242 12.851562 C 6.124674 12.695312 5.904948 12.571615 5.664062 12.480469 C 5.651042 12.382812 5.641276 12.283529 5.634766 12.182617 C 5.628255 12.081706 5.625 11.979167 5.625 11.875 C 5.625 11.770834 5.628255 11.668295 5.634766 11.567383 C 5.641276 11.466472 5.651042 11.367188 5.664062 11.269531 C 5.904948 11.178386 6.124674 11.054688 6.323242 10.898438 C 6.52181 10.742188 6.692708 10.561523 6.835938 10.356445 C 6.979167 10.151367 7.088216 9.928386 7.163086 9.6875 C 7.237956 9.446615 7.275391 9.195964 7.275391 8.935547 C 7.275391 8.863933 7.272135 8.789062 7.265625 8.710938 C 7.259114 8.632812 7.249349 8.557943 7.236328 8.486328 C 7.529296 8.238933 7.854817 8.037109 8.212891 7.880859 C 8.440755 8.121745 8.712564 8.307292 9.02832 8.4375 C 9.344075 8.567709 9.667969 8.632812 10 8.632812 C 10.332031 8.632812 10.655924 8.567709 10.97168 8.4375 C 11.287435 8.307292 11.559244 8.121745 11.787109 7.880859 C 12.145182 8.037109 12.470703 8.238933 12.763672 8.486328 C 12.75065 8.557943 12.740885 8.632812 12.734375 8.710938 C 12.727864 8.789062 12.724609 8.863933 12.724609 8.935547 Z M 10.9375 11.875 C 10.9375 11.614584 10.846354 11.393229 10.664062 11.210938 C 10.481771 11.028646 10.260416 10.9375 10 10.9375 C 9.739583 10.9375 9.518229 11.028646 9.335938 11.210938 C 9.153646 11.393229 9.0625 11.614584 9.0625 11.875 C 9.0625 12.135417 9.153646 12.356771 9.335938 12.539062 C 9.518229 12.721354 9.739583 12.8125 10 12.8125 C 10.260416 12.8125 10.481771 12.721354 10.664062 12.539062 C 10.846354 12.356771 10.9375 12.135417 10.9375 11.875 Z "), new SettingOption(Translator.SettingsLanguageTime_Title, Translator.SettingsLanguageTime_Description, WinoPage.LanguageTimePage,"F1 M 4.765625 12.324219 C 4.088542 12.167969 3.458659 11.899414 2.875977 11.518555 C 2.293294 11.137695 1.788737 10.680339 1.362305 10.146484 C 0.935872 9.612631 0.602214 9.020183 0.361328 8.369141 C 0.120443 7.7181 0 7.044271 0 6.347656 C 0 5.468751 0.159505 4.645184 0.478516 3.876953 C 0.797526 3.108725 1.236979 2.436523 1.796875 1.860352 C 2.356771 1.28418 3.017578 0.830078 3.779297 0.498047 C 4.541016 0.166016 5.364583 0 6.25 0 C 7.115885 0 7.92806 0.162762 8.686523 0.488281 C 9.444986 0.813803 10.107422 1.259766 10.673828 1.826172 C 11.240234 2.392578 11.686197 3.055014 12.011719 3.813477 C 12.337239 4.57194 12.5 5.384115 12.5 6.25 L 11.25 6.25 L 11.25 6.152344 C 11.25 5.475261 11.114908 4.838867 10.844727 4.243164 C 10.574544 3.647461 10.209961 3.128256 9.750977 2.685547 C 9.291992 2.24284 8.761393 1.892904 8.15918 1.635742 C 7.556966 1.378582 6.920573 1.25 6.25 1.25 C 5.579427 1.25 4.943034 1.378582 4.34082 1.635742 C 3.738607 1.892904 3.208008 2.24284 2.749023 2.685547 C 2.290039 3.128256 1.925456 3.647461 1.655273 4.243164 C 1.385091 4.838867 1.25 5.475261 1.25 6.152344 L 1.25 6.328125 C 1.25 6.901042 1.352539 7.454428 1.557617 7.988281 C 1.762695 8.522136 2.045898 9.005534 2.407227 9.438477 C 2.768555 9.87142 3.191732 10.239258 3.676758 10.541992 C 4.161784 10.844727 4.6875 11.048178 5.253906 11.152344 Z M 5.625 7.5 C 5.455729 7.5 5.309245 7.438151 5.185547 7.314453 C 5.061849 7.190756 5 7.044271 5 6.875 L 5 3.125 C 5 2.95573 5.061849 2.809246 5.185547 2.685547 C 5.309245 2.56185 5.455729 2.5 5.625 2.5 C 5.794271 2.5 5.940755 2.56185 6.064453 2.685547 C 6.188151 2.809246 6.25 2.95573 6.25 3.125 L 6.25 6.25 L 8.125 6.25 C 8.294271 6.25 8.440755 6.31185 8.564453 6.435547 C 8.68815 6.559245 8.75 6.705729 8.75 6.875 C 8.75 7.044271 8.68815 7.190756 8.564453 7.314453 C 8.440755 7.438151 8.294271 7.5 8.125 7.5 Z M 10 10 L 10 8.125 C 10 7.95573 10.061849 7.809246 10.185547 7.685547 C 10.309244 7.56185 10.455729 7.5 10.625 7.5 L 14.375 7.5 C 14.375 7.447917 14.373372 7.394206 14.370117 7.338867 C 14.366861 7.283529 14.365234 7.226563 14.365234 7.167969 C 14.365234 7.057292 14.371744 6.948242 14.384766 6.84082 C 14.397786 6.733398 14.425455 6.635742 14.467773 6.547852 C 14.51009 6.459961 14.573566 6.388347 14.658203 6.333008 C 14.742838 6.27767 14.856771 6.25 15 6.25 C 15.143229 6.25 15.255533 6.27767 15.336914 6.333008 C 15.418294 6.388347 15.480143 6.459961 15.522461 6.547852 C 15.564777 6.635742 15.592447 6.733398 15.605469 6.84082 C 15.618489 6.948242 15.625 7.057292 15.625 7.167969 L 15.625 7.5 L 19.375 7.5 C 19.54427 7.5 19.690754 7.56185 19.814453 7.685547 C 19.93815 7.809246 20 7.95573 20 8.125 L 20 10 C 20 10.169271 19.93815 10.315756 19.814453 10.439453 C 19.690754 10.563151 19.54427 10.625 19.375 10.625 C 19.205729 10.625 19.059244 10.563151 18.935547 10.439453 C 18.811848 10.315756 18.75 10.169271 18.75 10 L 18.75 8.75 L 11.25 8.75 L 11.25 10 C 11.25 10.169271 11.18815 10.315756 11.064453 10.439453 C 10.940755 10.563151 10.794271 10.625 10.625 10.625 C 10.455729 10.625 10.309244 10.563151 10.185547 10.439453 C 10.061849 10.315756 10 10.169271 10 10 Z M 14.375 17.5 C 14.205729 17.5 14.059244 17.43815 13.935547 17.314453 C 13.811849 17.190756 13.75 17.044271 13.75 16.875 C 13.75 16.731771 13.777669 16.619467 13.833008 16.538086 C 13.888346 16.456705 13.95996 16.394857 14.047852 16.352539 C 14.135741 16.310221 14.233397 16.282553 14.34082 16.269531 C 14.448241 16.256512 14.557291 16.25 14.667969 16.25 L 15 16.25 L 15 13.75 L 11.875 13.75 C 11.705729 13.75 11.559244 13.688151 11.435547 13.564453 C 11.311849 13.440756 11.25 13.294271 11.25 13.125 C 11.25 12.955729 11.311849 12.809245 11.435547 12.685547 C 11.559244 12.56185 11.705729 12.5 11.875 12.5 L 15 12.5 C 14.999999 12.376303 15.035807 12.259115 15.107422 12.148438 L 15.703125 11.25 L 13.125 11.25 C 12.955729 11.25 12.809244 11.188151 12.685547 11.064453 C 12.561849 10.940756 12.5 10.794271 12.5 10.625 C 12.5 10.455729 12.561849 10.309245 12.685547 10.185547 C 12.809244 10.06185 12.955729 10 13.125 10 L 16.875 10 C 17.04427 10 17.190754 10.06185 17.314453 10.185547 C 17.43815 10.309245 17.5 10.455729 17.5 10.625 C 17.5 10.748698 17.464191 10.862631 17.392578 10.966797 L 16.376953 12.5 L 19.375 12.5 C 19.54427 12.5 19.690754 12.56185 19.814453 12.685547 C 19.93815 12.809245 20 12.955729 20 13.125 C 20 13.294271 19.93815 13.440756 19.814453 13.564453 C 19.690754 13.688151 19.54427 13.75 19.375 13.75 L 16.25 13.75 L 16.25 16.25 C 16.25 16.425781 16.217447 16.588543 16.152344 16.738281 C 16.087238 16.888021 15.997721 17.019857 15.883789 17.133789 C 15.769856 17.247721 15.638021 17.33724 15.488281 17.402344 C 15.338541 17.467447 15.17578 17.5 15 17.5 Z M 4.0625 18.125 C 4.0625 18.046875 4.075521 17.972006 4.101562 17.900391 C 4.257812 17.477213 4.41569 17.05892 4.575195 16.645508 C 4.7347 16.232096 4.892578 15.813803 5.048828 15.390625 L 6.914062 10.400391 C 6.959635 10.276693 7.036133 10.185547 7.143555 10.126953 C 7.250977 10.068359 7.369792 10.039062 7.5 10.039062 C 7.630208 10.039062 7.749023 10.068359 7.856445 10.126953 C 7.963867 10.185547 8.040364 10.276693 8.085938 10.400391 L 9.951172 15.390625 C 10.107422 15.813803 10.265299 16.232096 10.424805 16.645508 C 10.58431 17.05892 10.742188 17.477213 10.898438 17.900391 C 10.924479 17.972006 10.9375 18.046875 10.9375 18.125 C 10.9375 18.300781 10.877278 18.448893 10.756836 18.569336 C 10.636393 18.689779 10.488281 18.75 10.3125 18.75 C 10.175781 18.75 10.056966 18.714193 9.956055 18.642578 C 9.855143 18.570963 9.778646 18.470053 9.726562 18.339844 L 8.945312 16.25 L 6.054688 16.25 L 5.273438 18.339844 C 5.227864 18.463541 5.151367 18.562826 5.043945 18.637695 C 4.936523 18.712564 4.817708 18.75 4.6875 18.75 C 4.511719 18.75 4.363606 18.689779 4.243164 18.569336 C 4.122721 18.448893 4.0625 18.300781 4.0625 18.125 Z M 7.5 12.402344 L 6.523438 15 L 8.476562 15 Z "), new SettingOption(Translator.SettingsPersonalization_Title, Translator.SettingsPersonalization_Description, WinoPage.PersonalizationPage,"F1 M 10 17.5 L 10 18.75 L 12.5 18.75 L 12.5 20 L 6.25 20 L 6.25 18.75 L 8.75 18.75 L 8.75 17.5 L 0 17.5 L 0 6.25 L 10 6.25 L 8.740234 7.5 L 1.25 7.5 L 1.25 16.25 L 17.5 16.25 L 17.5 8.75 L 18.75 7.5 L 18.75 17.5 Z M 5 13.75 C 5.175781 13.75 5.338542 13.717448 5.488281 13.652344 C 5.638021 13.58724 5.769856 13.497722 5.883789 13.383789 C 5.997721 13.269857 6.087239 13.138021 6.152344 12.988281 C 6.217448 12.838542 6.25 12.675781 6.25 12.5 C 6.25 12.18099 6.306966 11.878256 6.420898 11.591797 C 6.53483 11.305339 6.69108 11.051433 6.889648 10.830078 C 7.088216 10.608725 7.322591 10.424805 7.592773 10.27832 C 7.862955 10.131836 8.157552 10.042318 8.476562 10.009766 L 15.419922 3.066406 C 15.602213 2.884115 15.813802 2.744141 16.054688 2.646484 C 16.295572 2.548828 16.542969 2.5 16.796875 2.5 C 17.063801 2.5 17.31608 2.550457 17.553711 2.651367 C 17.79134 2.752279 17.998047 2.890625 18.173828 3.066406 C 18.349609 3.242188 18.487955 3.448895 18.588867 3.686523 C 18.689777 3.924154 18.740234 4.179688 18.740234 4.453125 C 18.740234 4.707031 18.691406 4.954428 18.59375 5.195312 C 18.496094 5.436199 18.356119 5.647787 18.173828 5.830078 L 11.230469 12.773438 C 11.197916 13.085938 11.110025 13.378906 10.966797 13.652344 C 10.823567 13.925781 10.639648 14.161784 10.415039 14.360352 C 10.19043 14.55892 9.936523 14.71517 9.65332 14.829102 C 9.370117 14.943034 9.06901 15 8.75 15 L 2.5 15 L 2.5 13.75 Z M 16.796875 3.75 C 16.608072 3.75 16.445312 3.818359 16.308594 3.955078 L 11.962891 8.300781 C 12.333984 8.58724 12.66276 8.916016 12.949219 9.287109 L 17.294922 4.941406 C 17.431641 4.804688 17.5 4.641928 17.5 4.453125 C 17.5 4.257812 17.430012 4.091797 17.290039 3.955078 C 17.150064 3.818359 16.985676 3.75 16.796875 3.75 Z M 10.175781 10.087891 C 10.572916 10.348308 10.901692 10.677084 11.162109 11.074219 L 12.060547 10.185547 C 11.787109 9.794922 11.455078 9.462891 11.064453 9.189453 Z M 10 12.5 C 10 12.324219 9.967447 12.161459 9.902344 12.011719 C 9.837239 11.861979 9.747721 11.730144 9.633789 11.616211 C 9.519856 11.502279 9.388021 11.412761 9.238281 11.347656 C 9.088541 11.282553 8.925781 11.25 8.75 11.25 C 8.574219 11.25 8.411458 11.282553 8.261719 11.347656 C 8.111979 11.412761 7.980143 11.502279 7.866211 11.616211 C 7.752278 11.730144 7.66276 11.861979 7.597656 12.011719 C 7.532552 12.161459 7.5 12.324219 7.5 12.5 C 7.5 12.942709 7.389322 13.359375 7.167969 13.75 L 8.75 13.75 C 8.919271 13.75 9.080403 13.717448 9.233398 13.652344 C 9.386393 13.58724 9.519856 13.497722 9.633789 13.383789 C 9.747721 13.269857 9.837239 13.136394 9.902344 12.983398 C 9.967447 12.830404 10 12.669271 10 12.5 Z "), + new SettingOption(Translator.Settings_KeyboardShortcuts_Title, Translator.Settings_KeyboardShortcuts_Description, WinoPage.KeyboardShortcutsPage,"F1 M 2.451172 16.25 C 2.125651 16.25 1.814779 16.18327 1.518555 16.049805 C 1.222331 15.916342 0.961914 15.737305 0.737305 15.512695 C 0.512695 15.288086 0.333659 15.02767 0.200195 14.731445 C 0.066732 14.435222 0 14.12435 0 13.798828 L 0 4.951172 C 0 4.625651 0.066732 4.314779 0.200195 4.018555 C 0.333659 3.722332 0.512695 3.461914 0.737305 3.237305 C 0.961914 3.012695 1.222331 2.83366 1.518555 2.700195 C 1.814779 2.566732 2.125651 2.5 2.451172 2.5 L 17.548828 2.5 C 17.874348 2.5 18.185221 2.566732 18.481445 2.700195 C 18.777668 2.83366 19.038086 3.012695 19.262695 3.237305 C 19.487305 3.461914 19.66634 3.722332 19.799805 4.018555 C 19.933268 4.314779 20 4.625651 20 4.951172 L 20 13.798828 C 20 14.12435 19.933268 14.435222 19.799805 14.731445 C 19.66634 15.02767 19.487305 15.288086 19.262695 15.512695 C 19.038086 15.737305 18.777668 15.916342 18.481445 16.049805 C 18.185221 16.18327 17.874348 16.25 17.548828 16.25 Z M 17.5 15 C 17.675781 15 17.838541 14.967448 17.988281 14.902344 C 18.13802 14.83724 18.269855 14.747722 18.383789 14.633789 C 18.497721 14.519857 18.587238 14.388021 18.652344 14.238281 C 18.717447 14.088542 18.75 13.925781 18.75 13.75 L 18.75 5 C 18.75 4.830729 18.717447 4.669597 18.652344 4.516602 C 18.587238 4.363607 18.497721 4.230144 18.383789 4.116211 C 18.269855 4.002279 18.136393 3.912762 17.983398 3.847656 C 17.830402 3.782553 17.66927 3.75 17.5 3.75 L 2.5 3.75 C 2.324219 3.75 2.161458 3.782553 2.011719 3.847656 C 1.861979 3.912762 1.730143 4.002279 1.616211 4.116211 C 1.502279 4.230144 1.41276 4.361979 1.347656 4.511719 C 1.282552 4.661459 1.25 4.82422 1.25 5 L 1.25 13.75 C 1.25 13.925781 1.282552 14.09017 1.347656 14.243164 C 1.41276 14.396159 1.500651 14.527995 1.611328 14.638672 C 1.722005 14.74935 1.853841 14.83724 2.006836 14.902344 C 2.159831 14.967448 2.324219 15 2.5 15 Z M 3.125 6.5625 C 3.125 6.302084 3.216146 6.08073 3.398438 5.898438 C 3.580729 5.716146 3.802083 5.625 4.0625 5.625 C 4.322917 5.625 4.544271 5.716146 4.726562 5.898438 C 4.908854 6.08073 5 6.302084 5 6.5625 C 5 6.822917 4.908854 7.044271 4.726562 7.226562 C 4.544271 7.408854 4.322917 7.5 4.0625 7.5 C 3.802083 7.5 3.580729 7.408854 3.398438 7.226562 C 3.216146 7.044271 3.125 6.822917 3.125 6.5625 Z M 6.875 6.5625 C 6.875 6.302084 6.966146 6.08073 7.148438 5.898438 C 7.330729 5.716146 7.552083 5.625 7.8125 5.625 C 8.072916 5.625 8.294271 5.716146 8.476562 5.898438 C 8.658854 6.08073 8.75 6.302084 8.75 6.5625 C 8.75 6.822917 8.658854 7.044271 8.476562 7.226562 C 8.294271 7.408854 8.072916 7.5 7.8125 7.5 C 7.552083 7.5 7.330729 7.408854 7.148438 7.226562 C 6.966146 7.044271 6.875 6.822917 6.875 6.5625 Z M 10.625 6.5625 C 10.625 6.302084 10.716146 6.08073 10.898438 5.898438 C 11.080729 5.716146 11.302083 5.625 11.5625 5.625 C 11.822916 5.625 12.044271 5.716146 12.226562 5.898438 C 12.408854 6.08073 12.5 6.302084 12.5 6.5625 C 12.5 6.822917 12.408854 7.044271 12.226562 7.226562 C 12.044271 7.408854 11.822916 7.5 11.5625 7.5 C 11.302083 7.5 11.080729 7.408854 10.898438 7.226562 C 10.716146 7.044271 10.625 6.822917 10.625 6.5625 Z M 14.375 6.5625 C 14.375 6.302084 14.466146 6.08073 14.648438 5.898438 C 14.830729 5.716146 15.052083 5.625 15.3125 5.625 C 15.572916 5.625 15.79427 5.716146 15.976562 5.898438 C 16.158854 6.08073 16.25 6.302084 16.25 6.5625 C 16.25 6.822917 16.158854 7.044271 15.976562 7.226562 C 15.79427 7.408854 15.572916 7.5 15.3125 7.5 C 15.052083 7.5 14.830729 7.408854 14.648438 7.226562 C 14.466146 7.044271 14.375 6.822917 14.375 6.5625 Z M 5.625 10.3125 C 5.625 10.052084 5.716146 9.830729 5.898438 9.648438 C 6.080729 9.466146 6.302083 9.375 6.5625 9.375 C 6.822917 9.375 7.044271 9.466146 7.226562 9.648438 C 7.408854 9.830729 7.5 10.052084 7.5 10.3125 C 7.5 10.572917 7.408854 10.794271 7.226562 10.976562 C 7.044271 11.158854 6.822917 11.25 6.5625 11.25 C 6.302083 11.25 6.080729 11.158854 5.898438 10.976562 C 5.716146 10.794271 5.625 10.572917 5.625 10.3125 Z M 9.375 10.3125 C 9.375 10.052084 9.466146 9.830729 9.648438 9.648438 C 9.830729 9.466146 10.052083 9.375 10.3125 9.375 C 10.572916 9.375 10.794271 9.466146 10.976562 9.648438 C 11.158854 9.830729 11.25 10.052084 11.25 10.3125 C 11.25 10.572917 11.158854 10.794271 10.976562 10.976562 C 10.794271 11.158854 10.572916 11.25 10.3125 11.25 C 10.052083 11.25 9.830729 11.158854 9.648438 10.976562 C 9.466146 10.794271 9.375 10.572917 9.375 10.3125 Z M 13.125 10.3125 C 13.124999 10.052084 13.216145 9.830729 13.398438 9.648438 C 13.580729 9.466146 13.802083 9.375 14.0625 9.375 C 14.322916 9.375 14.544271 9.466146 14.726562 9.648438 C 14.908854 9.830729 14.999999 10.052084 15 10.3125 C 14.999999 10.572917 14.908854 10.794271 14.726562 10.976562 C 14.544271 11.158854 14.322916 11.25 14.0625 11.25 C 13.802083 11.25 13.580729 11.158854 13.398438 10.976562 C 13.216145 10.794271 13.124999 10.572917 13.125 10.3125 Z M 4.375 13.75 C 4.205729 13.75 4.059245 13.688151 3.935547 13.564453 C 3.811849 13.440756 3.75 13.294271 3.75 13.125 C 3.75 12.955729 3.811849 12.809245 3.935547 12.685547 C 4.059245 12.56185 4.205729 12.5 4.375 12.5 L 15.625 12.5 C 15.79427 12.5 15.940754 12.56185 16.064453 12.685547 C 16.18815 12.809245 16.25 12.955729 16.25 13.125 C 16.25 13.294271 16.18815 13.440756 16.064453 13.564453 C 15.940754 13.688151 15.79427 13.75 15.625 13.75 Z "), new SettingOption(Translator.SettingsMessageList_Title, Translator.SettingsMessageList_Description, WinoPage.MessageListPage,"F1 M 20 1.25 L 20 12.5 L 18.75 12.5 L 18.75 2.5 L 1.25 2.5 L 1.25 13.75 L 3.75 13.75 L 3.75 16.611328 L 6.611328 13.75 L 13.75 13.75 L 13.75 15 L 7.138672 15 L 2.5 19.638672 L 2.5 15 L 0 15 L 0 1.25 Z M 16.875 13.75 L 20 16.875 L 16.875 20 L 15.986328 19.111328 L 17.607422 17.5 L 11.25 17.5 L 11.25 16.25 L 17.607422 16.25 L 15.986328 14.638672 Z "), new SettingOption(Translator.SettingsReadComposePane_Title, Translator.SettingsReadComposePane_Description, WinoPage.ReadComposePanePage,"F1 M 20 2.5 L 20 3.75 L 8.75 3.75 L 8.75 2.5 Z M 17.5 15 L 0 15 L 0 13.75 L 17.5 13.75 Z M 2.5 10 L 20 10 L 20 11.25 L 2.5 11.25 Z M 2.5 17.5 L 20 17.5 L 20 18.75 L 2.5 18.75 Z M 3.125 7.5 C 2.695312 7.5 2.291667 7.416992 1.914062 7.250977 C 1.536458 7.084961 1.206055 6.860352 0.922852 6.577148 C 0.639648 6.293945 0.415039 5.963542 0.249023 5.585938 C 0.083008 5.208334 0 4.804688 0 4.375 C 0 3.945312 0.083008 3.541668 0.249023 3.164062 C 0.415039 2.786459 0.639648 2.456055 0.922852 2.172852 C 1.206055 1.889648 1.536458 1.665039 1.914062 1.499023 C 2.291667 1.333008 2.695312 1.25 3.125 1.25 C 3.554688 1.25 3.958333 1.333008 4.335938 1.499023 C 4.713542 1.665039 5.043945 1.889648 5.327148 2.172852 C 5.610352 2.456055 5.834961 2.786459 6.000977 3.164062 C 6.166992 3.541668 6.25 3.945312 6.25 4.375 L 5 4.375 C 5 4.114584 4.951172 3.870443 4.853516 3.642578 C 4.755859 3.414715 4.622396 3.216146 4.453125 3.046875 C 4.283854 2.877605 4.085286 2.744141 3.857422 2.646484 C 3.629557 2.548828 3.385417 2.5 3.125 2.5 C 2.864583 2.5 2.620443 2.548828 2.392578 2.646484 C 2.164713 2.744141 1.966146 2.877605 1.796875 3.046875 C 1.627604 3.216146 1.494141 3.414715 1.396484 3.642578 C 1.298828 3.870443 1.25 4.114584 1.25 4.375 C 1.25 4.635418 1.298828 4.879559 1.396484 5.107422 C 1.494141 5.335287 1.627604 5.533854 1.796875 5.703125 C 1.966146 5.872396 2.164713 6.005859 2.392578 6.103516 C 2.620443 6.201172 2.864583 6.25 3.125 6.25 L 17.5 6.25 L 17.5 7.5 Z "), new SettingOption(Translator.SettingsAbout_Title, Translator.SettingsAbout_Description, WinoPage.AboutPage,"F1 M 9.375 18.75 C 8.509114 18.75 7.677409 18.639322 6.879883 18.417969 C 6.082356 18.196615 5.335286 17.882486 4.638672 17.475586 C 3.942057 17.068686 3.308919 16.580404 2.739258 16.010742 C 2.169596 15.441081 1.681315 14.807943 1.274414 14.111328 C 0.867513 13.414714 0.553385 12.667644 0.332031 11.870117 C 0.110677 11.072592 0 10.240886 0 9.375 C 0 8.509115 0.110677 7.677409 0.332031 6.879883 C 0.553385 6.082357 0.867513 5.335287 1.274414 4.638672 C 1.681315 3.942059 2.169596 3.30892 2.739258 2.739258 C 3.308919 2.169598 3.942057 1.681316 4.638672 1.274414 C 5.335286 0.867514 6.082356 0.553387 6.879883 0.332031 C 7.677409 0.110678 8.509114 0 9.375 0 C 10.240885 0 11.072591 0.110678 11.870117 0.332031 C 12.667643 0.553387 13.414713 0.867514 14.111328 1.274414 C 14.807942 1.681316 15.44108 2.169598 16.010742 2.739258 C 16.580402 3.30892 17.068684 3.942059 17.475586 4.638672 C 17.882486 5.335287 18.196613 6.082357 18.417969 6.879883 C 18.639322 7.677409 18.75 8.509115 18.75 9.375 C 18.75 10.240886 18.639322 11.072592 18.417969 11.870117 C 18.196613 12.667644 17.882486 13.414714 17.475586 14.111328 C 17.068684 14.807943 16.580402 15.441081 16.010742 16.010742 C 15.44108 16.580404 14.807942 17.068686 14.111328 17.475586 C 13.414713 17.882486 12.667643 18.196615 11.870117 18.417969 C 11.072591 18.639322 10.240885 18.75 9.375 18.75 Z M 9.375 1.25 C 8.626302 1.25 7.906901 1.347656 7.216797 1.542969 C 6.526692 1.738281 5.880533 2.011719 5.27832 2.363281 C 4.676106 2.714844 4.127604 3.138021 3.632812 3.632812 C 3.138021 4.127604 2.714844 4.676107 2.363281 5.27832 C 2.011719 5.880534 1.738281 6.52832 1.542969 7.22168 C 1.347656 7.915039 1.25 8.632812 1.25 9.375 C 1.25 10.117188 1.347656 10.834961 1.542969 11.52832 C 1.738281 12.22168 2.011719 12.869467 2.363281 13.47168 C 2.714844 14.073894 3.138021 14.622396 3.632812 15.117188 C 4.127604 15.611979 4.676106 16.035156 5.27832 16.386719 C 5.880533 16.738281 6.526692 17.011719 7.216797 17.207031 C 7.906901 17.402344 8.626302 17.5 9.375 17.5 C 10.117188 17.5 10.834961 17.402344 11.52832 17.207031 C 12.221679 17.011719 12.869465 16.738281 13.47168 16.386719 C 14.073893 16.035156 14.622396 15.611979 15.117188 15.117188 C 15.611979 14.622396 16.035156 14.073894 16.386719 13.47168 C 16.738281 12.869467 17.011719 12.223308 17.207031 11.533203 C 17.402344 10.8431 17.5 10.123698 17.5 9.375 C 17.5 8.632812 17.402344 7.915039 17.207031 7.22168 C 17.011719 6.52832 16.738281 5.880534 16.386719 5.27832 C 16.035156 4.676107 15.611979 4.127604 15.117188 3.632812 C 14.622396 3.138021 14.073893 2.714844 13.47168 2.363281 C 12.869465 2.011719 12.221679 1.738281 11.52832 1.542969 C 10.834961 1.347656 10.117188 1.25 9.375 1.25 Z M 8.75 7.5 L 10 7.5 L 10 13.75 L 8.75 13.75 Z M 8.75 5 L 10 5 L 10 6.25 L 8.75 6.25 Z "), diff --git a/Wino.Mail.WinUI/Views/Abstract/KeyboardShortuctsPageAbstract.cs b/Wino.Mail.WinUI/Views/Abstract/KeyboardShortuctsPageAbstract.cs new file mode 100644 index 00000000..193ce90a --- /dev/null +++ b/Wino.Mail.WinUI/Views/Abstract/KeyboardShortuctsPageAbstract.cs @@ -0,0 +1,8 @@ +using Wino.Core.ViewModels; +using Wino.Views.Abstract; + +namespace Wino.Mail.WinUI.Views.Abstract; + +public abstract class KeyboardShortcutsPageAbstract : SettingsPageBase +{ +} diff --git a/Wino.Mail.WinUI/Views/Settings/KeyboardShortcutsPage.xaml b/Wino.Mail.WinUI/Views/Settings/KeyboardShortcutsPage.xaml new file mode 100644 index 00000000..617484ee --- /dev/null +++ b/Wino.Mail.WinUI/Views/Settings/KeyboardShortcutsPage.xaml @@ -0,0 +1,93 @@ + + + + + + + + + + + +