Surface the AI-generated dialogue script alongside playback, synced to the audio
so tapping a line seeks to it. This leans into the app's unique angle — we generate the script, so we can do read-along for arbitrary articles, which
Apple Podcasts can't.
Motivation
Strong differentiator and reuses backend output. Great for noisy environments,
accessibility, and skimming/seeking to a specific point.
Current state of the code
ClaudeService.podcastStatus currently returns only status, progress, title, error. The transcript (and ideally per-line timestamps) would need to
be returned by the generation backend and stored — e.g. a new field on PodcastEntry or a sibling file next to the cached mp3.
The player (PodcastPlayerViewModel) already emits currentTime via a periodic
time observer — the sync/highlight can hang off that.
Behavior
Full player gains a transcript view (sheet or expandable panel).
Highlight the active line as audio plays; tap a line to seek(to:).
Degrade gracefully to a plain, unsynced transcript when timestamps are absent.
Dependencies
Backend change: generation must return the script (+ timing). Coordinate
with the magicive.api podcast pipeline. Track the API addition as a sub-task.
## Summary
Surface the AI-generated dialogue script alongside playback, synced to the audio
so tapping a line seeks to it. This leans into the app's unique angle — we
*generate* the script, so we can do read-along for arbitrary articles, which
Apple Podcasts can't.
## Motivation
Strong differentiator and reuses backend output. Great for noisy environments,
accessibility, and skimming/seeking to a specific point.
## Current state of the code
- `ClaudeService.podcastStatus` currently returns only `status`, `progress`,
`title`, `error`. The transcript (and ideally per-line timestamps) would need to
be returned by the generation backend and stored — e.g. a new field on
`PodcastEntry` or a sibling file next to the cached mp3.
- The player (`PodcastPlayerViewModel`) already emits `currentTime` via a periodic
time observer — the sync/highlight can hang off that.
## Behavior
- Full player gains a transcript view (sheet or expandable panel).
- Highlight the active line as audio plays; tap a line to `seek(to:)`.
- Degrade gracefully to a plain, unsynced transcript when timestamps are absent.
## Dependencies
- **Backend change**: generation must return the script (+ timing). Coordinate
with the magicive.api podcast pipeline. Track the API addition as a sub-task.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Surface the AI-generated dialogue script alongside playback, synced to the audio
so tapping a line seeks to it. This leans into the app's unique angle — we
generate the script, so we can do read-along for arbitrary articles, which
Apple Podcasts can't.
Motivation
Strong differentiator and reuses backend output. Great for noisy environments,
accessibility, and skimming/seeking to a specific point.
Current state of the code
ClaudeService.podcastStatuscurrently returns onlystatus,progress,title,error. The transcript (and ideally per-line timestamps) would need tobe returned by the generation backend and stored — e.g. a new field on
PodcastEntryor a sibling file next to the cached mp3.PodcastPlayerViewModel) already emitscurrentTimevia a periodictime observer — the sync/highlight can hang off that.
Behavior
seek(to:).Dependencies
with the magicive.api podcast pipeline. Track the API addition as a sub-task.