Tapping an episode opens a detail sheet that reconnects the podcast to the
bookmark it came from: source article, AI summary, "Open bookmark," and delete.
Motivation
Right now an episode is a title + date with no way back to its origin. Podcasts
are generated from bookmarks — the detail view should let you jump to the
source, re-read, or manage the episode.
Current state of the code
PodcastEntry already stores articleUrl, parentBookmarkUrl, title, createdAt, and now playedAt.
PodcastLibraryView / EpisodePickerView rows currently only play or expose
swipe/context actions — add a tap target that presents the detail sheet.
Opening the source can reuse the existing marks://bookmark?url= deep link or
present BrowserView directly.
AI summary is available via Bookmark.aiSummary / ClaudeService.enrich when
the parent bookmark is known.
Behavior
Detail sheet: title, source domain/link, created date, played state, AI summary
(if available), "Open bookmark", "Share episode", "Delete".
Reachable from the Podcasts tab and the episode picker.
## Summary
Tapping an episode opens a detail sheet that reconnects the podcast to the
bookmark it came from: source article, AI summary, "Open bookmark," and delete.
## Motivation
Right now an episode is a title + date with no way back to its origin. Podcasts
are generated *from* bookmarks — the detail view should let you jump to the
source, re-read, or manage the episode.
## Current state of the code
- `PodcastEntry` already stores `articleUrl`, `parentBookmarkUrl`, `title`,
`createdAt`, and now `playedAt`.
- `PodcastLibraryView` / `EpisodePickerView` rows currently only play or expose
swipe/context actions — add a tap target that presents the detail sheet.
- Opening the source can reuse the existing `marks://bookmark?url=` deep link or
present `BrowserView` directly.
- AI summary is available via `Bookmark.aiSummary` / `ClaudeService.enrich` when
the parent bookmark is known.
## Behavior
- Detail sheet: title, source domain/link, created date, played state, AI summary
(if available), "Open bookmark", "Share episode", "Delete".
- Reachable from the Podcasts tab and the episode picker.
Implemented in PR #4 (feat/podcast-app-experience). Shipped: EpisodeDetailView with title, source domain, created date, played badge, and actions (Play/Pause, Mark Played, Open Source, Share, Delete). Reachable from the Podcasts tab (row tap + context menu) and the episode picker. All mutations route through the PodcastLibrary store so the tab badge stays in sync.
Two deliberate deviations from the original spec, left as follow-ups:
AI summary omitted.aiData is keyed by bookmark id, but a PodcastEntry only carries the article/bookmark URL. Surfacing the summary would require recoupling the deliberately-decoupled Podcasts tab to BookmarksViewModel. Deferred pending that coupling decision.
Open Source uses Safari (external) rather than the in-app browser. The in-app route needs the marks://bookmark?url= deep link, which risks sheet-stacking from within the detail sheet. Safari is reliable; in-app open can be added if desired.
Implemented in PR #4 (`feat/podcast-app-experience`). Shipped: `EpisodeDetailView` with title, source domain, created date, played badge, and actions (Play/Pause, Mark Played, Open Source, Share, Delete). Reachable from the Podcasts tab (row tap + context menu) and the episode picker. All mutations route through the `PodcastLibrary` store so the tab badge stays in sync.
Two deliberate deviations from the original spec, left as follow-ups:
- **AI summary omitted.** `aiData` is keyed by bookmark **id**, but a `PodcastEntry` only carries the article/bookmark **URL**. Surfacing the summary would require recoupling the deliberately-decoupled Podcasts tab to `BookmarksViewModel`. Deferred pending that coupling decision.
- **Open Source uses Safari** (external) rather than the in-app browser. The in-app route needs the `marks://bookmark?url=` deep link, which risks sheet-stacking from within the detail sheet. Safari is reliable; in-app open can be added if desired.
Both earlier deviations are now resolved (same PR/branch):
AI summary — the detail sheet now shows the bookmark's AI summary. Rather than recoupling the Podcasts tab to BookmarksViewModel, added a URL-keyed AISummaryStore that BookmarksViewModel populates as it enriches/loads bookmarks; the detail sheet reads it by episode URL.
In-app open — added Open Bookmark, which opens the in-app BrowserView as a nested sheet (the generator is threaded through PodcastLibraryView / EpisodePickerView). Open in Safari and Share remain.
Both earlier deviations are now resolved (same PR/branch):
- **AI summary** — the detail sheet now shows the bookmark's AI summary. Rather than recoupling the Podcasts tab to `BookmarksViewModel`, added a URL-keyed `AISummaryStore` that `BookmarksViewModel` populates as it enriches/loads bookmarks; the detail sheet reads it by episode URL.
- **In-app open** — added **Open Bookmark**, which opens the in-app `BrowserView` as a nested sheet (the generator is threaded through `PodcastLibraryView` / `EpisodePickerView`). **Open in Safari** and **Share** remain.
#8 is fully implemented.
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
Tapping an episode opens a detail sheet that reconnects the podcast to the
bookmark it came from: source article, AI summary, "Open bookmark," and delete.
Motivation
Right now an episode is a title + date with no way back to its origin. Podcasts
are generated from bookmarks — the detail view should let you jump to the
source, re-read, or manage the episode.
Current state of the code
PodcastEntryalready storesarticleUrl,parentBookmarkUrl,title,createdAt, and nowplayedAt.PodcastLibraryView/EpisodePickerViewrows currently only play or exposeswipe/context actions — add a tap target that presents the detail sheet.
marks://bookmark?url=deep link orpresent
BrowserViewdirectly.Bookmark.aiSummary/ClaudeService.enrichwhenthe parent bookmark is known.
Behavior
(if available), "Open bookmark", "Share episode", "Delete".
Implemented in PR #4 (
feat/podcast-app-experience). Shipped:EpisodeDetailViewwith title, source domain, created date, played badge, and actions (Play/Pause, Mark Played, Open Source, Share, Delete). Reachable from the Podcasts tab (row tap + context menu) and the episode picker. All mutations route through thePodcastLibrarystore so the tab badge stays in sync.Two deliberate deviations from the original spec, left as follow-ups:
aiDatais keyed by bookmark id, but aPodcastEntryonly carries the article/bookmark URL. Surfacing the summary would require recoupling the deliberately-decoupled Podcasts tab toBookmarksViewModel. Deferred pending that coupling decision.marks://bookmark?url=deep link, which risks sheet-stacking from within the detail sheet. Safari is reliable; in-app open can be added if desired.Both earlier deviations are now resolved (same PR/branch):
BookmarksViewModel, added a URL-keyedAISummaryStorethatBookmarksViewModelpopulates as it enriches/loads bookmarks; the detail sheet reads it by episode URL.BrowserViewas a nested sheet (the generator is threaded throughPodcastLibraryView/EpisodePickerView). Open in Safari and Share remain.#8 is fully implemented.