import { motion, AnimatePresence } from 'framer-motion' import UpNext from './UpNext' import ResumePrompt from './ResumePrompt' import RecapCard from './RecapCard' import ChaptersPanel from './ChaptersPanel' import BookmarksPanel from './BookmarksPanel' import EndOfVideoCard from './EndOfVideoCard' import KeyboardHints from './KeyboardHints' import SubtitleSearchPanel from './SubtitleSearchPanel' import SyncPlayPanel from './SyncPlayPanel' import type { BaseItemDto } from '../../api/types' export interface ChapterMarker { StartPositionTicks?: number | null Name?: string | null ImageTag?: string | null } interface UpNextProps { item: BaseItemDto | null visible: boolean countdown: number onSkip: () => void onDismiss: () => void } interface ResumeProps { open: boolean positionTicks: number lastPlayedDate?: string | null onResume: () => void onRestart: () => void } interface RecapProps { open: boolean previousEpisodes: BaseItemDto[] daysSinceLastWatch: number | null onDismiss: () => void } interface ChaptersProps { open: boolean itemId: string chapters: ChapterMarker[] serverUrl: string currentTime: number onClose: () => void onJump: (t: number) => void } interface BookmarksProps { open: boolean itemId: string currentTime: number refreshKey: number onClose: () => void onAdd: () => void onJump: (t: number) => void } interface EndCardProps { open: boolean hasEpisodes: boolean item: BaseItemDto | null | undefined nextItem?: BaseItemDto | null | undefined onReplay: () => void onEpisodes: () => void onBack: () => void onPlayNext?: () => void } interface SkipPromptProps { seriesId: string | null onAccept: () => void onNotNow: () => void onDismiss: () => void } interface HintsProps { open: boolean onClose: () => void } interface SubSearchProps { open: boolean subtitleUrl: string | null onClose: () => void onJump: (t: number) => void } interface SyncPlayProps { open: boolean onClose: () => void currentItemId: string | null currentPositionTicks: number } interface Props { upNext: UpNextProps resume: ResumeProps recap: RecapProps chapters: ChaptersProps | null bookmarks: BookmarksProps | null endCard: EndCardProps nextItem?: BaseItemDto | null onPlayNext?: () => void skipPrompt: SkipPromptProps hints: HintsProps subSearch: SubSearchProps syncPlay: SyncPlayProps } /** * All the modal / panel / card overlays that float above the video. Kept in * one component so PlayerPage doesn't have to render 9 sibling overlays * inline. State lives in PlayerPage; this is pure presentation. */ export default function PlayerOverlays({ upNext, resume, recap, chapters, bookmarks, endCard, nextItem, onPlayNext, skipPrompt, hints, subSearch, syncPlay, }: Props) { return ( <> {chapters && ( )} {bookmarks && ( )} {/* Smart skip prompt - third manual skip on the same series triggers a one-shot offer to auto-skip from now on. */} {skipPrompt.seriesId && ( Auto-skip intros on this show? )} ) }