Improved keyboad shortcuts.

This commit is contained in:
Burak Kaan Köse
2026-03-08 13:21:42 +01:00
parent c1568d33e6
commit 15400d4096
35 changed files with 979 additions and 336 deletions
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models;
using Wino.Core.Domain.Models.Navigation;
namespace Wino.Core.ViewModels;
@@ -40,6 +41,8 @@ public class CoreBaseViewModel : ObservableRecipient, INavigationAware
public virtual void OnPageLoaded() { }
public virtual Task KeyboardShortcutHook(KeyboardShortcutTriggerDetails args) => Task.CompletedTask;
public Task ExecuteUIThread(Action action)
{
if (action == null) return Task.CompletedTask;
@@ -13,13 +13,16 @@ public partial class BreadcrumbNavigationItemViewModel : ObservableObject
public int StepNumber { get; set; }
public int BackStackDepth { get; set; }
public BreadcrumbNavigationRequested Request { get; set; }
public BreadcrumbNavigationItemViewModel(BreadcrumbNavigationRequested request, bool isActive, int stepNumber = 0)
public BreadcrumbNavigationItemViewModel(BreadcrumbNavigationRequested request, bool isActive, int stepNumber = 0, int backStackDepth = 0)
{
Request = request;
Title = request.PageTitle;
IsActive = isActive;
StepNumber = stepNumber;
BackStackDepth = backStackDepth;
}
}
@@ -0,0 +1,33 @@
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
namespace Wino.Core.ViewModels.Data;
public class KeyboardShortcutActionViewModel
{
public WinoApplicationMode Mode { get; }
public KeyboardShortcutAction Action { get; }
public string DisplayName => Action switch
{
KeyboardShortcutAction.NewMail => Translator.MenuNewMail,
KeyboardShortcutAction.ToggleReadUnread => Translator.KeyboardShortcuts_ActionToggleReadUnread,
KeyboardShortcutAction.ToggleFlag => Translator.KeyboardShortcuts_ActionToggleFlag,
KeyboardShortcutAction.ToggleArchive => Translator.KeyboardShortcuts_ActionToggleArchive,
KeyboardShortcutAction.Delete => Translator.Buttons_Delete,
KeyboardShortcutAction.Move => Translator.MailOperation_Move,
KeyboardShortcutAction.Reply => Translator.MailOperation_Reply,
KeyboardShortcutAction.ReplyAll => Translator.MailOperation_ReplyAll,
KeyboardShortcutAction.Send => Translator.Buttons_Send,
KeyboardShortcutAction.NewEvent => Translator.CalendarEventCompose_NewEventButton,
_ => Action.ToString()
};
public KeyboardShortcutActionViewModel(WinoApplicationMode mode, KeyboardShortcutAction action)
{
Mode = mode;
Action = action;
}
public override string ToString() => DisplayName;
}
@@ -15,9 +15,10 @@ public partial class KeyboardShortcutViewModel : ObservableObject
public partial bool IsEnabled { get; set; }
public Guid Id { get; }
public WinoApplicationMode Mode { get; }
public string Key { get; }
public ModifierKeys ModifierKeys { get; }
public MailOperation MailOperation { get; }
public KeyboardShortcutAction Action { get; }
public DateTime CreatedAt { get; }
public string DisplayName
@@ -38,25 +39,30 @@ public partial class KeyboardShortcutViewModel : ObservableObject
}
}
public string MailOperationDisplayName
public string ModeDisplayName => Mode switch
{
WinoApplicationMode.Mail => Translator.KeyboardShortcuts_ModeMail,
WinoApplicationMode.Calendar => Translator.KeyboardShortcuts_ModeCalendar,
_ => Mode.ToString()
};
public string ActionDisplayName
{
get
{
return MailOperation switch
return Action switch
{
MailOperation.Archive => Translator.MailOperation_Archive,
MailOperation.UnArchive => Translator.MailOperation_Unarchive,
MailOperation.SoftDelete => Translator.MailOperation_Delete,
MailOperation.Move => Translator.MailOperation_Move,
MailOperation.MoveToJunk => Translator.MailOperation_MoveJunk,
MailOperation.SetFlag => Translator.MailOperation_SetFlag,
MailOperation.ClearFlag => Translator.MailOperation_ClearFlag,
MailOperation.MarkAsRead => Translator.MailOperation_MarkAsRead,
MailOperation.MarkAsUnread => Translator.MailOperation_MarkAsUnread,
MailOperation.Reply => Translator.MailOperation_Reply,
MailOperation.ReplyAll => Translator.MailOperation_ReplyAll,
MailOperation.Forward => Translator.MailOperation_Forward,
_ => MailOperation.ToString()
KeyboardShortcutAction.NewMail => Translator.MenuNewMail,
KeyboardShortcutAction.ToggleReadUnread => Translator.KeyboardShortcuts_ActionToggleReadUnread,
KeyboardShortcutAction.ToggleFlag => Translator.KeyboardShortcuts_ActionToggleFlag,
KeyboardShortcutAction.ToggleArchive => Translator.KeyboardShortcuts_ActionToggleArchive,
KeyboardShortcutAction.Delete => Translator.Buttons_Delete,
KeyboardShortcutAction.Move => Translator.MailOperation_Move,
KeyboardShortcutAction.Reply => Translator.MailOperation_Reply,
KeyboardShortcutAction.ReplyAll => Translator.MailOperation_ReplyAll,
KeyboardShortcutAction.Send => Translator.Buttons_Send,
KeyboardShortcutAction.NewEvent => Translator.CalendarEventCompose_NewEventButton,
_ => Action.ToString()
};
}
}
@@ -64,9 +70,10 @@ public partial class KeyboardShortcutViewModel : ObservableObject
public KeyboardShortcutViewModel(KeyboardShortcut shortcut)
{
Id = shortcut.Id;
Mode = shortcut.Mode;
Key = shortcut.Key;
ModifierKeys = shortcut.ModifierKeys;
MailOperation = shortcut.MailOperation;
Action = shortcut.Action;
CreatedAt = shortcut.CreatedAt;
IsEnabled = shortcut.IsEnabled;
}
@@ -76,9 +83,10 @@ public partial class KeyboardShortcutViewModel : ObservableObject
return new KeyboardShortcut
{
Id = Id,
Mode = Mode,
Key = Key,
ModifierKeys = ModifierKeys,
MailOperation = MailOperation,
Action = Action,
CreatedAt = CreatedAt,
IsEnabled = IsEnabled
};
@@ -70,7 +70,7 @@ public partial class KeyboardShortcutsPageViewModel : CoreBaseViewModel
try
{
// Check if key combination is already in use
var isInUse = await _keyboardShortcutService.IsKeyCombinationInUseAsync(result.Key, result.ModifierKeys, null);
var isInUse = await _keyboardShortcutService.IsKeyCombinationInUseAsync(result.Mode, result.Key, result.ModifierKeys, null);
if (isInUse)
{
await _dialogService.ShowMessageAsync(Translator.KeyboardShortcuts_ShortcutInUse, Translator.GeneralTitle_Error, WinoCustomMessageDialogIcon.Error);
@@ -80,9 +80,10 @@ public partial class KeyboardShortcutsPageViewModel : CoreBaseViewModel
// Create new shortcut
var shortcut = new KeyboardShortcut
{
Mode = result.Mode,
Key = result.Key,
ModifierKeys = result.ModifierKeys,
MailOperation = result.MailOperation,
Action = result.Action,
IsEnabled = true
};
@@ -116,7 +117,7 @@ public partial class KeyboardShortcutsPageViewModel : CoreBaseViewModel
try
{
// Check if key combination is already in use (excluding current shortcut)
var isInUse = await _keyboardShortcutService.IsKeyCombinationInUseAsync(result.Key, result.ModifierKeys, shortcut.Id);
var isInUse = await _keyboardShortcutService.IsKeyCombinationInUseAsync(result.Mode, result.Key, result.ModifierKeys, shortcut.Id);
if (isInUse)
{
await _dialogService.ShowMessageAsync(Translator.KeyboardShortcuts_ShortcutInUse, Translator.GeneralTitle_Error, WinoCustomMessageDialogIcon.Error);
@@ -125,9 +126,10 @@ public partial class KeyboardShortcutsPageViewModel : CoreBaseViewModel
// Update existing shortcut
var updatedShortcut = shortcut.ToEntity();
updatedShortcut.Mode = result.Mode;
updatedShortcut.Key = result.Key;
updatedShortcut.ModifierKeys = result.ModifierKeys;
updatedShortcut.MailOperation = result.MailOperation;
updatedShortcut.Action = result.Action;
await _keyboardShortcutService.SaveKeyboardShortcutAsync(updatedShortcut);
await LoadShortcutsAsync();