mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-05-25 05:12:31 +00:00
67 lines
2.2 KiB
TypeScript
67 lines
2.2 KiB
TypeScript
import React, { createContext, useCallback, useContext, useEffect, useRef } from 'react';
|
|
import shortcuts from './shortcuts.json';
|
|
|
|
const SHORTCUTS = shortcuts.map(({ shortcuts }) => shortcuts).flat();
|
|
|
|
export type ShortcutName = string;
|
|
export type ShortcutListener = (combo: number) => void;
|
|
|
|
interface ShortcutsContext {
|
|
grouped: ShortcutGroup[],
|
|
on: (name: ShortcutName, listener: ShortcutListener) => void,
|
|
off: (name: ShortcutName, listener: ShortcutListener) => void,
|
|
}
|
|
|
|
const ShortcutsContext = createContext<ShortcutsContext>({} as ShortcutsContext);
|
|
|
|
type Props = {
|
|
children: JSX.Element,
|
|
onShortcut: (name: ShortcutName) => void,
|
|
};
|
|
|
|
const ShortcutsProvider = ({ children, onShortcut }: Props) => {
|
|
const listeners = useRef<Map<ShortcutName, Set<ShortcutListener>>>(new Map());
|
|
|
|
const onKeyDown = useCallback(({ ctrlKey, shiftKey, code, key }: KeyboardEvent) => {
|
|
SHORTCUTS.forEach(({ name, combos }) => combos.forEach((keys) => {
|
|
const modifers = (keys.includes('Ctrl') ? ctrlKey : true)
|
|
&& (keys.includes('Shift') ? shiftKey : true);
|
|
|
|
if (modifers && (keys.includes(code) || keys.includes(key.toUpperCase()))) {
|
|
const combo = combos.indexOf(keys);
|
|
listeners.current.get(name)?.forEach((listener) => listener(combo));
|
|
|
|
onShortcut(name as ShortcutName);
|
|
}
|
|
}));
|
|
}, [onShortcut]);
|
|
|
|
const on = (name: ShortcutName, listener: ShortcutListener) => {
|
|
!listeners.current.has(name) && listeners.current.set(name, new Set());
|
|
listeners.current.get(name)!.add(listener);
|
|
};
|
|
|
|
const off = (name: ShortcutName, listener: ShortcutListener) => {
|
|
listeners.current.get(name)?.delete(listener);
|
|
};
|
|
|
|
useEffect(() => {
|
|
document.addEventListener('keydown', onKeyDown);
|
|
return () => document.removeEventListener('keydown', onKeyDown);
|
|
}, [onKeyDown]);
|
|
|
|
return (
|
|
<ShortcutsContext.Provider value={{ grouped: shortcuts, on, off }}>
|
|
{children}
|
|
</ShortcutsContext.Provider>
|
|
);
|
|
};
|
|
|
|
const useShortcuts = () => {
|
|
return useContext(ShortcutsContext);
|
|
};
|
|
|
|
export {
|
|
ShortcutsProvider,
|
|
useShortcuts,
|
|
};
|