Commit Graph
5 Commits
Author SHA1 Message Date
KeelrLeek df3d15553a playlists + lyrics: setlists with pages of their own, and the words timed to the voice 2026-08-17 18:05:31 -05:00
KeelrLeekandClaude Opus 5 9aeb6c39c7 player bar: one row, aligned to the sidebar's column, and it says who is sending
88px becomes 62px and the two stacked rows become one. The 26px goes back to
the content area on every screen, and the scrubber stops capping at 560px while
the flanks stretch — a 1900px window used to put a small waveform adrift in the
middle of an empty bar.

The cover is 40x40 at 12px of padding, which lands its centre on x=40: the
column every sidebar cover and nav icon already shares, and which the sidebar
holds through its entire collapse. It was 56px at 16px, centre x=52 — twelve
pixels out of a column the app is otherwise strict about.

The waveform is drawn as discrete bars on the Now Playing rail's exact pitch, a
2px bar on a 4px gap with a 1px radius, both deriving their count from that one
pitch so neither can drift from the other. Mirrored here, where the lane is
short and wide; the rail stands its bars on the floor because it sits above a
caption. The standing white playhead went with it — at this pitch it read as a
seam through the bars, and the accent's own leading edge marks the position.

Artist and album share one line as "Artist · Album", the `.who` idiom from the
album page rather than a new one. They are read from the queue item's OWN
artist/album fields now: `sub` is a display convenience that the album
continuation fill writes as a bare artist while carrying the album right
alongside, so a record played straight through lost its album name from the
second track on. When the line must shrink the ALBUM shrinks — proportional
shrinking turned a short artist into "Po…", which saves nothing and reads as
nothing.

New: the source line. Who is sending this track, how much has arrived, how fast
and how long is left, then the format. Four states, derived exactly as
NowPlaying derives its status line — two surfaces disagreeing about whether a
track is cached would be worse than either being wrong. A library file reports
NOTHING, because it has no peer and no transfer and zeroes would read as a
stalled one. It sits in its own slot rather than inside the meta cluster:
sharing that budget let a live transfer readout crowd the artist and album down
to "Po… · Terrestria…". Its width is measured per STATE and never per value, so
a ticking percentage and a counting-down ETA move nothing.

The now-playing panel toggle is gone from the shelf — the panel carries its own
collapse control, and two ways to do one thing is one too many. What replaces it
is a single overflow menu, so landing lyrics, a mini player and output switching
later costs no width; those three are present and disabled, marked SOON, rather
than wired to nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 07:04:11 -05:00
KeelrLeek eba29824c9 sidebar and artist pipeline: one list in the rail, recents anchored to ids, and popular takes its own lane 2026-07-31 18:21:04 -05:00
KeelrLeek 7a517dca59 navigation: one glass bar for every page, with a history and a path in it
The glass bar was copied into two views and each carried its own contextual
back link — "Results" on the artist page, the artist's name on the album page.
It is a shared component now (src/components/GlassBar.svelte), and it carries
the app's navigation: back/forward arrows, and the trail to where you are.

**History and the trail are different things, and the file keeps them apart.**
History is a SEQUENCE — every place visited, in order — and it drives the
arrows. The trail is a HIERARCHY, derived from the current place, never from
history. That is why switching between two editions of a record adds a history
step but does not add a crumb: a breadcrumb built out of history would read
`Search › Weezer › Blue Album › Deluxe Edition`, which says the deluxe sits
inside the original. It does not.

Crumbs improve in place. An artist page opens on an id and learns its name and
portrait a moment later, so the crumb starts as a placeholder and is refreshed
through ONE call site (`rememberArtistSeed`), guarded so remembering a seed for
a row in some list can never rewrite where you are. Search results are the
journey's root rather than a bare "Search" — the crumb reads “weezer”, which
is the thing you actually want to get back to.

Arriving crumbs slide in from the right; only genuinely new ones animate, so an
ancestor that was already there does not re-run its entrance when the tail
changes. Chosen from four motions mocked against a real navigation stack.

