From 87f89803231b6fcff913b4791cecf653978dea88 Mon Sep 17 00:00:00 2001 From: vicrodh <103399283+vicrodh@users.noreply.github.com> Date: Thu, 15 Jan 2026 00:39:10 -0600 Subject: [PATCH] fix(ui): load album download status on grid view load Load download status for all albums when they are first loaded in grid views (Home, Search, Artist Detail, Favorites) so the 'Download Album' menu shows correct state immediately. cp --- .../components/views/ArtistDetailView.svelte | 16 +++++++++++++ src/lib/components/views/FavoritesView.svelte | 6 +++++ src/lib/components/views/HomeView.svelte | 24 ++++++++++++++----- src/lib/components/views/SearchView.svelte | 9 +++++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/lib/components/views/ArtistDetailView.svelte b/src/lib/components/views/ArtistDetailView.svelte index 8e8b9f5bc..17d747254 100644 --- a/src/lib/components/views/ArtistDetailView.svelte +++ b/src/lib/components/views/ArtistDetailView.svelte @@ -132,6 +132,11 @@ } } + async function loadAllAlbumDownloadStatuses(albums: { id: string }[]) { + if (!checkAlbumFullyDownloaded || albums.length === 0) return; + await Promise.all(albums.map(album => loadAlbumDownloadStatus(album.id))); + } + function isAlbumDownloaded(albumId: string): boolean { void downloadStateVersion; return albumDownloadStatuses.get(albumId) || false; @@ -159,8 +164,19 @@ loadTopTracks(); loadSimilarArtists(); checkFavoriteStatus(); + loadArtistAlbumDownloadStatuses(); }); + async function loadArtistAlbumDownloadStatuses() { + const allAlbums = [ + ...artist.albums, + ...artist.epsSingles, + ...artist.liveAlbums, + ...artist.compilations + ]; + await loadAllAlbumDownloadStatuses(allAlbums); + } + async function checkFavoriteStatus() { try { const response = await invoke<{ artists?: { items: Array<{ id: number }> } }>('get_favorites', { diff --git a/src/lib/components/views/FavoritesView.svelte b/src/lib/components/views/FavoritesView.svelte index d886865f6..443ccabc8 100644 --- a/src/lib/components/views/FavoritesView.svelte +++ b/src/lib/components/views/FavoritesView.svelte @@ -129,6 +129,11 @@ } } + async function loadAllAlbumDownloadStatuses(albums: { id: string }[]) { + if (!checkAlbumFullyDownloaded || albums.length === 0) return; + await Promise.all(albums.map(album => loadAlbumDownloadStatus(album.id))); + } + function isAlbumDownloaded(albumId: string): boolean { void downloadStateVersion; return albumDownloadStatuses.get(albumId) || false; @@ -284,6 +289,7 @@ favoriteTracks = items as FavoriteTrack[]; } else if (type === 'albums') { favoriteAlbums = items as FavoriteAlbum[]; + await loadAllAlbumDownloadStatuses(favoriteAlbums); } else if (type === 'artists') { favoriteArtists = items as FavoriteArtist[]; } diff --git a/src/lib/components/views/HomeView.svelte b/src/lib/components/views/HomeView.svelte index 331210dc6..329a4cab8 100644 --- a/src/lib/components/views/HomeView.svelte +++ b/src/lib/components/views/HomeView.svelte @@ -154,6 +154,11 @@ } } + async function loadAllAlbumDownloadStatuses(albums: AlbumCardData[]) { + if (!checkAlbumFullyDownloaded || albums.length === 0) return; + await Promise.all(albums.map(album => loadAlbumDownloadStatus(album.id))); + } + function isAlbumDownloaded(albumId: string): boolean { void downloadStateVersion; return albumDownloadStatuses.get(albumId) || false; @@ -358,8 +363,9 @@ // Start Qobuz API calls in parallel (don't await) if (isSectionVisible('newReleases')) { - fetchFeaturedAlbums('new-releases', LIMITS.featuredAlbums).then(albums => { + fetchFeaturedAlbums('new-releases', LIMITS.featuredAlbums).then(async albums => { newReleases = albums; + await loadAllAlbumDownloadStatuses(albums); loadingNewReleases = false; markSectionFinished(); }); @@ -368,8 +374,9 @@ } if (isSectionVisible('pressAwards')) { - fetchFeaturedAlbums('press-awards', LIMITS.featuredAlbums).then(albums => { + fetchFeaturedAlbums('press-awards', LIMITS.featuredAlbums).then(async albums => { pressAwards = albums; + await loadAllAlbumDownloadStatuses(albums); loadingPressAwards = false; markSectionFinished(); }); @@ -378,8 +385,9 @@ } if (isSectionVisible('mostStreamed')) { - fetchFeaturedAlbums('most-streamed', LIMITS.featuredAlbums).then(albums => { + fetchFeaturedAlbums('most-streamed', LIMITS.featuredAlbums).then(async albums => { mostStreamed = albums; + await loadAllAlbumDownloadStatuses(albums); loadingMostStreamed = false; markSectionFinished(); }); @@ -388,8 +396,9 @@ } if (isSectionVisible('qobuzissimes')) { - fetchFeaturedAlbums('qobuzissimes', LIMITS.featuredAlbums).then(albums => { + fetchFeaturedAlbums('qobuzissimes', LIMITS.featuredAlbums).then(async albums => { qobuzissimes = albums; + await loadAllAlbumDownloadStatuses(albums); loadingQobuzissimes = false; markSectionFinished(); }); @@ -398,8 +407,9 @@ } if (isSectionVisible('editorPicks')) { - fetchFeaturedAlbums('editor-picks', LIMITS.featuredAlbums).then(albums => { + fetchFeaturedAlbums('editor-picks', LIMITS.featuredAlbums).then(async albums => { editorPicks = albums; + await loadAllAlbumDownloadStatuses(albums); loadingEditorPicks = false; markSectionFinished(); }); @@ -426,8 +436,9 @@ // Recently Played (albums) - start immediately with seeds if (isSectionVisible('recentAlbums')) { const recentAlbumIds = normalizeAlbumIds(seeds.recentlyPlayedAlbumIds); - fetchAlbums(recentAlbumIds.slice(0, LIMITS.recentAlbums)).then(albums => { + fetchAlbums(recentAlbumIds.slice(0, LIMITS.recentAlbums)).then(async albums => { recentAlbums = albums; + await loadAllAlbumDownloadStatuses(albums); loadingRecentAlbums = false; markSectionFinished(); }); @@ -456,6 +467,7 @@ ]); const albums = await fetchAlbums(favoriteAlbumIds.slice(0, LIMITS.favoriteAlbums)); favoriteAlbums = albums; + await loadAllAlbumDownloadStatuses(albums); loadingFavoriteAlbums = false; markSectionFinished(); }); diff --git a/src/lib/components/views/SearchView.svelte b/src/lib/components/views/SearchView.svelte index 904ab88e9..bd2f2ef88 100644 --- a/src/lib/components/views/SearchView.svelte +++ b/src/lib/components/views/SearchView.svelte @@ -177,6 +177,11 @@ } } + async function loadAllAlbumDownloadStatuses(albums: { id: string }[]) { + if (!checkAlbumFullyDownloaded || albums.length === 0) return; + await Promise.all(albums.map(album => loadAlbumDownloadStatus(album.id))); + } + function isAlbumDownloaded(albumId: string): boolean { void downloadStateVersion; return albumDownloadStatuses.get(albumId) || false; @@ -197,6 +202,9 @@ offset: 0 }); console.log('Album results:', albumResults); + if (albumResults && albumResults.items) { + await loadAllAlbumDownloadStatuses(albumResults.items); + } } else if (activeTab === 'tracks') { trackResults = await invoke>('search_tracks', { query: query.trim(), @@ -233,6 +241,7 @@ limit: PAGE_SIZE, offset: newOffset }); + await loadAllAlbumDownloadStatuses(moreResults.items); albumResults = { ...moreResults, items: [...albumResults.items, ...moreResults.items],