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?
)}
>
)
}