|
import { useStore } from '@nanostores/react'; |
|
import { useEffect } from 'react'; |
|
import { shortcutsStore, type Shortcuts } from '~/lib/stores/settings'; |
|
|
|
class ShortcutEventEmitter { |
|
#emitter = new EventTarget(); |
|
|
|
dispatch(type: keyof Shortcuts) { |
|
this.#emitter.dispatchEvent(new Event(type)); |
|
} |
|
|
|
on(type: keyof Shortcuts, cb: VoidFunction) { |
|
this.#emitter.addEventListener(type, cb); |
|
|
|
return () => { |
|
this.#emitter.removeEventListener(type, cb); |
|
}; |
|
} |
|
} |
|
|
|
export const shortcutEventEmitter = new ShortcutEventEmitter(); |
|
|
|
export function useShortcuts(): void { |
|
const shortcuts = useStore(shortcutsStore); |
|
|
|
useEffect(() => { |
|
const handleKeyDown = (event: KeyboardEvent): void => { |
|
|
|
console.log('Key pressed:', { |
|
key: event.key, |
|
code: event.code, |
|
ctrlKey: event.ctrlKey, |
|
shiftKey: event.shiftKey, |
|
altKey: event.altKey, |
|
metaKey: event.metaKey, |
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if ( |
|
event.code === 'KeyD' && |
|
event.metaKey && |
|
event.altKey && |
|
event.shiftKey && |
|
!event.ctrlKey |
|
) { |
|
event.preventDefault(); |
|
event.stopPropagation(); |
|
shortcuts.toggleTheme.action(); |
|
|
|
return; |
|
} |
|
|
|
|
|
for (const name in shortcuts) { |
|
const shortcut = shortcuts[name as keyof Shortcuts]; |
|
|
|
if (name === 'toggleTheme') { |
|
continue; |
|
} |
|
|
|
|
|
const keyMatches = |
|
shortcut.key.toLowerCase() === event.key.toLowerCase() || `Key${shortcut.key.toUpperCase()}` === event.code; |
|
|
|
const modifiersMatch = |
|
(shortcut.ctrlKey === undefined || shortcut.ctrlKey === event.ctrlKey) && |
|
(shortcut.metaKey === undefined || shortcut.metaKey === event.metaKey) && |
|
(shortcut.shiftKey === undefined || shortcut.shiftKey === event.shiftKey) && |
|
(shortcut.altKey === undefined || shortcut.altKey === event.altKey); |
|
|
|
if (keyMatches && modifiersMatch) { |
|
event.preventDefault(); |
|
event.stopPropagation(); |
|
shortcutEventEmitter.dispatch(name as keyof Shortcuts); |
|
shortcut.action(); |
|
break; |
|
} |
|
} |
|
}; |
|
|
|
window.addEventListener('keydown', handleKeyDown); |
|
|
|
return () => { |
|
window.removeEventListener('keydown', handleKeyDown); |
|
}; |
|
}, [shortcuts]); |
|
} |
|
|