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>
- Save serverConfig to App Group on every app launch so ShareExtension
can always find credentials without requiring a disconnect/reconnect flow
- Add MarksWidget target with RandomBookmarkWidget (random saved bookmark,
reloads hourly) using file-based App Group storage to avoid CFPreferences issues
- Extract BookmarkListRow as shared component with editorial typography tweaks
(17pt semibold title, 13pt domain, relative date, 32×32 favicon, italic AI summary,
20pt podcast icon, 16pt horizontal insets)
- Add MarksWidget and ShareExtension Xcode schemes for direct run/debug
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PodcastIndex.swift stores {articleUrl, filename, title, createdAt} in
App Support/podcasts/index.json. Updated on every successful download.
Enables building a podcast library view later.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>