Version one on the App Store
This commit is contained in:
@@ -41,6 +41,9 @@ final class MALibraryManager {
|
||||
|
||||
// MARK: - Disk Cache
|
||||
|
||||
/// Increment this whenever the model format changes to invalidate stale caches.
|
||||
private static let cacheVersion = 2
|
||||
|
||||
private let cacheDirectory: URL = {
|
||||
let caches = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
|
||||
let dir = caches.appendingPathComponent("MMLibrary", isDirectory: true)
|
||||
@@ -52,9 +55,24 @@ final class MALibraryManager {
|
||||
|
||||
init(service: MAService?) {
|
||||
self.service = service
|
||||
migrateIfNeeded()
|
||||
loadFromDisk()
|
||||
}
|
||||
|
||||
/// Clears all disk-cached library data when the model format changes.
|
||||
private func migrateIfNeeded() {
|
||||
let storedVersion = UserDefaults.standard.integer(forKey: "lib.cacheVersion")
|
||||
guard storedVersion < Self.cacheVersion else { return }
|
||||
|
||||
logger.info("Cache version mismatch (\(storedVersion) → \(Self.cacheVersion)), clearing library cache")
|
||||
try? FileManager.default.removeItem(at: cacheDirectory)
|
||||
try? FileManager.default.createDirectory(at: cacheDirectory, withIntermediateDirectories: true)
|
||||
for key in ["lib.lastArtistsRefresh", "lib.lastAlbumsRefresh", "lib.lastPlaylistsRefresh"] {
|
||||
UserDefaults.standard.removeObject(forKey: key)
|
||||
}
|
||||
UserDefaults.standard.set(Self.cacheVersion, forKey: "lib.cacheVersion")
|
||||
}
|
||||
|
||||
func setService(_ service: MAService) {
|
||||
self.service = service
|
||||
}
|
||||
@@ -110,10 +128,10 @@ final class MALibraryManager {
|
||||
guard !isLoadingArtists else { return }
|
||||
guard let service else { throw MAWebSocketClient.ClientError.notConnected }
|
||||
|
||||
// For refresh, reset pagination counters but keep existing data visible until new data arrives
|
||||
let fetchOffset = refresh ? 0 : artistsOffset
|
||||
if refresh {
|
||||
artistsOffset = 0
|
||||
hasMoreArtists = true
|
||||
artists = []
|
||||
}
|
||||
|
||||
guard hasMoreArtists else { return }
|
||||
@@ -121,20 +139,25 @@ final class MALibraryManager {
|
||||
isLoadingArtists = true
|
||||
defer { isLoadingArtists = false }
|
||||
|
||||
logger.info("Loading artists (offset: \(self.artistsOffset))")
|
||||
logger.info("Loading artists (offset: \(fetchOffset), refresh: \(refresh))")
|
||||
|
||||
let newArtists = try await service.getArtists(limit: pageSize, offset: artistsOffset)
|
||||
let newArtists = try await service.getArtists(limit: pageSize, offset: fetchOffset)
|
||||
|
||||
if refresh {
|
||||
artists = newArtists
|
||||
} else {
|
||||
artists.append(contentsOf: newArtists)
|
||||
// DEBUG: log first artist's image state so we can trace artwork loading
|
||||
if let a = newArtists.first {
|
||||
logger.debug("DEBUG Artist[0] name=\(a.name) metadata=\(String(describing: a.metadata)) imageUrl=\(a.imageUrl ?? "nil") imageProvider=\(a.imageProvider ?? "nil")")
|
||||
}
|
||||
|
||||
artistsOffset += newArtists.count
|
||||
// Replace or append atomically — no intermediate empty state
|
||||
if refresh {
|
||||
artists = newArtists
|
||||
artistsOffset = newArtists.count
|
||||
} else {
|
||||
artists.append(contentsOf: newArtists)
|
||||
artistsOffset += newArtists.count
|
||||
}
|
||||
hasMoreArtists = newArtists.count >= pageSize
|
||||
|
||||
// Persist to disk after a full load or first page of refresh
|
||||
if refresh || artistsOffset <= pageSize {
|
||||
save(artists, "artists.json")
|
||||
lastArtistsRefresh = markRefreshed("lib.lastArtistsRefresh")
|
||||
@@ -159,10 +182,9 @@ final class MALibraryManager {
|
||||
guard !isLoadingAlbums else { return }
|
||||
guard let service else { throw MAWebSocketClient.ClientError.notConnected }
|
||||
|
||||
let fetchOffset = refresh ? 0 : albumsOffset
|
||||
if refresh {
|
||||
albumsOffset = 0
|
||||
hasMoreAlbums = true
|
||||
albums = []
|
||||
}
|
||||
|
||||
guard hasMoreAlbums else { return }
|
||||
@@ -170,17 +192,17 @@ final class MALibraryManager {
|
||||
isLoadingAlbums = true
|
||||
defer { isLoadingAlbums = false }
|
||||
|
||||
logger.info("Loading albums (offset: \(self.albumsOffset))")
|
||||
logger.info("Loading albums (offset: \(fetchOffset), refresh: \(refresh))")
|
||||
|
||||
let newAlbums = try await service.getAlbums(limit: pageSize, offset: albumsOffset)
|
||||
let newAlbums = try await service.getAlbums(limit: pageSize, offset: fetchOffset)
|
||||
|
||||
if refresh {
|
||||
albums = newAlbums
|
||||
albumsOffset = newAlbums.count
|
||||
} else {
|
||||
albums.append(contentsOf: newAlbums)
|
||||
albumsOffset += newAlbums.count
|
||||
}
|
||||
|
||||
albumsOffset += newAlbums.count
|
||||
hasMoreAlbums = newAlbums.count >= pageSize
|
||||
|
||||
if refresh || albumsOffset <= pageSize {
|
||||
|
||||
Reference in New Issue
Block a user