Podcast played/unplayed tracking + play queue (podcast-app model) #1

Closed
opened 2026-07-01 16:07:27 +00:00 by admin · 0 comments
Owner

Summary

Make the Podcasts tab behave like a real podcast app: track which episodes are new/unplayed vs played, and let me queue up all the unplayed ones for continuous listening. Once an episode finishes, it moves out of the unplayed list into a Played list.

Motivation

Right now the library is a flat, reverse-chronological list. There's no notion of what I've heard vs. what's new, and no way to just hit play and roll through everything unplayed.

Behavior

  • Each podcast has an explicit state: unplayed (new), in progress, played.
  • The Podcasts tab shows two sections/filters: Up Next / Unplayed and Played (like Apple Podcasts / Overcast).
  • "Play all unplayed" / queue: playing the queue auto-advances to the next unplayed episode when one finishes.
  • Finishing an episode (crossing the completion threshold) marks it played and moves it to the Played list.
  • Manual override: swipe to mark played / mark unplayed.

Current state of the code

  • PodcastEntry (Marks/Services/PodcastIndex.swift) has no played flag — needs a new field (e.g. playedAt: Date? or a PlayState enum) plus migration for the existing index.json.
  • PodcastProgress (Marks/Views/PodcastPlayerView.swift) already persists per-URL position and clears at >97% completion / <10s. The completion crossing (~line 240, the 97% analytics event) and the play-to-end handler (~line 200) are the natural hooks to flip state to played.
  • PodcastPlayerViewModel is single-episode today — no queue, no auto-advance. This needs a queue model (ordered list of unplayed PodcastEntrys) and "advance to next on completion".
  • PodcastLibraryView renders the flat list; it needs the Unplayed/Played split + a "Play all" affordance.

Notes / dependencies

  • The queue + auto-advance machinery here is a natural foundation for background generation. A freshly generated episode should land at the top of the Unplayed queue.
## Summary Make the Podcasts tab behave like a real podcast app: track which episodes are **new/unplayed** vs **played**, and let me queue up all the unplayed ones for continuous listening. Once an episode finishes, it moves out of the unplayed list into a Played list. ## Motivation Right now the library is a flat, reverse-chronological list. There's no notion of what I've heard vs. what's new, and no way to just hit play and roll through everything unplayed. ## Behavior - Each podcast has an explicit state: **unplayed** (new), **in progress**, **played**. - The Podcasts tab shows two sections/filters: **Up Next / Unplayed** and **Played** (like Apple Podcasts / Overcast). - "Play all unplayed" / queue: playing the queue auto-advances to the next unplayed episode when one finishes. - Finishing an episode (crossing the completion threshold) marks it **played** and moves it to the Played list. - Manual override: swipe to mark played / mark unplayed. ## Current state of the code - `PodcastEntry` (`Marks/Services/PodcastIndex.swift`) has **no played flag** — needs a new field (e.g. `playedAt: Date?` or a `PlayState` enum) plus migration for the existing `index.json`. - `PodcastProgress` (`Marks/Views/PodcastPlayerView.swift`) already persists per-URL position and clears at >97% completion / <10s. The completion crossing (~line 240, the 97% analytics event) and the play-to-end handler (~line 200) are the natural hooks to flip state to **played**. - `PodcastPlayerViewModel` is **single-episode** today — no queue, no auto-advance. This needs a queue model (ordered list of unplayed `PodcastEntry`s) and "advance to next on completion". - `PodcastLibraryView` renders the flat list; it needs the Unplayed/Played split + a "Play all" affordance. ## Notes / dependencies - The queue + auto-advance machinery here is a natural foundation for background generation. A freshly generated episode should land at the top of the Unplayed queue.
admin closed this issue 2026-07-01 18:18:57 +00:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/linkding-ios#1