diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index fc65d04cf..ca7745849 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -292,10 +292,12 @@ function VideoPreview({ onTimeUpdate, }: VideoPreviewProps) { const playerRef = useRef(null); + const sliderRef = useRef(null); // keep track of playback state const [progress, setProgress] = useState(0); + const [hoverTimeout, setHoverTimeout] = useState(); const playerStartTime = useMemo(() => { if (!relevantPreview) { return 0; @@ -456,6 +458,26 @@ function VideoPreview({ }, 500); }, [playerRef, setIgnoreClick]); + const onProgressHover = useCallback( + (event: React.MouseEvent) => { + if (!sliderRef.current) { + return; + } + + const rect = sliderRef.current.getBoundingClientRect(); + const positionX = event.clientX - rect.left; + const width = sliderRef.current.clientWidth; + onManualSeek([Math.round((positionX / width) * 100)]); + + if (hoverTimeout) { + clearTimeout(hoverTimeout); + } + + setHoverTimeout(setTimeout(() => onStopManualSeek(), 500)); + }, + [sliderRef, hoverTimeout, onManualSeek, onStopManualSeek, setHoverTimeout], + ); + return (
); @@ -498,12 +522,14 @@ function InProgressPreview({ onTimeUpdate, }: InProgressPreviewProps) { const apiHost = useApiHost(); + const sliderRef = useRef(null); const { data: previewFrames } = useSWR( `preview/${review.camera}/start/${Math.floor(review.start_time) - PREVIEW_PADDING}/end/${ Math.ceil(review.end_time) + PREVIEW_PADDING }/frames`, ); const [manualFrame, setManualFrame] = useState(false); + const [hoverTimeout, setHoverTimeout] = useState(); const [key, setKey] = useState(0); const handleLoad = useCallback(() => { @@ -575,6 +601,34 @@ function InProgressPreview({ [setManualFrame, setIgnoreClick], ); + const onProgressHover = useCallback( + (event: React.MouseEvent) => { + if (!sliderRef.current || !previewFrames) { + return; + } + + const rect = sliderRef.current.getBoundingClientRect(); + const positionX = event.clientX - rect.left; + const width = sliderRef.current.clientWidth; + const progress = [Math.round((positionX / width) * previewFrames.length)]; + onManualSeek(progress); + + if (hoverTimeout) { + clearTimeout(hoverTimeout); + } + + setHoverTimeout(setTimeout(() => onStopManualSeek(progress), 500)); + }, + [ + sliderRef, + hoverTimeout, + previewFrames, + onManualSeek, + onStopManualSeek, + setHoverTimeout, + ], + ); + if (!previewFrames || previewFrames.length == 0) { return ( );