+ {{ $t('keyboardShortcuts.helpText') }} +
diff --git a/keyboard-shortcuts-custom.md b/keyboard-shortcuts-custom.md new file mode 100644 index 0000000000..2dff2e9b55 --- /dev/null +++ b/keyboard-shortcuts-custom.md @@ -0,0 +1,1159 @@ +# Customizable Keyboard Shortcuts - Implementation Plan + +**Date:** 2025-11-27 +**Feature:** Allow users to customize keyboard shortcuts for actions in the Vikunja frontend + +## Overview + +This plan outlines the implementation of customizable keyboard shortcuts for Vikunja. Users will be able to customize action shortcuts (task operations, general app shortcuts) while keeping navigation shortcuts (j/k, g+key sequences) fixed. Customizations will be stored in the existing `frontendSettings` system and sync across devices. + +## Requirements Summary + +- **Scope:** Only action shortcuts customizable (not navigation keys like j/k or g+letter sequences) +- **Location:** Dedicated section in user settings page +- **Storage:** `frontendSettings` in auth store (syncs via backend) +- **Conflicts:** Prevent conflicts with validation and clear error messages +- **Reset:** Individual shortcut reset, category reset, and reset all +- **Display:** Show all shortcuts with non-customizable ones displayed as disabled + +## Architecture Overview + +### Core Component: ShortcutManager Composable + +The centerpiece will be a new `useShortcutManager()` composable that becomes the single source of truth for all keyboard shortcuts. This manager will: + +**Core Responsibilities:** +- Maintain the registry of all shortcuts (default + custom) +- Validate shortcut assignments and prevent conflicts +- Load/save custom shortcuts to `frontendSettings` +- Provide a reactive API for binding shortcuts to actions +- Handle the merging of defaults with user customizations + +**Key Design Decisions:** + +1. **Two-tier storage model:** Immutable defaults (from `shortcuts.ts`) and mutable overrides (from `frontendSettings.customShortcuts`) +2. **Semantic IDs:** Instead of hardcoded key strings, components register actions using IDs like `"general.toggleMenu"` or `"task.markDone"` +3. **Shared composable:** Uses VueUse's `createSharedComposable` for consistent state across all instances +4. **Reactive updates:** When settings change, all bound shortcuts update automatically without page reload + +### Current State Analysis + +**Current Implementation Uses Three Binding Approaches:** + +1. **v-shortcut directive** - Element-bound shortcuts on buttons/links + - Uses `@github/hotkey` library's `install()`/`uninstall()` + - Example: `