feat(podcasts): #6 quick wins — tab badge, remember speed, sleep timer, persist queue
- 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>
This commit is contained in:
31
Marks/Services/PodcastLibrary.swift
Normal file
31
Marks/Services/PodcastLibrary.swift
Normal file
@@ -0,0 +1,31 @@
|
||||
import Foundation
|
||||
import Observation
|
||||
|
||||
/// Observable, in-memory mirror of `PodcastIndex` so SwiftUI updates immediately
|
||||
/// on changes — the Podcasts tab badge and the library list both read from here.
|
||||
/// Route podcast mutations through this store so the unplayed badge stays in sync.
|
||||
@Observable
|
||||
@MainActor
|
||||
final class PodcastLibrary {
|
||||
static let shared = PodcastLibrary()
|
||||
|
||||
private(set) var entries: [PodcastEntry] = []
|
||||
|
||||
var unplayed: [PodcastEntry] { entries.filter { !$0.isPlayed } }
|
||||
var played: [PodcastEntry] { entries.filter { $0.isPlayed } }
|
||||
var unplayedCount: Int { entries.reduce(0) { $0 + ($1.isPlayed ? 0 : 1) } }
|
||||
|
||||
private init() { entries = PodcastIndex.all() }
|
||||
|
||||
func reload() { entries = PodcastIndex.all() }
|
||||
|
||||
func setPlayed(_ articleUrl: String, _ played: Bool) {
|
||||
PodcastIndex.setPlayed(articleUrl: articleUrl, played)
|
||||
reload()
|
||||
}
|
||||
|
||||
func remove(_ articleUrl: String) {
|
||||
PodcastIndex.remove(articleUrl: articleUrl)
|
||||
reload()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user