diff --git a/src/stories/dropdowns/autocomplete/index.stories.tsx b/src/stories/dropdowns/autocomplete/index.stories.tsx index d3f9a05d..ab8a1e9d 100644 --- a/src/stories/dropdowns/autocomplete/index.stories.tsx +++ b/src/stories/dropdowns/autocomplete/index.stories.tsx @@ -51,9 +51,6 @@ const TemplateCreatable: Story = (args) => { }, 1000) ); }} - onOptionClick={({ selectionValue }) => { - console.log("Option clicked", selectionValue); - }} /> ); diff --git a/src/stories/dropdowns/autocomplete/index.tsx b/src/stories/dropdowns/autocomplete/index.tsx index b69aecd5..497df216 100644 --- a/src/stories/dropdowns/autocomplete/index.tsx +++ b/src/stories/dropdowns/autocomplete/index.tsx @@ -125,8 +125,9 @@ const Autocomplete = ({ onInputChange(sanitizedInputValue); } if ( - event.type === "option:click" && - typeof onOptionClick === "function" + (event.type === "option:click" || event.type === "input:keyDown:Enter") + && typeof onOptionClick === "function" + && event.selectionValue // address the issue of clicking enter on an empty input ) { setInputValue(undefined); onOptionClick({ diff --git a/src/stories/multiselect/index.tsx b/src/stories/multiselect/index.tsx index 8215655e..b75b02ef 100644 --- a/src/stories/multiselect/index.tsx +++ b/src/stories/multiselect/index.tsx @@ -76,7 +76,7 @@ export const MultiSelect = ({ } if ( onChange && - (type === "fn:setSelectionValue" || type === "option:click") && + (type === "fn:setSelectionValue" || type === "option:click" || type === "input:keyDown:Enter") && Array.isArray(selectionValue) ) { const ss = selectionValue.map((s) => { diff --git a/src/stories/player/hooks/useKeyboardCommands.ts b/src/stories/player/hooks/useKeyboardCommands.ts new file mode 100644 index 00000000..b0922f83 --- /dev/null +++ b/src/stories/player/hooks/useKeyboardCommands.ts @@ -0,0 +1,49 @@ +import { useVideoContext } from "@appquality/stream-player"; +import { useEffect } from "react"; + +type KeyboardCommandsHook = ( + setIsPlaying: (isPlaying: boolean) => void, + onCutHandler?: (time: number) => void, + videoRef?: HTMLVideoElement | null, +) => void; + +export const useKeyboardCommands: KeyboardCommandsHook = (setIsPlaying, onCutHandler, videoRef) => { + useEffect(() => { + function handleKeyDown(e: KeyboardEvent) { + // console.log("handleKeyDown", e.code, document.activeElement, e.target); + if (document.activeElement?.tagName === "INPUT") return; + if (document.activeElement?.tagName === "TEXTAREA") return; + + if (!videoRef) return; + + if (e.code === "Space") { + e.preventDefault(); + if (videoRef.paused) { + setIsPlaying(true); + videoRef.play(); + } else { + setIsPlaying(false); + videoRef.pause(); + } + } + if (e.code === "ArrowLeft") { + videoRef.currentTime -= 10; + } + if (e.code === "ArrowRight") { + videoRef.currentTime += 10; + } + if (e.code === "KeyM") { + videoRef.muted = !videoRef.muted; + videoRef.volume = videoRef.muted ? 0 : 1; + } + if (e.code === "KeyS") { + onCutHandler?.(videoRef.currentTime); + e.stopPropagation(); + } + } + document.addEventListener("keydown", handleKeyDown); + return () => { + document.removeEventListener("keydown", handleKeyDown); + } + }, [videoRef, onCutHandler]); +} \ No newline at end of file diff --git a/src/stories/player/index.tsx b/src/stories/player/index.tsx index ed0c5042..cfff8d91 100644 --- a/src/stories/player/index.tsx +++ b/src/stories/player/index.tsx @@ -13,6 +13,7 @@ import { FloatingControls } from "./parts/floatingControls"; import { VideoSpinner } from "./parts/spinner"; import { ProgressContextProvider } from "./context/progressContext"; import { usePictureInPicture } from "./hooks/usePictureInPicture"; +import { useKeyboardCommands } from "./hooks/useKeyboardCommands"; /** * The Player is a styled media tag with custom controls @@ -38,6 +39,7 @@ const PlayerCore = forwardRef( videoRef, ]); + useKeyboardCommands(setIsPlaying, onCutHandler, videoRef); usePictureInPicture(videoRef, pipMode, onPipChange); useEffect(() => {