64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
import { useEffect } from "react";
|
||
import { REACTION_EMOJIS } from "@/api/types";
|
||
import { selectIsPaused, usePlaybackPauseStore } from "@/stores/playback-pause-store";
|
||
import { isTypingTarget } from "@/lib/keyboard";
|
||
|
||
interface UseStreamActionKeysOptions {
|
||
onToggleReaction: (emoji: string) => void;
|
||
onOpenHuddle: () => void;
|
||
onToggleRecordingMode: () => void;
|
||
onToggleKeybindings: () => void;
|
||
onOpenTextReaction: () => void;
|
||
}
|
||
|
||
/**
|
||
* Reactions 1–7, `r` quick text reply, `h` huddle, `v` toggle recording mode,
|
||
* `?` toggle keybindings overlay. Skipped while playback is paused for any reason.
|
||
*/
|
||
export function useStreamActionKeys({
|
||
onToggleReaction,
|
||
onOpenHuddle,
|
||
onToggleRecordingMode,
|
||
onToggleKeybindings,
|
||
onOpenTextReaction,
|
||
}: UseStreamActionKeysOptions) {
|
||
useEffect(() => {
|
||
const onKeyDown = (e: KeyboardEvent) => {
|
||
if (isTypingTarget(e)) return;
|
||
if (selectIsPaused(usePlaybackPauseStore.getState())) return;
|
||
|
||
switch (e.key) {
|
||
case "h":
|
||
e.preventDefault();
|
||
onOpenHuddle();
|
||
break;
|
||
case "v":
|
||
e.preventDefault();
|
||
onToggleRecordingMode();
|
||
break;
|
||
case "r":
|
||
e.preventDefault();
|
||
onOpenTextReaction();
|
||
break;
|
||
case "?":
|
||
e.preventDefault();
|
||
onToggleKeybindings();
|
||
break;
|
||
case "1":
|
||
case "2":
|
||
case "3":
|
||
case "4":
|
||
case "5":
|
||
case "6":
|
||
case "7":
|
||
e.preventDefault();
|
||
onToggleReaction(REACTION_EMOJIS[parseInt(e.key) - 1]);
|
||
break;
|
||
}
|
||
};
|
||
|
||
window.addEventListener("keydown", onKeyDown);
|
||
return () => window.removeEventListener("keydown", onKeyDown);
|
||
}, [onToggleReaction, onOpenHuddle, onToggleRecordingMode, onToggleKeybindings, onOpenTextReaction]);
|
||
}
|