From c0d5d6aebfa56f965064b927385682289634bd5b Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Mon, 1 Jun 2026 20:55:54 -0400 Subject: [PATCH 1/3] feat(web): Most Played horizontal compact tiles + revert Rediscover MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator clarification: the 'compact like the app' request was for Most Played, not Rediscover. - CompactTrackCard rewritten as a horizontal Row: cover thumbnail left, title + artist column right. w-72 (~288 px) matches the Android CompactTrackTile's 176 dp visual weight. Most Played's existing chunked-rows-in-shared-scroller layout now reads like the Android multi-row LazyHorizontalGrid. - Rediscover steps back from the compact w-32/w-28 widths to w-40/ w-36 (the pre-PR-#66 sizes) — the size hierarchy still works with the regular AlbumCard treatment. --- .../lib/components/CompactTrackCard.svelte | 20 +++++++++++++------ web/src/routes/+page.svelte | 12 +++++------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/web/src/lib/components/CompactTrackCard.svelte b/web/src/lib/components/CompactTrackCard.svelte index ed526455..2588bb7a 100644 --- a/web/src/lib/components/CompactTrackCard.svelte +++ b/web/src/lib/components/CompactTrackCard.svelte @@ -5,6 +5,11 @@ import TrackMenu from './TrackMenu.svelte'; import CardActionCluster from './CardActionCluster.svelte'; + // Horizontal compact track row — cover thumb on the left, title + + // artist on the right. Mirrors Android's CompactTrackTile so the + // Most Played section reads the same way across platforms (three + // narrow rows that scroll together). + let { track, sectionTracks, @@ -32,24 +37,27 @@ } -
+
{#snippet item(album: import('$lib/api/types').AlbumRef)} - -
+ +
{/snippet} {/if} @@ -214,7 +212,7 @@ ariaLabel="Rediscover artists" > {#snippet item(artist: import('$lib/api/types').ArtistRef)} -
+
{/snippet} {/if} From 27f1cefd5550a6a32a93adcf4361623eb5065e4f Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Mon, 1 Jun 2026 20:58:05 -0400 Subject: [PATCH 2/3] fix(web): center nav in window + Library link + Search placeholder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three operator-reported issues: - Header was flex with the nav inside a flex-1 span — when the right side (search + user menu) grew wider than the left (wordmark), the nav's centered position drifted off page-center. Switched to grid-cols-3 with justify-self-{start,center,end} so the middle column pins to true window-center regardless of side widths. - Library nav link pointed to /library, which 308-redirects via +page.server.ts. Operator reported it didn't navigate. Linked the nav button directly to /library/artists so SPA navigation skips the redirect roundtrip. matchPrefix='/library' keeps isActive matching every Library tab. - SearchInput placeholder was 'Search artists, albums, tracks…' — shortened to 'Search' and added a Lucide Search icon inside the input on the left. Padding adjusted (pl-7) so the input text clears the icon. --- web/src/lib/components/SearchInput.svelte | 27 ++++++++++++------- web/src/lib/components/Shell.svelte | 33 ++++++++++++++++------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/web/src/lib/components/SearchInput.svelte b/web/src/lib/components/SearchInput.svelte index 174fd5e2..ef642d3c 100644 --- a/web/src/lib/components/SearchInput.svelte +++ b/web/src/lib/components/SearchInput.svelte @@ -2,6 +2,7 @@ import { page } from '$app/state'; import { goto } from '$app/navigation'; import { untrack } from 'svelte'; + import { Search } from 'lucide-svelte'; let value = $state(page.url.searchParams.get('q') ?? ''); let timeout: ReturnType | null = null; @@ -51,12 +52,20 @@ } - + diff --git a/web/src/lib/components/Shell.svelte b/web/src/lib/components/Shell.svelte index 747da9c6..cb9fe4c9 100644 --- a/web/src/lib/components/Shell.svelte +++ b/web/src/lib/components/Shell.svelte @@ -36,9 +36,9 @@ goto('/login', { replaceState: true }); } - function isActive(href: string): boolean { - if (href === '/') return page.url.pathname === '/'; - return page.url.pathname.startsWith(href); + function isActive(prefix: string): boolean { + if (prefix === '/') return page.url.pathname === '/'; + return page.url.pathname.startsWith(prefix); } // Primary nav. Sits centered in the top bar (replaces the prior left @@ -46,22 +46,33 @@ // destinations, plus Library acting as a parent for Artists / Albums / // Liked / History / Playlists (tabs at /library/+layout.svelte). // Search + user menu live on the right side of the header (unchanged). + // Library targets the Artists tab directly so SPA navigation doesn't + // bounce through the /library 308-redirect. isActive('/library') + // still matches all sub-routes by prefix so the active state covers + // every tab. const navItems = [ - { href: '/', label: 'Home', icon: House }, - { href: '/library', label: 'Library', icon: LibraryBig }, - { href: '/discover', label: 'Discover', icon: Compass } + { href: '/', label: 'Home', icon: House, matchPrefix: '/' }, + { href: '/library/artists', label: 'Library', icon: LibraryBig, matchPrefix: '/library' }, + { href: '/discover', label: 'Discover', icon: Compass, matchPrefix: '/discover' } ]; e.key === 'Escape' && (menuOpen = false)} />
-
- {appName()} + +
+ + {appName()} + -
{/if}
+