Every navigation now goes through a recorder. A bare `ui.view = "…"` is a
destination the back arrow can never return to, so the sidebar routes through
`goToView` and the catalog openers record on arrival.

**Scroll position is remembered.** Going back returns you to the paragraph you
left; arriving somewhere new starts at its top. The difference is exactly
whether the move came from the arrows/trail or from a fresh click. Two details
that mattered: the offset is captured at the START of a navigation, because the
scroll pane outlives the view swap and by the time a page has been replaced its
scrollTop already belongs to its successor; and restoring is not one assignment
— the artist page paints a skeleton, then an overview, then the full
discography, so a single `scrollTop = 900` clamps to whatever height exists in
that frame and lands near the top. It re-applies until the target is reachable
and gives up the instant the reader touches wheel, key or trackpad. The album
page never reset its scroll at all, so a record opened from half-way down an
artist page began half-way down; it does now.

**The artwork lightbox serves any cover.** It was hardwired to the playing
queue item; `ui.fullscreenArt` (a boolean) is now `ui.artwork` (a descriptor),
so Now Playing, the artist page's expander rail and the album hero all open the
same viewer with their own `{src, local, title, subtitle}`. Each passes the
UPGRADED cover rather than the sized variant it paints — the point of the
viewer is the master resolution.

Hovering artwork offers it: the whole element lifts under a light wash with the
expand mark centred. `transform`, not a width change — on the album page the
copy column is sized to end level with the artwork, so a reflowing hover would
twitch the entire hero. The three numbers (--art-grow 1.035, --art-motion
160ms, --art-wash) live in global.css rather than being typed into three files.
Now Playing's corner expand disc is gone: one gesture for "open this artwork"
everywhere instead of a disc in one place and a lift in the others.

On the artist page the expander's album NAME now opens that record's page.

Also removed: the album page's scroll-triggered title takeover. The breadcrumb
names the record permanently, which made it redundant — the build was already
flagging its CSS as dead.

**And the fix this session actually turned on.** Kyle reported the album
tracklist's counts as "heavily glitched": Pinkerton showed El Scorcho at 636
listeners beside Tired Of Sex at 606,324. Switching the column from plays to
listeners changed nothing, because both were wrong for the same reason.

`artist.gettoptracks` returns a popular song many times over — once as itself,
then again for every "(Album Version)", live cut and remaster — listeners
descending. The fold meant to keep the first entry, and its comment said so,
but it was written `if by_key.insert(k, v).is_some() { continue }`.
`HashMap::insert` returns the previous value AND STILL OVERWRITES, so the guard
correctly skipped the ranked push while letting every later duplicate win the
map the album tracklist reads. The last re-listing — the most obscure pressing
— is what reached the screen.

Measured against the live API for Weezer: Buddy Holly is rank 1 at 2,351,642
listeners and rank 679 as "(Album Version)" at 1,919; the page printed 1,919.
My Name Is Jonas 1,100,251 → 870. El Scorcho 654,071 → 636. Pink Triangle
810,659 → 6,070. Only songs Last.fm lists exactly once — "Tired of Sex",
"Across the Sea" — were ever right, which is why the column looked plausible in
places and absurd in others. Twenty-four entries for "The Good Life", twenty
for "El Scorcho".

The fold is now `fold_lastfm_duplicates`, pinned by two tests using those real
figures. It also repairs Popular's plays and the album totals, which read the
same map. The tracklist column shows listeners in both places it appears — the
album page and the artist page's expander — because leaving one on plays would
have let one record disagree with itself.

152 Rust tests and 85 JS tests pass.
2026-07-28 16:40:31 -05:00
KeelrLeek a667b4b28e Baseline: full tree snapshot after git repository loss
The previous .git directory was found gutted (only info/ remained), so
history is unrecoverable locally. This commit restores version control
with the tree exactly as it stands: the working app, the preview-tracks
launcher on the artist hero, the scrollable-track-previews design bundle
(docs + approved mockups), and the Phase 0 validation artifacts.
2026-07-22 17:57:00 -05:00