New PodcastGenerationManager runs the generate → poll → download loop off the player, so a new episode is produced without stopping current playback.
Headphone taps now never interrupt: player idle → generate-and-play in the foreground (unchanged); already playing → generate in the background, and the finished episode lands in the library.
A "Generating…" banner in the bookmarks overlay surfaces active jobs with progress.
"Create podcast" toggle on the save card + configurable Auto-Podcast Tags in Settings.
The extension enqueues a request into the shared App Group (it's too short-lived to generate); the main app drains it on launch/foreground and runs it through the background manager.
Notes
project.yml updated so PodcastRequests.swift is a member of both the Marks and ShareExtension targets; xcodegen generate + simulator build pass clean.
Turns the Podcasts tab into a real podcast-app experience. Three features that compose on one shared background-generation service.
## #2 — Background generation (keystone)
- New `PodcastGenerationManager` runs the generate → poll → download loop **off** the player, so a new episode is produced without stopping current playback.
- Headphone taps now **never interrupt**: player idle → generate-and-play in the foreground (unchanged); already playing → generate in the **background**, and the finished episode lands in the library.
- A "Generating…" banner in the bookmarks overlay surfaces active jobs with progress.
## #1 — Played/unplayed + queue
- `PodcastEntry` gains `playedAt` (pre-existing `index.json` decodes as unplayed — automatic migration).
- Podcasts tab splits into **Up Next** / **Played**, with a **Play All** queue that auto-advances episode to episode.
- Finishing marks an episode played; swipe to toggle played/unplayed.
## #3 — Share-extension audio
- "Create podcast" toggle on the save card + configurable **Auto-Podcast Tags** in Settings.
- The extension enqueues a request into the shared App Group (it's too short-lived to generate); the main app drains it on launch/foreground and runs it through the background manager.
## Notes
- `project.yml` updated so `PodcastRequests.swift` is a member of both the Marks and ShareExtension targets; `xcodegen generate` + simulator build pass clean.
Closes #1
Closes #2
Closes #3
Closes #6
Closes #8
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Turns the Podcasts tab into a proper podcast-app experience across three
features that compose on a shared background-generation service.
Background generation (#2)
- New PodcastGenerationManager runs generate→poll→download off the player,
so producing a new episode never stops current playback.
- Headphone taps never interrupt: idle → generate-and-play in the foreground
(unchanged); already playing → generate in the background, episode lands in
the library. A "Generating…" banner surfaces active jobs.
Played/unplayed + queue (#1)
- PodcastEntry gains playedAt (old index.json decodes as unplayed).
- Podcasts tab splits into Up Next / Played with a Play All queue that
auto-advances; finishing marks played; swipe to toggle played state.
Share-extension audio (#3)
- "Create podcast" toggle on the save card, plus configurable Auto-Podcast
Tags in Settings. The extension enqueues a request into the App Group; the
main app drains it on launch/foreground and generates in the background.
Closes#1Closes#2Closes#3
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add a long-press context menu on each library row (Play/Pause,
Mark as Played/Unplayed, Delete).
- Add a Mark as Played/Unplayed control next to Share Episode in the full
player, tracking the loaded episode across queue advances.
- Show a green checkmark on played rows, on top of the existing Played
section + dimmed title, so played state reads at a glance.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Unread badge on the Podcasts tab via a new observable PodcastLibrary store
that mirrors PodcastIndex; all played/remove/generation mutations route
through it so the count stays live.
- Persist playback speed across sessions (UserDefaults), applied on setup.
- Sleep timer (15/30/45 min or end-of-episode) with a moon menu in the full
player; end-of-episode stops instead of auto-advancing.
- Persist the current episode + Up Next queue and restore a *paused* session on
launch; save position when backgrounding. Audio session is only claimed on
actual playback so a restored session never interrupts other audio.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- New EpisodeDetailView: title, source domain, created date, played badge,
and per-episode actions — Play/Pause, Mark Played/Unplayed, Open Source,
Share, Delete — all routed through the PodcastLibrary store so the badge
stays in sync.
- Reachable by tapping a row (or "Episode Details" in the context menu) in the
Podcasts tab, and by tapping a row in the episode picker.
Note: AI summary is intentionally omitted for now — it's keyed by bookmark id
(not URL), so surfacing it would recouple the deliberately-decoupled Podcasts
tab to BookmarksViewModel. Open Source uses Safari rather than the in-app
browser to avoid sheet-stacking. Both are noted as follow-ups on issue #8.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolves the two deviations from the episode detail sheet:
- AI summary now shows in the detail sheet. Added a URL-keyed AISummaryStore
that BookmarksViewModel populates as it enriches/loads bookmarks, so the
decoupled Podcasts tab can surface a summary from just the episode URL —
without recoupling to BookmarksViewModel.
- "Open Bookmark" opens the in-app BrowserView as a nested sheet (generator
threaded through PodcastLibraryView / EpisodePickerView), alongside the
existing "Open in Safari" and Share.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
admin
merged commit b496e607fc into master2026-07-01 18:18:57 +00:00
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.
Turns the Podcasts tab into a real podcast-app experience. Three features that compose on one shared background-generation service.
#2 — Background generation (keystone)
PodcastGenerationManagerruns the generate → poll → download loop off the player, so a new episode is produced without stopping current playback.#1 — Played/unplayed + queue
PodcastEntrygainsplayedAt(pre-existingindex.jsondecodes as unplayed — automatic migration).#3 — Share-extension audio
Notes
project.ymlupdated soPodcastRequests.swiftis a member of both the Marks and ShareExtension targets;xcodegen generate+ simulator build pass clean.Closes #1
Closes #2
Closes #3
Closes #6
Closes #8
🤖 Generated with Claude Code