diff --git a/apps/client/src/components/app_context.ts b/apps/client/src/components/app_context.ts index 2944005bd..aef00f032 100644 --- a/apps/client/src/components/app_context.ts +++ b/apps/client/src/components/app_context.ts @@ -266,6 +266,72 @@ export type CommandMappings = { jumpToNote: CommandData; commandPalette: CommandData; + // Keyboard shortcuts + backInNoteHistory: CommandData; + forwardInNoteHistory: CommandData; + forceSaveRevision: CommandData; + scrollToActiveNote: CommandData; + quickSearch: CommandData; + collapseTree: CommandData; + createNoteAfter: CommandData; + createNoteInto: CommandData; + addNoteAboveToSelection: CommandData; + addNoteBelowToSelection: CommandData; + openNewTab: CommandData; + activateNextTab: CommandData; + activatePreviousTab: CommandData; + openNewWindow: CommandData; + toggleTray: CommandData; + firstTab: CommandData; + secondTab: CommandData; + thirdTab: CommandData; + fourthTab: CommandData; + fifthTab: CommandData; + sixthTab: CommandData; + seventhTab: CommandData; + eigthTab: CommandData; + ninthTab: CommandData; + lastTab: CommandData; + showNoteSource: CommandData; + showSQLConsole: CommandData; + showBackendLog: CommandData; + showCheatsheet: CommandData; + showHelp: CommandData; + addLinkToText: CommandData; + followLinkUnderCursor: CommandData; + insertDateTimeToText: CommandData; + pasteMarkdownIntoText: CommandData; + cutIntoNote: CommandData; + addIncludeNoteToText: CommandData; + editReadOnlyNote: CommandData; + toggleRibbonTabClassicEditor: CommandData; + toggleRibbonTabBasicProperties: CommandData; + toggleRibbonTabBookProperties: CommandData; + toggleRibbonTabFileProperties: CommandData; + toggleRibbonTabImageProperties: CommandData; + toggleRibbonTabOwnedAttributes: CommandData; + toggleRibbonTabInheritedAttributes: CommandData; + toggleRibbonTabPromotedAttributes: CommandData; + toggleRibbonTabNoteMap: CommandData; + toggleRibbonTabNoteInfo: CommandData; + toggleRibbonTabNotePaths: CommandData; + toggleRibbonTabSimilarNotes: CommandData; + toggleRightPane: CommandData; + printActiveNote: CommandData; + exportAsPdf: CommandData; + openNoteExternally: CommandData; + renderActiveNote: CommandData; + unhoist: CommandData; + reloadFrontendApp: CommandData; + openDevTools: CommandData; + findInText: CommandData; + toggleLeftPane: CommandData; + toggleFullscreen: CommandData; + zoomOut: CommandData; + zoomIn: CommandData; + zoomReset: CommandData; + copyWithoutFormatting: CommandData; + // Geomap deleteFromMap: { noteId: string }; diff --git a/apps/client/src/services/shortcuts.spec.ts b/apps/client/src/services/shortcuts.spec.ts index c23cb3730..1a20f9a84 100644 --- a/apps/client/src/services/shortcuts.spec.ts +++ b/apps/client/src/services/shortcuts.spec.ts @@ -15,10 +15,10 @@ const mockElement = { }; const mockJQuery = vi.fn(() => [mockElement]); -mockJQuery.length = 1; +(mockJQuery as any).length = 1; mockJQuery[0] = mockElement; -global.$ = mockJQuery as any; +(global as any).$ = mockJQuery as any; global.document = mockElement as any; describe("shortcuts", () => { diff --git a/apps/client/src/services/shortcuts.ts b/apps/client/src/services/shortcuts.ts index 22b1ce3bc..00f2f7721 100644 --- a/apps/client/src/services/shortcuts.ts +++ b/apps/client/src/services/shortcuts.ts @@ -1,7 +1,7 @@ import utils from "./utils.js"; type ElementType = HTMLElement | Document; -type Handler = () => void; +type Handler = (e: KeyboardEvent) => void; interface ShortcutBinding { element: HTMLElement | Document; @@ -45,7 +45,7 @@ function bindElShortcut($el: JQuery, keyboardShortcut: st if (matchesShortcut(e, keyboardShortcut)) { e.preventDefault(); e.stopPropagation(); - handler(); + handler(e); } }; diff --git a/apps/client/src/widgets/buttons/command_button.ts b/apps/client/src/widgets/buttons/command_button.ts index ba32fb7f8..49b147d35 100644 --- a/apps/client/src/widgets/buttons/command_button.ts +++ b/apps/client/src/widgets/buttons/command_button.ts @@ -1,9 +1,10 @@ +import { ActionKeyboardShortcut } from "@triliumnext/commons"; import type { CommandNames } from "../../components/app_context.js"; -import keyboardActionsService, { type Action } from "../../services/keyboard_actions.js"; +import keyboardActionsService from "../../services/keyboard_actions.js"; import AbstractButtonWidget, { type AbstractButtonWidgetSettings } from "./abstract_button.js"; import type { ButtonNoteIdProvider } from "./button_from_note.js"; -let actions: Action[]; +let actions: ActionKeyboardShortcut[]; keyboardActionsService.getActions().then((as) => (actions = as)); @@ -49,7 +50,7 @@ export default class CommandButtonWidget extends AbstractButtonWidget act.actionName === this._command); - if (action && action.effectiveShortcuts.length > 0) { + if (action?.effectiveShortcuts && action.effectiveShortcuts.length > 0) { return `${title} (${action.effectiveShortcuts.join(", ")})`; } else { return title; diff --git a/apps/client/src/widgets/containers/ribbon_container.ts b/apps/client/src/widgets/containers/ribbon_container.ts index 7563e2a2b..9aee7bb67 100644 --- a/apps/client/src/widgets/containers/ribbon_container.ts +++ b/apps/client/src/widgets/containers/ribbon_container.ts @@ -268,7 +268,7 @@ export default class RibbonContainer extends NoteContextAwareWidget { const action = actions.find((act) => act.actionName === toggleCommandName); const title = $(this).attr("data-title"); - if (action && action.effectiveShortcuts.length > 0) { + if (action?.effectiveShortcuts && action.effectiveShortcuts.length > 0) { return `${title} (${action.effectiveShortcuts.join(", ")})`; } else { return title ?? ""; diff --git a/apps/client/src/widgets/dialogs/jump_to_note.ts b/apps/client/src/widgets/dialogs/jump_to_note.ts index 6c9b78d84..70676f696 100644 --- a/apps/client/src/widgets/dialogs/jump_to_note.ts +++ b/apps/client/src/widgets/dialogs/jump_to_note.ts @@ -187,7 +187,7 @@ export default class JumpToNoteDialog extends BasicWidget { } } - showInFullText(e: JQuery.TriggeredEvent) { + showInFullText(e: JQuery.TriggeredEvent | KeyboardEvent) { // stop from propagating upwards (dangerous, especially with ctrl+enter executable javascript notes) e.preventDefault(); e.stopPropagation(); diff --git a/apps/client/src/widgets/note_tree.ts b/apps/client/src/widgets/note_tree.ts index d6dd4d733..301a61b6b 100644 --- a/apps/client/src/widgets/note_tree.ts +++ b/apps/client/src/widgets/note_tree.ts @@ -1552,7 +1552,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget { const hotKeyMap: Record boolean> = {}; for (const action of actions) { - for (const shortcut of action.effectiveShortcuts) { + for (const shortcut of action.effectiveShortcuts ?? []) { hotKeyMap[shortcutService.normalizeShortcut(shortcut)] = (node) => { const notePath = treeService.getNotePath(node); diff --git a/apps/client/src/widgets/type_widgets/options/text_notes/date_time_format.ts b/apps/client/src/widgets/type_widgets/options/text_notes/date_time_format.ts index 467bd4a78..c5fd6876c 100644 --- a/apps/client/src/widgets/type_widgets/options/text_notes/date_time_format.ts +++ b/apps/client/src/widgets/type_widgets/options/text_notes/date_time_format.ts @@ -52,7 +52,8 @@ export default class DateTimeFormatOptions extends OptionsWidget { } async optionsLoaded(options: OptionMap) { - const shortcutKey = (await keyboardActionsService.getAction("insertDateTimeToText")).effectiveShortcuts.join(", "); + const action = await keyboardActionsService.getAction("insertDateTimeToText"); + const shortcutKey = (action.effectiveShortcuts ?? []).join(", "); const $link = await linkService.createLink("_hidden/_options/_optionsShortcuts", { "title": shortcutKey, "showTooltip": false