auto-commit for df4b0748-985b-4592-8c48-1e56102f3613

This commit is contained in:
emergent-agent-e1
2026-04-29 14:49:07 +00:00
parent 7673090279
commit 356aa13063
30 changed files with 2809 additions and 244 deletions
+80
View File
@@ -0,0 +1,80 @@
import { useEffect, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import api, { getStreamUrl } from "../lib/api";
import { ArrowLeft } from "lucide-react";
export default function Player() {
const { id } = useParams();
const nav = useNavigate();
const [movie, setMovie] = useState(null);
const videoRef = useRef(null);
const lastSent = useRef(0);
useEffect(() => {
let cancelled = false;
(async () => {
const { data } = await api.get(`/movies/${id}`);
if (cancelled) return;
setMovie(data);
// Restore progress
try {
const { data: p } = await api.get(`/progress/${id}`);
if (videoRef.current && p?.position_seconds) {
videoRef.current.currentTime = p.position_seconds;
}
} catch {}
})();
return () => { cancelled = true; };
}, [id]);
const onTimeUpdate = () => {
const v = videoRef.current;
if (!v || !v.duration) return;
const now = Date.now();
if (now - lastSent.current < 5000) return;
lastSent.current = now;
api.post("/progress", {
movie_id: id,
position_seconds: v.currentTime,
duration_seconds: v.duration,
}).catch(() => {});
};
if (!movie) {
return (
<div className="min-h-screen bg-black flex items-center justify-center text-[#8A8A8A]" data-testid="player-loading">
Loading
</div>
);
}
return (
<div className="fixed inset-0 bg-black z-50 flex flex-col" data-testid="player-page">
<button
onClick={() => nav(-1)}
className="absolute top-6 left-6 z-10 flex items-center gap-2 text-white/80 hover:text-white bg-black/60 hover:bg-black px-4 py-2 transition-colors duration-300"
data-testid="player-back-button"
>
<ArrowLeft size={16} strokeWidth={1.5} />
<span className="text-xs uppercase tracking-[0.2em]">Back</span>
</button>
<div className="absolute top-6 right-6 z-10 text-right">
<h2 className="font-display text-xl text-white tracking-tight" data-testid="player-title">
{movie.title}
</h2>
<p className="text-[10px] uppercase tracking-[0.3em] text-[#8A8A8A]">{movie.year} · {movie.rating}</p>
</div>
<video
ref={videoRef}
src={getStreamUrl(movie)}
controls
autoPlay
className="w-full h-full object-contain bg-black"
onTimeUpdate={onTimeUpdate}
data-testid="player-video"
/>
</div>
);
}