From 8cd56a433e9e8be7251512396ed35e5450abc5f6 Mon Sep 17 00:00:00 2001 From: KeelrLeek <156356974+KeelrLeek@users.noreply.github.com> Date: Mon, 3 Aug 2026 17:18:25 -0500 Subject: [PATCH] player bar: the album line survives library plays, and lands with the title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two halves of one defect family. The meta line preferred the queue item's artist/album fields as a PAIR whenever either existed — but a library play (playAlbum) writes only `artist`, with the record's name living inside `sub` ("artist — album"), so `album: null` was taken at face value and every library album lost its name from the bar (and the morning comment claiming local rows carry neither field was simply wrong). Each half now falls back to the `sub` split on its own, here and in the rail's byline — which also restores the album for continuation items whose `sub` is a bare artist. And the line no longer trickles in: the buffering branch used to render the artist alone, so the album flashed in a beat after the title when playback started. The status gate is replaced by a REAL distinction — a resolver-phase track has no `path` (playQueueIndex always writes one), so "finding best source…" still shows as a bare label, and the moment a real queue item owns the transport the full clickable line renders, buffering or not. Measured: the first frame carrying the new title already carries artist · album; no artist-only frame exists. --- src/components/NowPlaying.svelte | 10 +++++++++- src/components/PlayerBar.svelte | 34 ++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/components/NowPlaying.svelte b/src/components/NowPlaying.svelte index 7db3e81..120a7d0 100644 --- a/src/components/NowPlaying.svelte +++ b/src/components/NowPlaying.svelte @@ -104,11 +104,19 @@ return sub.includes(" — ") ? sub.split(" — ")[0].trim() : sub; }); // Artist / album split for the separate, clickable identity lines. + // Per field, like the player bar's: the item's own artist/album win when + // present (the continuation fill writes them beside a bare-artist `sub`), + // and each half falls back to the `sub` split on its own — a library play + // carries only `artist`, with the record's name living inside `sub`. const metaParts = $derived.by(() => { const sub = player.track?.sub ?? ""; - return sub.includes(" — ") + const split = sub.includes(" — ") ? sub.split(" — ").map((s) => s.trim()) : [sub.trim(), ""]; + return [ + currentItem?.artist ?? split[0] ?? "", + currentItem?.album ?? split[1] ?? "", + ]; }); const LOSSLESS = new Set(["FLAC", "WAV", "ALAC", "AIFF", "APE"]); diff --git a/src/components/PlayerBar.svelte b/src/components/PlayerBar.svelte index 9609c15..ac47d28 100644 --- a/src/components/PlayerBar.svelte +++ b/src/components/PlayerBar.svelte @@ -43,21 +43,23 @@ const canScratch = $derived(!currentItem?.stream); /** Artist and album for the separate, clickable meta lines. * - * The queue item's OWN `artist` / `album` fields come first, and splitting - * `sub` on the em dash is only the fallback. `sub` is a display convenience - * that not every path fills the same way: the album-continuation fill - * (`maybeExtendAlbumQueue`) writes a bare artist into it while carrying the - * album right alongside, so a record played straight through lost its album - * name from the second track on — which is exactly what it looked like. - * Local library rows carry neither field, and those still fall back. */ + * Per FIELD, not all-or-nothing. The queue paths disagree about what an + * item carries: the album-continuation fill writes artist AND album + * fields beside a bare-artist `sub`; a library play (`playAlbum`) writes + * only `artist`, with the record's name living inside `sub` + * ("artist — album"); old restored items may carry neither. Preferring + * the item's fields as a PAIR whenever either existed took `album: null` + * at face value and erased the record from every library play — each + * half now falls back to the `sub` split on its own. */ const metaParts = $derived.by(() => { - if (currentItem?.artist || currentItem?.album) { - return [currentItem.artist ?? "", currentItem.album ?? ""]; - } const sub = player.track?.sub ?? ""; - return sub.includes(" — ") + const split = sub.includes(" — ") ? sub.split(" — ").map((s) => s.trim()) : [sub.trim(), ""]; + return [ + currentItem?.artist ?? split[0] ?? "", + currentItem?.album ?? split[1] ?? "", + ]; }); const volumeIcon = $derived( player.muted || player.volume === 0 @@ -791,8 +793,14 @@ - {#if player.status === "buffering"} - {metaParts[0] || "buffering…"} + + {#if player.track && !player.track.path} + {player.track.sub || "buffering…"} {:else if player.track && (metaParts[0] || metaParts[1])} {#if metaParts[0]}