# Watch

**Job:** Play media and surface **what to watch next** on the device you choose.

One-liner: *What am I watching, on which screen, right now?*

**Split from Library:** catalog scan, browse grids, metadata live under
[library.md](./library.md). Watch consumes library data for Home rails and Player.

---

## Scope

| In | Out |
|----|-----|
| Playback control (play/pause/seek/volume/queue) | Library scan, index rebuild (Library) |
| Home presentation (rails, play actions) | Metadata enrichment queue (Library) |
| Player chrome, skip intro, up next | Torrent search (Download) |
| Continue Watching **UX** | Show grouping logic (Library) |
| Play queue popover | Device registry (Devices) |
| Now Playing, media keys | Shared media placement (Devices) |
| Offline **playback** path resolution | Offline **policy** editor (Devices) |
| Adult play / queue UX | Adult catalog rotation (Library) |

---

## User surfaces

### macOS

| Tab / area | Role |
|------------|------|
| Home | Rails, resume, launch play |
| Player | Transport, skip intro, queue rail |
| Adult | Play into queue (catalog from Library) |
| Play Queue (global) | `PlaylistController` |

Library · Metadata · Devices · Search · Downloads · Settings are other pillars
(same app shell).

### iOS

| Tab | Role |
|-----|------|
| Remote | Control registered devices |
| Library tab play | In-app VLC (Watch + Library data) |

---

## Core modules

### Playback

| Module | Role |
|--------|------|
| `PlayerController` | Target routing, poll, commands, skip-intro |
| `PlayerTarget`, `VLCTarget`, `MpvTarget`, `QuickTimeTarget`, `RokuTarget` | Backends |
| `PlaylistController` | User queue |
| `NowPlayingController` | System media keys |
| `TrackPreferenceStore` | Per-series track prefs |
| `WatchState` | In-session progress |
| `VLCLauncher` | Start local VLC |

### Watch history

| Module | Role |
|--------|------|
| `WatchHistory` | Continue Watching data |
| `BlackWatchlog` | Black resume map |

### Labels (from Library)

Watch **does not** parse filenames for display. Player hero, queue chips, and
up-next read `CachedEpisode.displayName` / `episodeTitle` —
[library-display.md](../pillars/library-display.md).

### Playback paths

| Module | Role |
|--------|------|
| `MediaPaths` | Resolve play URL — **placement-aware** (Devices) |
| `DownloadsIndex` | Local file routing |

### Appearance

| Module | Role |
|--------|------|
| `AppTheme`, `Theme/`, Winamp skins | [watch-appearance.md](./watch-appearance.md) |

---

## Settings (Watch pillar)

See [settings.md](./settings.md): playback mode, skip intro, Home rails, media
keys, adult playback mode, hover previews.

---

## Net touchpoints

| Net part | Watch consumer |
|----------|----------------|
| `intro-markers` | `PlayerController` skip window |

Watch **produces** skip observations.

---

## State

Watch-primary reads: library snapshot, watchlog, placement index (Devices),
settings `watch` section.

---

## Tests

`ContinueWatchingTests`, `WatchStateTests`, `PlaylistTests`, `NowPlayingTests`,
`PlayerDisplayTests`, `SleepTimerTests`, `TrackPreferenceTests`, `MpvIPCParserTests`,
`RokuTargetTests`, `MediaPathsTests`.