File size: 1,727 Bytes
			
			| 8486d85 e5ed23c 8486d85 e5ed23c 8486d85 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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 => {
      const { key, ctrlKey, shiftKey, altKey, metaKey } = event;
      for (const name in shortcuts) {
        const shortcut = shortcuts[name as keyof Shortcuts];
        if (
          shortcut.key.toLowerCase() === key.toLowerCase() &&
          (shortcut.ctrlOrMetaKey
            ? ctrlKey || metaKey
            : (shortcut.ctrlKey === undefined || shortcut.ctrlKey === ctrlKey) &&
              (shortcut.metaKey === undefined || shortcut.metaKey === metaKey)) &&
          (shortcut.shiftKey === undefined || shortcut.shiftKey === shiftKey) &&
          (shortcut.altKey === undefined || shortcut.altKey === altKey)
        ) {
          shortcutEventEmitter.dispatch(name as keyof Shortcuts);
          event.preventDefault();
          event.stopPropagation();
          shortcut.action();
          break;
        }
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, [shortcuts]);
}
 | 
