import { useRef, useState, useEffect, useCallback } from "react"; import { Play, Pause, SkipBack, Volume2, VolumeX, Maximize2, Minimize2, Settings, VideoIcon, Volume1, SkipForward, Gauge, X, RotateCcw, } from "lucide-react"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import { ChevronLeft, ChevronRight } from "lucide-react"; import api from "@/utils/api.util"; import { MediaFallback } from "@/components/generic/MediaFallback"; import { useMediaWatchGuard } from "@/hooks/useMediaWatchGuard"; import { formatPlayerTime as fmtTime } from "@/utils/format.util"; const PLAYBACK_SPEEDS = ["0.5", "0.75", "Normal", "1.25", "1.5", "2"]; const API_BASE = (import.meta.env.VITE_API_URL ?? "http://localhost:3024").replace(/\/$/, ""); // ─── Tooltip control button ─────────────────────────────────────────────────── function CtrlBtn({ label, onClick, children, className = "" }) { return ( {label} ); } // ─── Settings panel ─────────────────────────────────────────────────────────── function SettingsPanel({ speed, onSpeed, onClose }) { const [tab, setTab] = useState(null); const Row = ({ icon: Icon, label, value, onClick }) => ( ); const OptionList = ({ options, current, onSelect }) => (
{options.map((opt) => ( ))}
); return ( <>
e.stopPropagation()} > {tab === null && ( <>

Settings

setTab("speed")} />
)} {tab !== null && ( <>
)}
e.stopPropagation()} >
{tab === null && ( <>

Settings

setTab("speed")} />
)} {tab !== null && ( <>
{PLAYBACK_SPEEDS.map((opt) => ( ))}
)}
); } // ─── VideoBlock (Client — secure) ──────────────────────────────────────────── // // S3/Garage: // 1. POST /client/media/token → get JWT token // 2. fetch(streamUrl, { credentials: "include" }) → get raw bytes // 3. URL.createObjectURL(blob) → blob:http://... URL // 4.