import { useVideoPlayerDescriptor } from "@/video/state/hooks"; import { useControls } from "@/video/state/logic/controls"; import { useInterface } from "@/video/state/logic/interface"; import { useMediaPlaying } from "@/video/state/logic/mediaplaying"; import React, { useCallback, useEffect, useRef, useState } from "react"; interface BackdropActionProps { children?: React.ReactNode; onBackdropChange?: (showing: boolean) => void; } export function BackdropAction(props: BackdropActionProps) { const descriptor = useVideoPlayerDescriptor(); const controls = useControls(descriptor); const mediaPlaying = useMediaPlaying(descriptor); const videoInterface = useInterface(descriptor); const [moved, setMoved] = useState(false); const timeout = useRef | null>(null); const clickareaRef = useRef(null); const handleMouseMove = useCallback(() => { if (!moved) setMoved(true); if (timeout.current) clearTimeout(timeout.current); timeout.current = setTimeout(() => { if (moved) setMoved(false); timeout.current = null; }, 3000); }, [setMoved, moved]); const handleMouseLeave = useCallback(() => { setMoved(false); }, [setMoved]); const [lastTouchEnd, setLastTouchEnd] = useState(0); const handleClick = useCallback( ( e: React.MouseEvent | React.TouchEvent ) => { if (!clickareaRef.current || clickareaRef.current !== e.target) return; if (videoInterface.popout !== null) return; if ((e as React.TouchEvent).type === "touchend") { setLastTouchEnd(Date.now()); return; } if ((e as React.MouseEvent).button !== 0) { return; // not main button (left click), exit event } setTimeout(() => { if (Date.now() - lastTouchEnd < 200) { setMoved(!moved); return; } if (mediaPlaying.isPlaying) controls.pause(); else controls.play(); }, 20); }, [controls, mediaPlaying, videoInterface, lastTouchEnd, moved] ); const handleDoubleClick = useCallback( (e: React.MouseEvent) => { if (!clickareaRef.current || clickareaRef.current !== e.target) return; if (!videoInterface.isFullscreen) controls.enterFullscreen(); else controls.exitFullscreen(); }, [controls, videoInterface] ); const lastBackdropValue = useRef(null); useEffect(() => { const currentValue = moved || mediaPlaying.isPaused || !!videoInterface.popout; if (currentValue !== lastBackdropValue.current) { lastBackdropValue.current = currentValue; props.onBackdropChange?.(currentValue); } }, [moved, mediaPlaying, props, videoInterface]); const showUI = moved || mediaPlaying.isPaused || !!videoInterface.popout; return (
{props.children}
); }