diff --git a/web/src/lib/components/HomeHeroCard.svelte b/web/src/lib/components/HomeHeroCard.svelte deleted file mode 100644 index 4c4e6445..00000000 --- a/web/src/lib/components/HomeHeroCard.svelte +++ /dev/null @@ -1,75 +0,0 @@ - - - -
- -
-
-
-
{eyebrow}
-
- {title} -
- {#if subtitle} -
{subtitle}
- {/if} -
- -
-
diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 60cf8d5a..2980abe5 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -3,13 +3,6 @@ import { createHomeQuery } from '$lib/api/home'; import HorizontalScrollRow from '$lib/components/HorizontalScrollRow.svelte'; import AlbumCard from '$lib/components/AlbumCard.svelte'; - import HomeHeroCard from '$lib/components/HomeHeroCard.svelte'; - import { systemShuffle, getPlaylist } from '$lib/api/playlists'; - import { playlistTrackToRef } from '$lib/playlists/playlistTrackToRef'; - import { playQueue } from '$lib/player/store.svelte'; - import { api } from '$lib/api/client'; - import { coverUrl as albumCoverUrl } from '$lib/media/covers'; - import type { AlbumDetail, TrackRef as TrackRefType } from '$lib/api/types'; import ArtistCard from '$lib/components/ArtistCard.svelte'; import CompactTrackCard from '$lib/components/CompactTrackCard.svelte'; import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte'; @@ -82,46 +75,6 @@ const userPlaylists = $derived(userPlaylistsQ.data?.owned ?? []); - // Hero row: For-You + most-recently-added album. Anchors the page - // so the eye lands on these instead of cascading down a wall of - // identical tiles. - const latestAlbum = $derived(data?.recently_added_albums?.[0] ?? null); - - function albumCoverFor(albumId: string | undefined | null): string { - return albumId ? albumCoverUrl(albumId) : ''; - } - - let heroStarting = $state(false); - - async function playForYou(e: MouseEvent) { - e.preventDefault(); - e.stopPropagation(); - if (heroStarting || !forYouPlaylist?.system_variant) return; - heroStarting = true; - try { - const detail = await systemShuffle(forYouPlaylist.system_variant); - const refs = detail.tracks - .map((r) => playlistTrackToRef(r)) - .filter((t): t is TrackRefType => t !== null); - if (refs.length > 0) playQueue(refs, 0, { source: forYouPlaylist.system_variant }); - } finally { - heroStarting = false; - } - } - - async function playLatestAlbum(e: MouseEvent) { - e.preventDefault(); - e.stopPropagation(); - if (heroStarting || !latestAlbum) return; - heroStarting = true; - try { - const detail = await api.get(`/api/albums/${latestAlbum.id}`); - if (detail.tracks.length > 0) playQueue(detail.tracks, 0); - } finally { - heroStarting = false; - } - } - type PlaceholderVariant = 'building' | 'failed' | 'pending' | 'seed-needed'; function placeholderVariant(slot: 'for-you' | 'discover' | 'songs-like'): PlaceholderVariant { const s = systemStatusQ.data; @@ -181,40 +134,6 @@ {pageTitle('Home')}
- - {#if forYouPlaylist || latestAlbum} -
- {#if forYouPlaylist} - 0 - ? `${forYouPlaylist.track_count} tracks for you` - : 'Building your mix'} - onPlay={playForYou} - playDisabled={heroStarting || forYouPlaylist.track_count === 0} - /> - {/if} - {#if latestAlbum} - - {/if} -
- {/if} -
{#snippet item(album: import('$lib/api/types').AlbumRef)} - -
+ +
{/snippet}
{/if} @@ -292,7 +214,7 @@ ariaLabel="Rediscover artists" > {#snippet item(artist: import('$lib/api/types').ArtistRef)} -
+
{/snippet} {/if} diff --git a/web/src/routes/page.test.ts b/web/src/routes/page.test.ts index 70fbff51..51df7407 100644 --- a/web/src/routes/page.test.ts +++ b/web/src/routes/page.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; -import { render, screen, within } from '@testing-library/svelte'; +import { render, screen } from '@testing-library/svelte'; import { readable } from 'svelte/store'; import { emptyLikesMock } from '../test-utils/mocks/likes'; import type { Playlist } from '$lib/api/types'; @@ -103,11 +103,7 @@ describe('home Playlists section', () => { : readable({ data: emptyPlaylistsResponse, isPending: false, isError: false }) ); render(Page); - // For-You renders twice: once in the new hero card at the top of - // Home and once in the Playlists carousel. Scope the assertion - // to the Playlists section to avoid the hero collision. - const playlistsSection = screen.getByLabelText('Playlists'); - expect(within(playlistsSection).getByText('For You')).toBeInTheDocument(); + expect(screen.getByText('For You')).toBeInTheDocument(); const placeholders = screen.queryAllByTestId('playlist-placeholder-card'); // 1 Discover + 3 Songs-like slots = 4 placeholders alongside the // real For-You tile. @@ -147,11 +143,7 @@ describe('home Playlists section', () => { : readable({ data: emptyPlaylistsResponse, isPending: false, isError: false }) ); render(Page); - // For-You also renders in the hero card; scope to the Playlists - // section. The secondary kinds aren't featured in the hero, so - // their getByText assertions can stay document-scoped. - const playlistsSection = screen.getByLabelText('Playlists'); - expect(within(playlistsSection).getByText('For You')).toBeInTheDocument(); + expect(screen.getByText('For You')).toBeInTheDocument(); expect(screen.getByText('Deep cuts')).toBeInTheDocument(); expect(screen.getByText('New for you')).toBeInTheDocument(); });