mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-12 23:33:43 +08:00
125 lines
3.8 KiB
TypeScript
125 lines
3.8 KiB
TypeScript
import { useEffect } from 'react';
|
|
|
|
interface UseDesktopShortcutsProps {
|
|
videoRef: React.RefObject<HTMLVideoElement | null>;
|
|
isPlaying: boolean;
|
|
volume: number;
|
|
isPiPSupported: boolean;
|
|
togglePlay: () => void;
|
|
toggleMute: () => void;
|
|
toggleFullscreen: () => void;
|
|
togglePictureInPicture: () => void;
|
|
skipForward: () => void;
|
|
skipBackward: () => void;
|
|
showVolumeBarTemporarily: () => void;
|
|
setShowControls: (show: boolean) => void;
|
|
setVolume: (volume: number) => void;
|
|
setIsMuted: (muted: boolean) => void;
|
|
controlsTimeoutRef: React.MutableRefObject<NodeJS.Timeout | null>;
|
|
}
|
|
|
|
export function useDesktopShortcuts({
|
|
videoRef,
|
|
isPlaying,
|
|
volume,
|
|
isPiPSupported,
|
|
togglePlay,
|
|
toggleMute,
|
|
toggleFullscreen,
|
|
togglePictureInPicture,
|
|
skipForward,
|
|
skipBackward,
|
|
showVolumeBarTemporarily,
|
|
setShowControls,
|
|
setVolume,
|
|
setIsMuted,
|
|
controlsTimeoutRef,
|
|
}: UseDesktopShortcutsProps) {
|
|
useEffect(() => {
|
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
// Ignore shortcuts if typing in an input
|
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
|
|
return;
|
|
}
|
|
|
|
// Show controls on any key press
|
|
setShowControls(true);
|
|
if (controlsTimeoutRef.current) {
|
|
clearTimeout(controlsTimeoutRef.current);
|
|
}
|
|
if (isPlaying) {
|
|
controlsTimeoutRef.current = setTimeout(() => {
|
|
setShowControls(false);
|
|
}, 3000);
|
|
}
|
|
|
|
switch (e.key.toLowerCase()) {
|
|
case ' ':
|
|
case 'k':
|
|
e.preventDefault();
|
|
togglePlay();
|
|
break;
|
|
case 'f':
|
|
e.preventDefault();
|
|
toggleFullscreen();
|
|
break;
|
|
case 'm':
|
|
e.preventDefault();
|
|
toggleMute();
|
|
break;
|
|
case 'p':
|
|
if (isPiPSupported) {
|
|
e.preventDefault();
|
|
togglePictureInPicture();
|
|
}
|
|
break;
|
|
case 'arrowright':
|
|
case 'l':
|
|
e.preventDefault();
|
|
skipForward();
|
|
break;
|
|
case 'arrowleft':
|
|
case 'j':
|
|
e.preventDefault();
|
|
skipBackward();
|
|
break;
|
|
case 'arrowup':
|
|
e.preventDefault();
|
|
const newVolUp = Math.min(1, volume + 0.1);
|
|
setVolume(newVolUp);
|
|
if (videoRef.current) videoRef.current.volume = newVolUp;
|
|
setIsMuted(newVolUp === 0);
|
|
showVolumeBarTemporarily();
|
|
break;
|
|
case 'arrowdown':
|
|
e.preventDefault();
|
|
const newVolDown = Math.max(0, volume - 0.1);
|
|
setVolume(newVolDown);
|
|
if (videoRef.current) videoRef.current.volume = newVolDown;
|
|
setIsMuted(newVolDown === 0);
|
|
showVolumeBarTemporarily();
|
|
break;
|
|
}
|
|
};
|
|
|
|
window.addEventListener('keydown', handleKeyDown);
|
|
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
}, [
|
|
videoRef,
|
|
isPlaying,
|
|
volume,
|
|
isPiPSupported,
|
|
togglePlay,
|
|
toggleMute,
|
|
toggleFullscreen,
|
|
togglePictureInPicture,
|
|
skipForward,
|
|
skipBackward,
|
|
showVolumeBarTemporarily,
|
|
setShowControls,
|
|
setVolume,
|
|
setIsMuted,
|
|
controlsTimeoutRef,
|
|
]);
|
|
}
|