feat: add Popular Albums section with conditional loading
- Add mostStreamed section using album/getFeatured most-streamed - Optimize API calls by only fetching visible sections - Default to hidden (enable via Home settings)
This commit is contained in:
1 parent
87b89f0709
commit
721dc2996c
2 files changed
+49
-8
No files matched your search
@@ -86,6 +86,7 @@
|
|||||||
let error = $state<string | null>(null);
|
let error = $state<string | null>(null);
|
||||||
let loadingNewReleases = $state(true);
|
let loadingNewReleases = $state(true);
|
||||||
let loadingPressAwards = $state(true);
|
let loadingPressAwards = $state(true);
|
||||||
|
let loadingMostStreamed = $state(true);
|
||||||
let loadingRecentAlbums = $state(true);
|
let loadingRecentAlbums = $state(true);
|
||||||
let loadingContinueTracks = $state(true);
|
let loadingContinueTracks = $state(true);
|
||||||
let loadingTopArtists = $state(true);
|
let loadingTopArtists = $state(true);
|
||||||
@@ -94,6 +95,7 @@
|
|||||||
// Featured albums (from Qobuz editorial)
|
// Featured albums (from Qobuz editorial)
|
||||||
let newReleases = $state<AlbumCardData[]>([]);
|
let newReleases = $state<AlbumCardData[]>([]);
|
||||||
let pressAwards = $state<AlbumCardData[]>([]);
|
let pressAwards = $state<AlbumCardData[]>([]);
|
||||||
|
let mostStreamed = $state<AlbumCardData[]>([]);
|
||||||
|
|
||||||
// User-specific content
|
// User-specific content
|
||||||
let recentAlbums = $state<AlbumCardData[]>([]);
|
let recentAlbums = $state<AlbumCardData[]>([]);
|
||||||
@@ -106,6 +108,7 @@
|
|||||||
const hasContent = $derived(
|
const hasContent = $derived(
|
||||||
newReleases.length > 0
|
newReleases.length > 0
|
||||||
|| pressAwards.length > 0
|
|| pressAwards.length > 0
|
||||||
|
|| mostStreamed.length > 0
|
||||||
|| recentAlbums.length > 0
|
|| recentAlbums.length > 0
|
||||||
|| continueTracks.length > 0
|
|| continueTracks.length > 0
|
||||||
|| topArtists.length > 0
|
|| topArtists.length > 0
|
||||||
@@ -250,6 +253,7 @@
|
|||||||
error = null;
|
error = null;
|
||||||
loadingNewReleases = true;
|
loadingNewReleases = true;
|
||||||
loadingPressAwards = true;
|
loadingPressAwards = true;
|
||||||
|
loadingMostStreamed = true;
|
||||||
loadingRecentAlbums = true;
|
loadingRecentAlbums = true;
|
||||||
loadingContinueTracks = true;
|
loadingContinueTracks = true;
|
||||||
loadingTopArtists = true;
|
loadingTopArtists = true;
|
||||||
@@ -257,17 +261,35 @@
|
|||||||
|
|
||||||
// Start loading featured albums immediately (no seeds needed)
|
// Start loading featured albums immediately (no seeds needed)
|
||||||
// These show first since they're fast API calls
|
// These show first since they're fast API calls
|
||||||
fetchFeaturedAlbums('new-releases', LIMITS.featuredAlbums).then(albums => {
|
// Only load if section is visible to save API calls
|
||||||
newReleases = albums;
|
if (isSectionVisible('newReleases')) {
|
||||||
|
fetchFeaturedAlbums('new-releases', LIMITS.featuredAlbums).then(albums => {
|
||||||
|
newReleases = albums;
|
||||||
|
loadingNewReleases = false;
|
||||||
|
// Hide initializing as soon as we have some content
|
||||||
|
if (albums.length > 0) isInitializing = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
loadingNewReleases = false;
|
loadingNewReleases = false;
|
||||||
// Hide initializing as soon as we have some content
|
}
|
||||||
if (albums.length > 0) isInitializing = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
fetchFeaturedAlbums('press-awards', LIMITS.featuredAlbums).then(albums => {
|
if (isSectionVisible('pressAwards')) {
|
||||||
pressAwards = albums;
|
fetchFeaturedAlbums('press-awards', LIMITS.featuredAlbums).then(albums => {
|
||||||
|
pressAwards = albums;
|
||||||
|
loadingPressAwards = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
loadingPressAwards = false;
|
loadingPressAwards = false;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if (isSectionVisible('mostStreamed')) {
|
||||||
|
fetchFeaturedAlbums('most-streamed', LIMITS.featuredAlbums).then(albums => {
|
||||||
|
mostStreamed = albums;
|
||||||
|
loadingMostStreamed = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
loadingMostStreamed = false;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// ML-based scoring for personalized recommendations (falls back to simple queries if no scores)
|
// ML-based scoring for personalized recommendations (falls back to simple queries if no scores)
|
||||||
@@ -401,6 +423,23 @@
|
|||||||
</HorizontalScrollRow>
|
</HorizontalScrollRow>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if sectionId === 'mostStreamed' && mostStreamed.length > 0}
|
||||||
|
<HorizontalScrollRow title="Popular Albums">
|
||||||
|
{#snippet children()}
|
||||||
|
{#each mostStreamed as album}
|
||||||
|
<AlbumCard
|
||||||
|
artwork={album.artwork}
|
||||||
|
title={album.title}
|
||||||
|
artist={album.artist}
|
||||||
|
quality={album.quality}
|
||||||
|
onclick={() => onAlbumClick?.(album.id)}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
<div class="spacer"></div>
|
||||||
|
{/snippet}
|
||||||
|
</HorizontalScrollRow>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if sectionId === 'recentAlbums' && recentAlbums.length > 0}
|
{#if sectionId === 'recentAlbums' && recentAlbums.length > 0}
|
||||||
<HorizontalScrollRow title="Recently Played">
|
<HorizontalScrollRow title="Recently Played">
|
||||||
{#snippet children()}
|
{#snippet children()}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
export type HomeSectionId =
|
export type HomeSectionId =
|
||||||
| 'newReleases'
|
| 'newReleases'
|
||||||
| 'pressAwards'
|
| 'pressAwards'
|
||||||
|
| 'mostStreamed'
|
||||||
| 'recentAlbums'
|
| 'recentAlbums'
|
||||||
| 'continueTracks'
|
| 'continueTracks'
|
||||||
| 'topArtists'
|
| 'topArtists'
|
||||||
@@ -35,6 +36,7 @@ const STORAGE_KEY = 'qbz-home-settings';
|
|||||||
const DEFAULT_SECTIONS: HomeSection[] = [
|
const DEFAULT_SECTIONS: HomeSection[] = [
|
||||||
{ id: 'newReleases', label: 'New Releases', visible: true, source: 'qobuz' },
|
{ id: 'newReleases', label: 'New Releases', visible: true, source: 'qobuz' },
|
||||||
{ id: 'pressAwards', label: 'Press Awards', visible: true, source: 'qobuz' },
|
{ id: 'pressAwards', label: 'Press Awards', visible: true, source: 'qobuz' },
|
||||||
|
{ id: 'mostStreamed', label: 'Popular Albums', visible: false, source: 'qobuz' },
|
||||||
{ id: 'recentAlbums', label: 'Recently Played', visible: true, source: 'user' },
|
{ id: 'recentAlbums', label: 'Recently Played', visible: true, source: 'user' },
|
||||||
{ id: 'continueTracks', label: 'Continue Listening', visible: true, source: 'user' },
|
{ id: 'continueTracks', label: 'Continue Listening', visible: true, source: 'user' },
|
||||||
{ id: 'topArtists', label: 'Your Top Artists', visible: true, source: 'user' },
|
{ id: 'topArtists', label: 'Your Top Artists', visible: true, source: 'user' },
|
||||||
|
|||||||
Reference in new issue
Block a user