Queue mgmt, Podcast support, Favorites section.
This commit is contained in:
@@ -22,6 +22,7 @@ final class MALibraryManager {
|
||||
private(set) var albumArtists: [MAArtist] = []
|
||||
private(set) var albums: [MAAlbum] = []
|
||||
private(set) var playlists: [MAPlaylist] = []
|
||||
private(set) var podcasts: [MAPodcast] = []
|
||||
|
||||
// Pagination
|
||||
private var artistsOffset = 0
|
||||
@@ -37,6 +38,7 @@ final class MALibraryManager {
|
||||
private(set) var isLoadingAlbumArtists = false
|
||||
private(set) var isLoadingAlbums = false
|
||||
private(set) var isLoadingPlaylists = false
|
||||
private(set) var isLoadingPodcasts = false
|
||||
|
||||
/// URIs currently marked as favorites — source of truth for UI.
|
||||
/// Populated from decoded model data, then mutated optimistically on toggle.
|
||||
@@ -47,6 +49,7 @@ final class MALibraryManager {
|
||||
private(set) var lastAlbumArtistsRefresh: Date?
|
||||
private(set) var lastAlbumsRefresh: Date?
|
||||
private(set) var lastPlaylistsRefresh: Date?
|
||||
private(set) var lastPodcastsRefresh: Date?
|
||||
|
||||
// MARK: - Disk Cache
|
||||
|
||||
@@ -109,17 +112,23 @@ final class MALibraryManager {
|
||||
playlists = cached
|
||||
logger.info("Loaded \(cached.count) playlists from disk cache")
|
||||
}
|
||||
if let cached: [MAPodcast] = load("podcasts.json") {
|
||||
podcasts = cached
|
||||
logger.info("Loaded \(cached.count) podcasts from disk cache")
|
||||
}
|
||||
|
||||
// Seed favorite URIs from cached data
|
||||
for artist in artists where artist.favorite { favoriteURIs.insert(artist.uri) }
|
||||
for artist in albumArtists where artist.favorite { favoriteURIs.insert(artist.uri) }
|
||||
for album in albums where album.favorite { favoriteURIs.insert(album.uri) }
|
||||
for podcast in podcasts where podcast.favorite { favoriteURIs.insert(podcast.uri) }
|
||||
|
||||
let ud = UserDefaults.standard
|
||||
lastArtistsRefresh = ud.object(forKey: "lib.lastArtistsRefresh") as? Date
|
||||
lastAlbumArtistsRefresh = ud.object(forKey: "lib.lastAlbumArtistsRefresh") as? Date
|
||||
lastAlbumsRefresh = ud.object(forKey: "lib.lastAlbumsRefresh") as? Date
|
||||
lastPlaylistsRefresh = ud.object(forKey: "lib.lastPlaylistsRefresh") as? Date
|
||||
lastPodcastsRefresh = ud.object(forKey: "lib.lastPodcastsRefresh") as? Date
|
||||
}
|
||||
|
||||
private func save<T: Encodable>(_ value: T, _ filename: String) {
|
||||
@@ -338,6 +347,32 @@ final class MALibraryManager {
|
||||
logger.info("Loaded \(loaded.count) playlists")
|
||||
}
|
||||
|
||||
// MARK: - Podcasts
|
||||
|
||||
func loadPodcasts(refresh: Bool = false) async throws {
|
||||
guard !isLoadingPodcasts else { return }
|
||||
guard let service else { throw MAWebSocketClient.ClientError.notConnected }
|
||||
|
||||
isLoadingPodcasts = true
|
||||
defer { isLoadingPodcasts = false }
|
||||
|
||||
logger.info("Loading podcasts")
|
||||
|
||||
let loaded = try await service.getPodcasts()
|
||||
podcasts = loaded
|
||||
for podcast in loaded where podcast.favorite { favoriteURIs.insert(podcast.uri) }
|
||||
save(podcasts, "podcasts.json")
|
||||
lastPodcastsRefresh = markRefreshed("lib.lastPodcastsRefresh")
|
||||
|
||||
logger.info("Loaded \(loaded.count) podcasts")
|
||||
}
|
||||
|
||||
func getPodcastEpisodes(podcastUri: String) async throws -> [MAMediaItem] {
|
||||
guard let service else { throw MAWebSocketClient.ClientError.notConnected }
|
||||
logger.info("Loading episodes for podcast \(podcastUri)")
|
||||
return try await service.getPodcastEpisodes(podcastUri: podcastUri)
|
||||
}
|
||||
|
||||
// MARK: - Artist Albums & Tracks (not cached — fetched on demand)
|
||||
|
||||
func getArtistAlbums(artistUri: String) async throws -> [MAAlbum] {
|
||||
|
||||
Reference in New Issue
Block a user