Overview
Film Fanatic provides granular episode-level tracking for TV shows, allowing users to mark individual episodes as watched, track viewing progress, and automatically update show completion status.Episode Browser Interface
Location:src/components/media/inline-episode-browser.tsx
The episode browser appears on TV show detail pages and provides:
Season Accordion
- Collapsible season sections
- Season metadata (episode count, air year)
- Watch completion indicators
- Batch mark all/unmark all buttons
Episode Cards
- Episode thumbnail stills
- Title and air date
- Episode ratings
- Watch status toggle
- Progress percentage
- Expandable descriptions
Season Display
Season Accordion
Each season is displayed as an accordion item with:- Season Header
- Season Actions
- Season Number - “Season 1”, “Season 2”, etc.
- Episode Count - Badge showing total episodes
- Air Year - First air date year
- Completion Badge - “Seen” indicator if all episodes watched
- Progress Counter - “X/Y watched” for partial completion
Special Seasons
Seasons are organized with main seasons first, then specials:- Main Seasons - Season 1, 2, 3, … (season_number > 0)
- Specials - Season 0 (bonus content, behind-the-scenes)
src/components/media/inline-episode-browser.tsx:52-55
Progressive Disclosure
To avoid overwhelming users:- First 3 seasons shown by default
- “View all X seasons” button if more than 3 exist
- Clicking reveals all remaining seasons
src/components/media/inline-episode-browser.tsx:57-59
Episode Cards
Episode Information Display
Visual
- Episode still/thumbnail
- Hover play overlay
- Fallback for missing images
Metadata
- Episode number (E01, E02…)
- Episode title
- Air date
- Runtime (if available)
- Rating (TMDB score)
Status
- Watch status badge
- Progress percentage
- Quick toggle button
Episode Description
Expandable Overviews
Expandable Overviews
Long episode descriptions are truncated to 120 characters with a “Read more” button.Implementation:
src/components/media/inline-episode-browser.tsx:406-422Features:- Hidden on mobile (sm breakpoint)
- Expandable via “Read more” / “Show less” toggle
- Graceful handling of missing descriptions
Watch Status Toggle
Each episode has a toggle button with two states:- Unwatched
- Watched
- Eye icon (outline)
- Gray border
- Hover shows “Mark as watched”
- Click marks episode as watched
src/components/media/inline-episode-browser.tsx:315-361
Episode Watch Tracking
Location:src/hooks/useWatchProgress.ts
Hook: useEpisodeWatched
isEpisodeWatched(season, episode): booleantoggleEpisodeWatched(season, episode): voidmarkSeasonWatched(season, episodes[]): voidunmarkSeasonWatched(season, episodes[]): voidisSeasonFullyWatched(season, episodeCount): booleangetSeasonWatchedCount(season, episodeCount): numberwatchedCount: number- Total episodes watched
Data Storage
- Anonymous Users
- Authenticated Users
Stored in local state via Location:
useLocalProgressStore:src/hooks/useLocalProgressStore.tsBatch Operations
Mark Season as Watched
When a user clicks “Mark all as watched” for a season:Batch Mutation
For authenticated users, single mutation marks all episodes.For local users, iterate and mark each episode in localStorage.Location:
src/hooks/useWatchProgress.ts:574-588Unmark Season
Similar process in reverse:- Identify all watched episodes in the season
- Batch remove watched status
- Recalculate progress (may change to “watching” or “want-to-watch”)
- Update UI
src/hooks/useWatchProgress.ts:601-630
Progress Calculation
Episode-Based Progress
TV show progress is calculated from watched episode count:src/hooks/useWatchProgress.ts:404-412
Auto-Status Updates
As users watch episodes, the show’s progress status updates automatically:- Want to Watch
- Watching
- Finished
- 0 episodes watched
- Progress: 0%
- Status:
"want-to-watch"
For ongoing series (status: “Returning Series”), even with 100% of current episodes watched, the status remains “watching” since more episodes are expected.
Manual Status Override
Users can manually set status from the watchlist:- Manual “finished” status is respected even if not all episodes watched
- Manual “watching” status persists even when 100% complete
- Progress percentage still updates based on actual episode counts
src/hooks/useWatchProgress.ts:433-459
Player Integration
Location:src/hooks/useWatchProgress.ts:69-177
Auto-Mark on Completion
TheusePlayerProgressListener hook listens for video player events:
Player Event
Video player sends postMessage events:
play- User starts playbacktimeupdate- Progress during playbackended- Video finishedpause- Playback pausedseeked- User skipped forward/backward
Episode Marked
Episode watch status is automatically updated:
- For authenticated users:
markEpisodeWatchedmutation - For local users: Update local progress store
Progress Persistence
Player events also save viewing progress:- Saved every 2% of progress change
- Persisted for “Continue Watching” feature
- Resume playback from last position
src/hooks/useWatchProgress.ts:120-162
Season Watch Statistics
Season Completion Badge
Location:src/components/media/inline-episode-browser.tsx:125-132
- Fully Watched
- Partially Watched
- Unwatched
Green “Seen” badge appears when:All episodes in the season have been marked watched.
Season Watch Count
src/hooks/useWatchProgress.ts:646-656
Optimistic UI Updates
For instant feedback, all episode tracking operations use optimistic updates:- Single Episode Toggle
- Batch Season Operation
- UI updates immediately (checkmark appears/disappears)
- Mutation sent to backend
- On success: UI state confirmed
- On failure: UI reverts to previous state
src/hooks/useWatchProgress.ts:296-332Episode Progress Percentage
Individual episodes can have partial progress:Unwatched
Progress: 0%No badge shown
In Progress
Progress: 1-94%Yellow badge with percentage
Completed
Progress: 95-100%Green “Seen” badge
src/hooks/useWatchProgress.ts:708-738
Episode Video Player Modal
Location:src/components/video-player-modal.tsx
Clicking an episode thumbnail opens a modal with:
- Embedded video player
- Episode title and metadata
- Auto-resume from last position
- Auto-play next episode (optional)
- Episode selector dropdown
usePlayerProgressListener.
Continue Watching Feature
Location:src/hooks/useWatchProgress.ts:204-228
Hook: useContinueWatching
- Movies with partial playback
- TV shows with episodes in progress
- Sorted by last updated
Sync Between Progress and Status
Automatic Synchronization
Episode tracking automatically updates show-level metadata: Location:src/hooks/useWatchProgress.ts:383-536
Conflict Resolution
Priority:- Manual “dropped” - Preserved regardless of episode watch count
- Manual “watching” with 100% - Preserved (user may not consider it finished)
- Auto-derived status - Calculated from episode count and series status
