| 'use client' |
|
|
| import { useEffect, useMemo } from 'react' |
|
|
| import { redoOp, selectAllTextNodesOnCurrentPage, undoOp } from '@/lib/io/scene' |
| import { getPlatform, formatShortcut, isModifierKey } from '@/lib/shortcutUtils' |
| import { useEditorUiStore } from '@/lib/stores/editorUiStore' |
| import { usePreferencesStore } from '@/lib/stores/preferencesStore' |
|
|
| export function useKeyboardShortcuts() { |
| const setMode = useEditorUiStore((state) => state.setMode) |
| const setBrushConfig = usePreferencesStore((state) => state.setBrushConfig) |
| const shortcuts = usePreferencesStore((state) => state.shortcuts) |
| const isMac = useMemo(() => getPlatform() === 'mac', []) |
|
|
| |
| const TOOL_MAP = useMemo( |
| (): Record<string, import('@/lib/types').ToolMode> => ({ |
| [shortcuts.select]: 'select', |
| [shortcuts.block]: 'block', |
| [shortcuts.brush]: 'brush', |
| [shortcuts.eraser]: 'eraser', |
| [shortcuts.repairBrush]: 'repairBrush', |
| }), |
| [shortcuts], |
| ) |
|
|
| useEffect(() => { |
| const handleKeyDown = (event: KeyboardEvent) => { |
| const target = event.target |
| const inTextField = |
| target instanceof HTMLElement && |
| (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) |
|
|
| |
| |
| |
| const shortcut = formatShortcut(event, isMac) |
| const mod = isMac ? event.metaKey : event.ctrlKey |
|
|
| if (shortcut === shortcuts.undo) { |
| event.preventDefault() |
| void undoOp() |
| return |
| } |
|
|
| if (shortcut === shortcuts.redo) { |
| event.preventDefault() |
| void redoOp() |
| return |
| } |
|
|
| |
| if (mod && (event.key === 'y' || event.key === 'Y')) { |
| event.preventDefault() |
| void redoOp() |
| return |
| } |
|
|
| |
| |
| if (mod && (event.key === 'a' || event.key === 'A') && !inTextField) { |
| event.preventDefault() |
| selectAllTextNodesOnCurrentPage() |
| return |
| } |
|
|
| |
| if (inTextField) return |
|
|
| |
| if (isModifierKey(event.key)) { |
| return |
| } |
|
|
| |
| const matchingTool = shortcut ? TOOL_MAP[shortcut] : undefined |
| if (matchingTool) { |
| setMode(matchingTool) |
| return |
| } |
|
|
| |
| if (shortcut === shortcuts.increaseBrushSize) { |
| const currentSize = usePreferencesStore.getState().brushConfig.size |
| setBrushConfig({ size: Math.min(128, currentSize + 4) }) |
| } else if (shortcut === shortcuts.decreaseBrushSize) { |
| const currentSize = usePreferencesStore.getState().brushConfig.size |
| setBrushConfig({ size: Math.max(8, currentSize - 4) }) |
| } |
| } |
|
|
| window.addEventListener('keydown', handleKeyDown) |
| return () => window.removeEventListener('keydown', handleKeyDown) |
| |
| }, [isMac, setMode, TOOL_MAP, shortcuts]) |
| } |
|
|