import { useEffect, useRef, useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { useTranslation } from "react-i18next"; import { Play, X } from "lucide-react"; import { api } from "../lib/api"; import { plexLang } from "../i18n"; import { qk } from "../lib/queryKeys"; import { Button } from "./ui/Button"; import { IconButton } from "./ui/IconButton"; // Up-next / end-card (E6 S4). Shown at episode end when a next item exists and the pref is on, INSTEAD // of the old instant jump — so binge stays under the viewer's control (D6-A). Counts down ~10s then // advances; "Play now" advances immediately; Cancel/✕ dismisses and stays on the finished frame. It only // lives on the play-to-the-end path; credits-auto-skip advances earlier and never reaches this card. const COUNTDOWN_S = 10; export function UpNextCard({ nextId, onAdvance, onCancel, }: { nextId: string; onAdvance: () => void; onCancel: () => void; }) { const { t } = useTranslation(); const lang = plexLang(); const nextQ = useQuery({ queryKey: qk.plexItem(nextId, lang), queryFn: () => api.plexItem(nextId, lang), }); const next = nextQ.data; // Countdown. `onAdvance` is read through a ref so the 100ms interval never restarts on re-render. const [remaining, setRemaining] = useState(COUNTDOWN_S); const advanceRef = useRef(onAdvance); advanceRef.current = onAdvance; useEffect(() => { const started = performance.now(); const iv = window.setInterval(() => { const left = COUNTDOWN_S - (performance.now() - started) / 1000; if (left <= 0) { window.clearInterval(iv); setRemaining(0); advanceRef.current(); } else { setRemaining(left); } }, 100); return () => window.clearInterval(iv); }, []); const secs = Math.ceil(remaining); const frac = remaining / COUNTDOWN_S; // 1 → 0 as it counts down const R = 10; const C = 2 * Math.PI * R; // Title: "Show · S2·E5" over the episode title for episodes; the plain title for movies/queue items. const heading = next?.kind === "episode" && next.show_title ? `${next.show_title} · S${next.season_number ?? "?"}·E${next.episode_number ?? "?"}` : (next?.title ?? ""); const sub = next?.kind === "episode" ? next.title : null; return (