Files
20260512-skg-tk/web/components/video-lightbox.tsx

75 lines
2.7 KiB
TypeScript

"use client"
import { useEffect, useRef, useState } from "react"
import { X, Plus, Loader2 } from "lucide-react"
import { videoUrl } from "@/lib/api"
interface Props {
jobId: string | null
open: boolean
onClose: () => void
onAddFrame: (t: number) => Promise<void>
}
export function VideoLightbox({ jobId, open, onClose, onAddFrame }: Props) {
const videoRef = useRef<HTMLVideoElement>(null)
const [currentT, setCurrentT] = useState(0)
const [adding, setAdding] = useState(false)
useEffect(() => {
if (!open) return
const onKey = (e: KeyboardEvent) => {
if (e.key === "Escape") onClose()
}
window.addEventListener("keydown", onKey)
return () => window.removeEventListener("keydown", onKey)
}, [open, onClose])
if (!open || !jobId) return null
return (
<div
className="fixed inset-0 z-[100] bg-black/85 backdrop-blur-sm flex items-center justify-center"
onClick={onClose}
>
<button
onClick={(e) => { e.stopPropagation(); onClose() }}
className="absolute top-5 right-5 h-10 w-10 rounded-full bg-white/10 hover:bg-white/20 text-white flex items-center justify-center"
aria-label="关闭"
>
<X className="h-5 w-5" />
</button>
<div onClick={(e) => e.stopPropagation()} className="flex flex-col items-center gap-4 max-w-[92vw] max-h-[92vh]">
<video
ref={videoRef}
src={videoUrl(jobId)}
controls
autoPlay
playsInline
preload="auto"
onTimeUpdate={(e) => setCurrentT((e.target as HTMLVideoElement).currentTime)}
className="max-w-[88vw] max-h-[72vh] rounded-xl shadow-2xl bg-black"
/>
<div className="flex items-center gap-4 text-white">
<div className="font-mono text-sm tabular-nums text-white/80">
{currentT.toFixed(2)}s
</div>
<button
disabled={adding}
onClick={async () => {
const t = videoRef.current?.currentTime ?? currentT
setAdding(true)
try { await onAddFrame(t) } finally { setAdding(false) }
}}
className="px-5 py-2 rounded-lg text-sm font-medium inline-flex items-center gap-2 bg-emerald-500 hover:bg-emerald-400 text-white disabled:opacity-50 transition"
>
{adding ? <Loader2 className="h-4 w-4 animate-spin" /> : <Plus className="h-4 w-4" />}
{adding ? "抽帧中…" : `+ 把 ${currentT.toFixed(1)}s 加为关键帧`}
</button>
</div>
<div className="text-[11px] text-white/40 font-mono"> · + · ESC </div>
</div>
</div>
)
}