"You might like" web client row (#790 web slice) #94
@@ -18,7 +18,9 @@ describe('home client', () => {
|
|||||||
rediscover_albums: [],
|
rediscover_albums: [],
|
||||||
rediscover_artists: [],
|
rediscover_artists: [],
|
||||||
most_played_tracks: [],
|
most_played_tracks: [],
|
||||||
last_played_artists: []
|
last_played_artists: [],
|
||||||
|
you_might_like_albums: [],
|
||||||
|
you_might_like_artists: []
|
||||||
};
|
};
|
||||||
(api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce(fixture);
|
(api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce(fixture);
|
||||||
const got = await listHome();
|
const got = await listHome();
|
||||||
|
|||||||
@@ -342,4 +342,6 @@ export type HomePayload = {
|
|||||||
rediscover_artists: ArtistRef[];
|
rediscover_artists: ArtistRef[];
|
||||||
most_played_tracks: TrackRef[];
|
most_played_tracks: TrackRef[];
|
||||||
last_played_artists: ArtistRef[];
|
last_played_artists: ArtistRef[];
|
||||||
|
you_might_like_albums: AlbumRef[];
|
||||||
|
you_might_like_artists: ArtistRef[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -161,6 +161,42 @@
|
|||||||
{:else if showSkeleton.value && !data}
|
{:else if showSkeleton.value && !data}
|
||||||
<p class="text-text-secondary">Loading…</p>
|
<p class="text-text-secondary">Loading…</p>
|
||||||
{:else if data}
|
{:else if data}
|
||||||
|
<!-- You might like: taste-predicted in-library albums + artists the user
|
||||||
|
doesn't actively spin (server section, daily-built, cold-start gated).
|
||||||
|
Sits directly under the system playlists row. Two scrollers like
|
||||||
|
Rediscover (square album vs circular artist cards). -->
|
||||||
|
<section class="space-y-3">
|
||||||
|
{#if data.you_might_like_albums.length === 0 && data.you_might_like_artists.length === 0}
|
||||||
|
<header>
|
||||||
|
<h2 class="font-display text-2xl font-medium text-text-primary">You might like</h2>
|
||||||
|
</header>
|
||||||
|
<p class="text-text-secondary">We're still learning your taste — keep listening and picks you might like will show up here.</p>
|
||||||
|
{:else}
|
||||||
|
{#if data.you_might_like_albums.length > 0}
|
||||||
|
<HorizontalScrollRow
|
||||||
|
rows={[data.you_might_like_albums]}
|
||||||
|
title="You might like"
|
||||||
|
ariaLabel="You might like albums"
|
||||||
|
>
|
||||||
|
{#snippet item(album: import('$lib/api/types').AlbumRef)}
|
||||||
|
<div class="w-40"><AlbumCard {album} /></div>
|
||||||
|
{/snippet}
|
||||||
|
</HorizontalScrollRow>
|
||||||
|
{/if}
|
||||||
|
{#if data.you_might_like_artists.length > 0}
|
||||||
|
<HorizontalScrollRow
|
||||||
|
rows={[data.you_might_like_artists]}
|
||||||
|
title={data.you_might_like_albums.length === 0 ? 'You might like' : undefined}
|
||||||
|
ariaLabel="You might like artists"
|
||||||
|
>
|
||||||
|
{#snippet item(artist: import('$lib/api/types').ArtistRef)}
|
||||||
|
<div class="w-36"><ArtistCard {artist} /></div>
|
||||||
|
{/snippet}
|
||||||
|
</HorizontalScrollRow>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Recently added: 50 albums in 2 rows of 25, scrolling together -->
|
<!-- Recently added: 50 albums in 2 rows of 25, scrolling together -->
|
||||||
<section class="space-y-3">
|
<section class="space-y-3">
|
||||||
{#if data.recently_added_albums.length === 0}
|
{#if data.recently_added_albums.length === 0}
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ vi.mock('$lib/api/home', () => ({
|
|||||||
most_played_tracks: [],
|
most_played_tracks: [],
|
||||||
rediscover_albums: [],
|
rediscover_albums: [],
|
||||||
rediscover_artists: [],
|
rediscover_artists: [],
|
||||||
last_played_artists: []
|
last_played_artists: [],
|
||||||
|
you_might_like_albums: [],
|
||||||
|
you_might_like_artists: []
|
||||||
},
|
},
|
||||||
isPending: false,
|
isPending: false,
|
||||||
isError: false,
|
isError: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user