diff --git a/apps/desktop/src/components/editor/EditorSettingsDialog.vue b/apps/desktop/src/components/editor/EditorSettingsDialog.vue index 2d1eb23a6d..37e2a8e7e7 100644 --- a/apps/desktop/src/components/editor/EditorSettingsDialog.vue +++ b/apps/desktop/src/components/editor/EditorSettingsDialog.vue @@ -493,6 +493,7 @@ function onShortcutKeydown(actionId: ShortcutActionId, event: KeyboardEvent) { } function formatShortcutPill(shortcut: string): string { + if (!shortcut) return "—"; const isMac = globalThis.navigator?.platform?.toLowerCase().includes("mac") ?? false; return shortcut .split("+") @@ -539,6 +540,10 @@ function resetShortcut(actionId: ShortcutActionId) { editShortcuts.value = { ...editShortcuts.value, [actionId]: definition.defaultShortcut }; } +function clearShortcut(actionId: ShortcutActionId) { + editShortcuts.value = { ...editShortcuts.value, [actionId]: "" }; +} + function setAppLayout(value: "separated" | "classic") { editAppLayout.value = value; } @@ -1746,6 +1751,17 @@ watch( > +

{{ t("settings.shortcutConflict") }} diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index 0e3392381b..7e06e87e58 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -1922,6 +1922,7 @@ export default { shortcutScopeSearch: "Search fields", shortcutPressShortcut: "Press shortcut", shortcutConflict: "This shortcut conflicts with another action in the same scope.", + shortcutClear: "Clear shortcut", preview: "Live Preview", customTheme: "Custom Theme", customThemeConfigure: "Configure Custom Theme", diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts index 949a21e2d5..3f286f1803 100644 --- a/apps/desktop/src/i18n/locales/es.ts +++ b/apps/desktop/src/i18n/locales/es.ts @@ -1701,6 +1701,7 @@ export default { shortcutScopeSearch: "Campos de búsqueda", shortcutPressShortcut: "Presiona un atajo", shortcutConflict: "Este atajo entra en conflicto con otra acción del mismo ámbito.", + shortcutClear: "Borrar atajo", preview: "Vista previa en tiempo real", customTheme: "Tema personalizado", customThemeConfigure: "Configurar tema personalizado", diff --git a/apps/desktop/src/i18n/locales/it.ts b/apps/desktop/src/i18n/locales/it.ts index 3e9b7d4eda..5a09c20157 100644 --- a/apps/desktop/src/i18n/locales/it.ts +++ b/apps/desktop/src/i18n/locales/it.ts @@ -1821,6 +1821,7 @@ export default { shortcutScopeSearch: "Cerca campi", shortcutPressShortcut: "Premi scorciatoia", shortcutConflict: "Questa scorciatoia è in conflitto con un'altra azione nello stesso ambito.", + shortcutClear: "Cancella scorciatoia", preview: "Anteprima in tempo reale", customTheme: "Tema personalizzato", customThemeConfigure: "Configura tema personalizzato", diff --git a/apps/desktop/src/i18n/locales/pt-BR.ts b/apps/desktop/src/i18n/locales/pt-BR.ts index 7dd4593c30..57dd4e3383 100644 --- a/apps/desktop/src/i18n/locales/pt-BR.ts +++ b/apps/desktop/src/i18n/locales/pt-BR.ts @@ -1821,6 +1821,7 @@ export default { shortcutScopeSearch: "Campos de pesquisa", shortcutPressShortcut: "Pressione o atalho", shortcutConflict: "Este atalho conflita com outra ação no mesmo escopo.", + shortcutClear: "Limpar atalho", preview: "Pré-visualização ao vivo", customTheme: "Tema personalizado", customThemeConfigure: "Configurar tema personalizado", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index 5d2a9eafba..76aabf2746 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -1921,6 +1921,7 @@ export default { shortcutScopeSearch: "搜索框", shortcutPressShortcut: "按下快捷键", shortcutConflict: "这个快捷键与同一作用域内的其他操作冲突。", + shortcutClear: "清除快捷键", preview: "实时预览", customTheme: "自定义主题", customThemeConfigure: "自定义主题配置", diff --git a/apps/desktop/src/i18n/locales/zh-TW.ts b/apps/desktop/src/i18n/locales/zh-TW.ts index f5e5803bd5..2ef1f42c25 100644 --- a/apps/desktop/src/i18n/locales/zh-TW.ts +++ b/apps/desktop/src/i18n/locales/zh-TW.ts @@ -1793,6 +1793,7 @@ export default { shortcutScopeSearch: "搜尋框", shortcutPressShortcut: "按下快速鍵", shortcutConflict: "這個快速鍵與同一作用域內的其他操作衝突。", + shortcutClear: "清除快速鍵", preview: "即時預覽", customTheme: "自定義主題", customThemeConfigure: "自定義主題配置", diff --git a/apps/desktop/src/lib/keyboardShortcuts.ts b/apps/desktop/src/lib/keyboardShortcuts.ts index 8d2adc9eb5..bb6eed5d51 100644 --- a/apps/desktop/src/lib/keyboardShortcuts.ts +++ b/apps/desktop/src/lib/keyboardShortcuts.ts @@ -1,4 +1,4 @@ -import { DEFAULT_SHORTCUT_SETTINGS, normalizeShortcutSettings, type ShortcutActionId, type ShortcutSettings } from "@/lib/shortcutRegistry"; +import { normalizeShortcutSettings, type ShortcutActionId, type ShortcutSettings } from "@/lib/shortcutRegistry"; export interface ShortcutLikeEvent { key: string; @@ -39,7 +39,7 @@ export function eventToShortcut(event: ShortcutLikeEvent): string | null { } export function matchesShortcut(event: ShortcutLikeEvent, shortcut: string): boolean { - if (event.isComposing) return false; + if (event.isComposing || !shortcut) return false; const parts = shortcut.split("+"); const key = parts[parts.length - 1] ?? ""; const modifiers = new Set(parts.slice(0, -1)); @@ -60,7 +60,7 @@ export function matchesShortcut(event: ShortcutLikeEvent, shortcut: string): boo } function actionShortcut(actionId: ShortcutActionId, shortcuts?: Partial): string { - return normalizeShortcutSettings(shortcuts)[actionId] || DEFAULT_SHORTCUT_SETTINGS[actionId]; + return normalizeShortcutSettings(shortcuts)[actionId]; } export function isExecuteSqlShortcut(event: ShortcutLikeEvent, shortcuts?: Partial): boolean { diff --git a/apps/desktop/src/lib/shortcutRegistry.ts b/apps/desktop/src/lib/shortcutRegistry.ts index 7b7a5cdee7..9e171ec7b1 100644 --- a/apps/desktop/src/lib/shortcutRegistry.ts +++ b/apps/desktop/src/lib/shortcutRegistry.ts @@ -143,7 +143,7 @@ export const SHORTCUT_DEFINITIONS: ShortcutDefinition[] = [ export const DEFAULT_SHORTCUT_SETTINGS: ShortcutSettings = Object.fromEntries(SHORTCUT_DEFINITIONS.map((definition) => [definition.id, definition.defaultShortcut])) as ShortcutSettings; export function normalizeShortcutSettings(settings?: Partial): ShortcutSettings { - return Object.fromEntries(SHORTCUT_DEFINITIONS.map((definition) => [definition.id, typeof settings?.[definition.id] === "string" && settings[definition.id]?.trim() ? settings[definition.id] : definition.defaultShortcut])) as ShortcutSettings; + return Object.fromEntries(SHORTCUT_DEFINITIONS.map((definition) => [definition.id, typeof settings?.[definition.id] === "string" ? settings[definition.id] : definition.defaultShortcut])) as ShortcutSettings; } export function shortcutToCodeMirrorKey(shortcut: string): string { @@ -166,6 +166,7 @@ export function formatShortcut(shortcut: string, platform = globalThis.navigator } export function findShortcutConflict(actionId: ShortcutActionId, shortcut: string, shortcuts: ShortcutSettings): ShortcutActionId | null { + if (!shortcut) return null; const definition = SHORTCUT_DEFINITIONS.find((item) => item.id === actionId); if (!definition) return null;