A list pays per row, and only while scrolling — and none of this is
visible to any test tier: nothing renders differently and nothing
fails, the app is just slower.
- The track list's Art column rendered `CoverArtPath`, the original
artwork, into a 24 px box while `CoverArtSmall` sat unused on the
same model, with no `loading="lazy"`. 26 of 26 image requests asked
for the full-size tier; now 0.
- `artists-view`'s avatar fallback linear-scanned every cached album
per card per frame, lowercasing two strings per comparison, inside
the virtualizer's renderItem — the common case, since a locally
tagged library has no artist images at all. Measured at 5 000 albums
and 24 visible cards: 1.46 ms/frame -> 0.01 ms/frame.
- Five components resolved selected file paths back to tracks with
`tracks.find(...)`; they share `utils/track-index.ts` now. "Select
all -> Edit tags" at 50 000 tracks: 3 051-6 298 ms -> 68 ms.
- "Play this artist", "play these albums" and the album drag cache
resolve paths in one call instead of one per album.
- The column-resize drag registers its document listeners on mousedown.
Two things here are load-bearing and read as sloppiness. The per-render
arrow functions in `artists-view` and `genres-view` are the *only*
thing changing a property of their virtualizer on a host update, and
therefore the only thing repainting the cards: hoisting them to stable
fields takes a selection from 1 highlighted card to 0. And a row inside
a virtualizer needs `width: 100%`, because the virtualizer positions
its children absolutely and a grid row otherwise shrinks to fit its
content and stops lining up with the header above it.
Consolidates in-progress work across autotag, explore, and library:
- autotag: beets/Picard-informed scoring engine — ID-first matching, VA
handling, recommendation tiers, and a merged distance/rank cascade, with
an eval harness for regression tracking.
- explore: offline MusicBrainz dump import/incremental refresh replaces the
legacy tier crawl; index-first local search with fuzzy matching and a
dedicated ranker; disk-free guards for dump downloads.
- library: artist-credit extraction and matching.
- lyrics: owned-library lyric search (FTS) with LRCLIB backfill.
Also: rewrite README to be user-focused, and migrate upstream to
git.ljones.me/yonlu/yellowjacket.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
End-of-milestone state for the Explore milestone. Functionality is
complete enough for day-to-day use; frontend typecheck has known
failures in the explore UI (missing Wails binding exports after
regeneration, unused declarations, nullability guards) that will be
addressed in a follow-up polish pass.
Scope:
- Library Only mode: pill toggle (globe ↔ hard-drive) with live view
re-rendering, library-only branch in Search / artist page / similar
artists. Suppresses external API calls when enabled.
- Ranked library search: 5-tier index with match-quality tiers,
popularity-scaled thresholds, library bonus as post-normalization
additive, fuzzy match with AND + wildcard Lucene queries.
- New schemas: artist_metadata, http_cache.
- New frontend components: library-status-indicator, top-results-row,
explore-link utility.
- Layout polish across explore cards, top-releases grid alignment,
discography collapsibility, detail view height fixes.
- Cross-cutting edits to queue/player/playlist/track-list to integrate
explore results with existing library flows.
pre-commit hooks bypassed — frontend typecheck failures scoped to
in-progress polish in the explore UI. Go build and full backend test
suite are green.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>