From 964bc74b83d5f256b4fb77c35dcc7a66eef89bc6 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 27 Jul 2025 21:16:23 +0300 Subject: [PATCH] refactor(command_palette): use declarative command approach --- apps/client/src/services/command_registry.ts | 35 +++++++++++++------ apps/client/src/services/keyboard_actions.ts | 3 ++ .../src/widgets/dialogs/jump_to_note.ts | 1 + 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/apps/client/src/services/command_registry.ts b/apps/client/src/services/command_registry.ts index 5bb4bbde6..2fc9beb83 100644 --- a/apps/client/src/services/command_registry.ts +++ b/apps/client/src/services/command_registry.ts @@ -1,6 +1,6 @@ import appContext, { type CommandNames } from "../components/app_context.js"; import type NoteTreeWidget from "../widgets/note_tree.js"; -import keyboardActions from "./keyboard_actions.js"; +import keyboardActions, { Action } from "./keyboard_actions.js"; export interface CommandDefinition { id: string; @@ -12,6 +12,8 @@ export interface CommandDefinition { handler?: () => void | Promise; aliases?: string[]; source?: "manual" | "keyboard-action"; + /** Reference to the original keyboard action for scope checking. */ + keyboardAction?: Action; } class CommandRegistry { @@ -155,7 +157,7 @@ class CommandRegistry { } } - private registerKeyboardActions(actions: any[]) { + private registerKeyboardActions(actions: Action[]) { for (const action of actions) { // Skip actions that we've already manually registered if (this.commands.has(action.actionName)) { @@ -167,9 +169,6 @@ class CommandRegistry { continue; } - // Note-tree scoped actions need special handling - const needsFocusEmulation = action.scope === "note-tree"; - // Get the primary shortcut (first one in the list) const primaryShortcut = action.effectiveShortcuts?.[0]; @@ -182,7 +181,7 @@ class CommandRegistry { shortcut: primaryShortcut ? this.formatShortcut(primaryShortcut) : undefined, commandName: action.actionName as CommandNames, source: "keyboard-action", - handler: needsFocusEmulation ? () => this.executeWithNoteTreeFocus(action.actionName) : undefined + keyboardAction: action }; this.register(commandDef); @@ -325,13 +324,29 @@ class CommandRegistry { return; } + // Execute custom handler if provided if (command.handler) { await command.handler(); - } else if (command.commandName) { - appContext.triggerCommand(command.commandName); - } else { - console.error(`Command ${commandId} has no handler or commandName`); + return; } + + // Handle keyboard action with scope-aware execution + if (command.keyboardAction && command.commandName) { + if (command.keyboardAction.scope === "note-tree") { + this.executeWithNoteTreeFocus(command.commandName); + } else { + appContext.triggerCommand(command.commandName); + } + return; + } + + // Fallback for commands without keyboard action reference + if (command.commandName) { + appContext.triggerCommand(command.commandName); + return; + } + + console.error(`Command ${commandId} has no handler or commandName`); } private executeWithNoteTreeFocus(actionName: CommandNames) { diff --git a/apps/client/src/services/keyboard_actions.ts b/apps/client/src/services/keyboard_actions.ts index 3cb0ffd33..35cae43fa 100644 --- a/apps/client/src/services/keyboard_actions.ts +++ b/apps/client/src/services/keyboard_actions.ts @@ -10,6 +10,9 @@ export interface Action { actionName: CommandNames; effectiveShortcuts: string[]; scope: string; + friendlyName: string; + description?: string; + iconClass?: string; } const keyboardActionsLoaded = server.get("keyboard-actions").then((actions) => { diff --git a/apps/client/src/widgets/dialogs/jump_to_note.ts b/apps/client/src/widgets/dialogs/jump_to_note.ts index abadde0d3..5139f55ab 100644 --- a/apps/client/src/widgets/dialogs/jump_to_note.ts +++ b/apps/client/src/widgets/dialogs/jump_to_note.ts @@ -179,6 +179,7 @@ export default class JumpToNoteDialog extends BasicWidget { // If we restored a command mode value, manually trigger command display if (this.isCommandMode) { + console.log("DEBUG: Restoring command mode, clearing and showing commands"); // Clear the value first, then set it to ">" to trigger a proper change this.$autoComplete.autocomplete("val", ""); noteAutocompleteService.showAllCommands(this.$autoComplete);