import type { DocsShortcutBinding } from "@/lib/drive/docs-keyboard-shortcuts-config" export type { DocsShortcutBinding } export function isMacPlatform(): boolean { if (typeof navigator === "undefined") return false return ( /Mac|iPhone|iPad|iPod/.test(navigator.platform) || (navigator.userAgent.includes("Mac") && "ontouchend" in document) ) } export function docsModKeyLabel(): string { return isMacPlatform() ? "⌘" : "Ctrl" } export function normalizeDocsShortcutBinding( binding: DocsShortcutBinding ): Required> & { mod: boolean shift: boolean alt: boolean } { return { key: binding.key.length === 1 ? binding.key.toLowerCase() : binding.key, mod: binding.mod ?? true, shift: binding.shift ?? false, alt: binding.alt ?? false, } } /** Display label, e.g. ⌘Z or Ctrl+Shift+V */ export function formatDocsShortcutBinding(binding: DocsShortcutBinding): string { const normalized = normalizeDocsShortcutBinding(binding) const mod = docsModKeyLabel() const isMac = isMacPlatform() const keyLabel = normalized.key.length === 1 ? normalized.key.toUpperCase() : normalized.key if (isMac) { const parts: string[] = [] if (normalized.shift) parts.push("Maj") if (normalized.alt) parts.push("⌥") if (parts.length > 0) { return `${mod}+${parts.join("+")}+${keyLabel}` } return normalized.mod ? `${mod}${keyLabel}` : keyLabel } const parts: string[] = [] if (normalized.shift) parts.push("Shift") if (normalized.alt) parts.push("Alt") if (normalized.mod) parts.push(mod) parts.push(keyLabel) return parts.join("+") } export function matchesDocsShortcutBinding( event: KeyboardEvent, binding: DocsShortcutBinding ): boolean { const normalized = normalizeDocsShortcutBinding(binding) const modPressed = isMacPlatform() ? event.metaKey : event.ctrlKey if (normalized.mod && !modPressed) return false if (!normalized.mod && modPressed) return false const eventKey = event.key.length === 1 ? event.key.toLowerCase() : event.key if (eventKey !== normalized.key) return false if (normalized.shift !== event.shiftKey) return false if (normalized.alt !== event.altKey) return false return true } /** TipTap key string, e.g. Mod-Shift-h */ export function docsShortcutBindingToTipTapKey(binding: DocsShortcutBinding): string { const normalized = normalizeDocsShortcutBinding(binding) const parts: string[] = [] if (normalized.mod) parts.push("Mod") if (normalized.shift) parts.push("Shift") if (normalized.alt) parts.push("Alt") parts.push( normalized.key.length === 1 ? normalized.key.toLowerCase() : normalized.key ) return parts.join("-") }