import { formatDocsShortcutBinding, matchesDocsShortcutBinding, normalizeDocsShortcutBinding, } from "@/lib/drive/docs-keyboard-shortcut" import { DOCS_KEYBOARD_SHORTCUT_DEFINITIONS, DOCS_KEYBOARD_SHORTCUTS_BY_ID, type DocsKeyboardShortcutsUserConfig, type DocsShortcutBinding, type DocsShortcutDefinition, type DocsShortcutId, } from "@/lib/drive/docs-keyboard-shortcuts-config" export function getDocsShortcutDefinition(id: DocsShortcutId): DocsShortcutDefinition { return DOCS_KEYBOARD_SHORTCUTS_BY_ID[id] } export function resolveDocsShortcutBinding( id: DocsShortcutId, overrides: DocsKeyboardShortcutsUserConfig = {} ): DocsShortcutBinding { return overrides[id] ?? DOCS_KEYBOARD_SHORTCUTS_BY_ID[id].defaultBinding } export function resolveDocsShortcutBindings( id: DocsShortcutId, overrides: DocsKeyboardShortcutsUserConfig = {} ): DocsShortcutBinding[] { const definition = DOCS_KEYBOARD_SHORTCUTS_BY_ID[id] const primary = resolveDocsShortcutBinding(id, overrides) const alt = overrides[id] ? [] : (definition.altBindings ?? []) return [primary, ...alt] } export function formatDocsShortcutId( id: DocsShortcutId, overrides: DocsKeyboardShortcutsUserConfig = {} ): string { return formatDocsShortcutBinding(resolveDocsShortcutBinding(id, overrides)) } export function matchDocsShortcutEvent( event: KeyboardEvent, overrides: DocsKeyboardShortcutsUserConfig = {}, filter?: (definition: DocsShortcutDefinition) => boolean ): DocsShortcutId | null { for (const definition of DOCS_KEYBOARD_SHORTCUT_DEFINITIONS) { if (filter && !filter(definition)) continue const bindings = resolveDocsShortcutBindings(definition.id, overrides) if (bindings.some((binding) => matchesDocsShortcutBinding(event, binding))) { return definition.id } } return null } export function isValidDocsShortcutBinding(value: unknown): value is DocsShortcutBinding { if (!value || typeof value !== "object") return false const binding = value as DocsShortcutBinding if (typeof binding.key !== "string" || binding.key.length === 0) return false if (binding.mod != null && typeof binding.mod !== "boolean") return false if (binding.shift != null && typeof binding.shift !== "boolean") return false if (binding.alt != null && typeof binding.alt !== "boolean") return false return true } export function sanitizeDocsKeyboardShortcutsUserConfig( raw: unknown ): DocsKeyboardShortcutsUserConfig { if (!raw || typeof raw !== "object") return {} const input = raw as Record const output: DocsKeyboardShortcutsUserConfig = {} for (const definition of DOCS_KEYBOARD_SHORTCUT_DEFINITIONS) { const candidate = input[definition.id] if (isValidDocsShortcutBinding(candidate)) { output[definition.id] = normalizeDocsShortcutBinding(candidate) } } return output } /** Catalog for a future keyboard-shortcuts settings screen. */ export function listDocsKeyboardShortcutCatalog( overrides: DocsKeyboardShortcutsUserConfig = {} ) { return DOCS_KEYBOARD_SHORTCUT_DEFINITIONS.map((definition) => ({ ...definition, binding: resolveDocsShortcutBinding(definition.id, overrides), display: formatDocsShortcutId(definition.id, overrides), isCustomized: Boolean(overrides[definition.id]), })) }