import { createContext, useCallback, useContext, useEffect, useRef, useState, type PropsWithChildren, } from "react"; import { createPortal } from "react-dom"; import { X } from "lucide-react"; import type { Attachment } from "../../../types/post"; type PlayerState = { attachment: Attachment; currentTime: number; } | null; type Ctx = { openVideo: (attachment: Attachment, currentTime?: number) => void; closeVideo: () => void; }; const VideoPlayerContext = createContext(null); export function useVideoPlayer(): Ctx { const ctx = useContext(VideoPlayerContext); if (!ctx) throw new Error("useVideoPlayer must be used inside VideoPlayerProvider"); return ctx; } export function VideoPlayerProvider({ children }: PropsWithChildren) { const [state, setState] = useState(null); const openVideo = useCallback( (attachment: Attachment, currentTime = 0) => setState({ attachment, currentTime }), [], ); const closeVideo = useCallback(() => setState(null), []); return ( {children} {state ? ( ) : null} ); } function PlayerView({ attachment, startAt, onClose, }: { attachment: Attachment; startAt: number; onClose: () => void; }) { const videoRef = useRef(null); useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; window.addEventListener("keydown", onKey); const prevOverflow = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { window.removeEventListener("keydown", onKey); document.body.style.overflow = prevOverflow; }; }, [onClose]); useEffect(() => { const v = videoRef.current; if (!v) return; if (startAt > 0) v.currentTime = startAt; v.play().catch(() => {}); }, [startAt]); return createPortal(
, document.body, ); }