Files
OpenCut/apps/web/src/hooks/use-keybindings.ts
T

76 lines
2.2 KiB
TypeScript
Raw Normal View History

import { useEffect } from "react";
2026-01-31 00:20:04 +01:00
import { invokeAction } from "@/lib/actions";
import { useKeybindingsStore } from "@/stores/keybindings-store";
/**
2026-01-31 00:20:04 +01:00
* a composable that hooks to the caller component's
* lifecycle and hooks to the keyboard events to fire
* the appropriate actions based on keybindings
*/
export function useKeybindingsListener() {
2026-01-31 00:20:04 +01:00
const { keybindings, getKeybindingString, keybindingsEnabled, isRecording } =
useKeybindingsStore();
2026-01-31 00:20:04 +01:00
useEffect(() => {
const eventOptions: AddEventListenerOptions = { capture: true };
const handleKeyDown = (ev: KeyboardEvent) => {
// do not check keybinds if the mode is disabled
if (!keybindingsEnabled) return;
// ignore key events if user is changing keybindings
if (isRecording) return;
2026-01-31 00:20:04 +01:00
const binding = getKeybindingString(ev);
if (!binding) return;
2026-01-31 00:20:04 +01:00
const boundAction = keybindings[binding];
if (!boundAction) return;
2026-01-31 00:20:04 +01:00
const activeElement = document.activeElement;
const isTextInput =
activeElement &&
(activeElement.tagName === "INPUT" ||
activeElement.tagName === "TEXTAREA" ||
(activeElement as HTMLElement).isContentEditable);
2026-01-31 00:20:04 +01:00
if (isTextInput) return;
2026-01-31 00:20:04 +01:00
ev.preventDefault();
2026-01-31 00:20:04 +01:00
switch (boundAction) {
case "seek-forward":
invokeAction("seek-forward", { seconds: 1 }, "keypress");
break;
case "seek-backward":
invokeAction("seek-backward", { seconds: 1 }, "keypress");
break;
case "jump-forward":
invokeAction("jump-forward", { seconds: 5 }, "keypress");
break;
case "jump-backward":
invokeAction("jump-backward", { seconds: 5 }, "keypress");
break;
default:
invokeAction(boundAction, undefined, "keypress");
}
};
2026-01-31 00:20:04 +01:00
document.addEventListener("keydown", handleKeyDown, eventOptions);
2026-01-31 00:20:04 +01:00
return () => {
document.removeEventListener("keydown", handleKeyDown, eventOptions);
};
}, [keybindings, getKeybindingString, keybindingsEnabled, isRecording]);
}
/**
2026-01-31 00:20:04 +01:00
* this composable allows for the UI component to be disabled if the component in question is mounted
*/
export function useKeybindingDisabler() {
2026-01-31 00:20:04 +01:00
const { disableKeybindings, enableKeybindings } = useKeybindingsStore();
2026-01-31 00:20:04 +01:00
return {
disableKeybindings,
enableKeybindings,
};
}