yonlu
4ac8a7c5af
chore(Q2): auto-commit after quick-task
2026-03-23 23:46:27 -04:00
yonlu
6ee16c7a87
feat(S03/T01): Add explore-artist-details Lit component with artist hea…
...
- frontend/src/components/explore-artist-details/explore-artist-details.ts
- frontend/index.ts
2026-03-23 23:33:27 -04:00
yonlu
5451e70a0c
chore(M004/S02): auto-commit after complete-slice
2026-03-23 17:45:08 -04:00
yonlu
677ed01d89
feat(S02/T01): Added CoverArtGroupURL for release-group cover art, conc…
...
- backend/explore/coverart.go
- backend/explore/explore.go
- backend/explore/coverart_test.go
- frontend/wailsjs/go/explore/Service.js
- frontend/wailsjs/go/explore/Service.d.ts
2026-03-23 17:31:01 -04:00
yonlu
1ff53d8084
chore(M004/S01): auto-commit after complete-slice
2026-03-23 16:55:22 -04:00
yonlu
6cc9acbc99
perf(S01/T02): Add MusicBrainz search/lookup/browse client, ListenBrain…
...
- backend/explore/types.go
- backend/explore/musicbrainz.go
- backend/explore/listenbrainz.go
- backend/explore/coverart.go
- backend/explore/coverart_test.go
2026-03-23 14:03:51 -04:00
yonlu
8fc075c24a
perf(S01/T01): Add token-bucket rate limiter (1 req/sec), SQLite respon…
...
- backend/explore/ratelimiter.go
- backend/explore/cache.go
- backend/database/sql/schemas/explore_cache.sql
- backend/database/database.go
2026-03-23 07:55:25 -04:00
yonlu
398fd5aaae
chore(M004/S01): auto-commit after state-rebuild
2026-03-22 23:25:58 -04:00
yonlu
916b5ef753
fix: add missing playCount and lastPlayed args to mapTrackRow test calls
...
The mapTrackRow signature was extended with playCount and lastPlayed
fields in the play history feature, but the scan_test.go callers
were not updated, breaking go vet and golangci-lint.
2026-03-22 11:10:59 -04:00
yonlu
f7ca138296
fix: flush BufferedStreamer ring buffer on seek to prevent stale audio
...
When seeking, the underlying decoder position was updated but the
BufferedStreamer's ring buffer still contained up to 2 seconds of
pre-seek audio data. The speaker would drain this stale buffer
before playing audio from the new position, causing an audible
delay where the old position's audio continued playing.
Add a Flush() method to BufferedStreamer that resets the ring buffer
pointers, and call it in seekLocked() immediately after a successful
seek. This ensures the speaker starts playing from the seeked
position without any stale audio artifact.
2026-03-22 11:10:53 -04:00
yonlu
3173b78a87
chore(Q1): auto-commit after quick-task
2026-03-22 11:07:17 -04:00
yonlu
c7bf5271e6
fix: simplify play count accessor, remove right-align to debug rendering
2026-03-22 10:52:58 -04:00
yonlu
c5b293d410
chore: update sqlcgen models with play_count/last_played fields
...
Auto-generated by sqlc from updated schema. Adds PlayCount/LastPlayed
to AudioFile and TrackMetadatum structs, and PlayHistory model.
2026-03-22 10:48:35 -04:00
yonlu
7cde7cc7b8
fix: play count display and live update after playback
...
- Column accessor shows '0' instead of empty string for unplayed tracks
- recordPlay emits TrackMetadataChanged event after updating DB
- Frontend library store invalidates on that event, refreshing play counts
2026-03-22 09:42:18 -04:00
yonlu
e1bfe12903
fix: register playCount column in backend AllColumnIDs + rename to 'Play Count'
...
Backend validation rejected 'playCount' as unknown column ID, silently
preventing it from being enabled or persisted. Added ColPlayCount to
the tracklist package's constant list and AllColumnIDs slice.
2026-03-21 22:53:52 -04:00
yonlu
2db6e09aa3
fix: use sql.NullTime for last_played to handle NULL scan
...
COALESCE(last_played, '') returned empty string which can't scan into
time.Time. Removed COALESCE, use sql.NullTime instead. Format to string
only when Valid.
2026-03-21 15:40:34 -04:00
yonlu
b643aee5a3
fix: mapTrackRow accepts time.Time for LastPlayed (matches sqlcgen Row type)
2026-03-21 15:36:59 -04:00
yonlu
2ee157a376
feat(M003/S03): play count column + data pipeline
...
Backend:
- GetAllTracksWithFullMetadata queries now select play_count and last_played
- mapTrackRow accepts and passes through PlayCount/LastPlayed
- PlayCount + LastPlayed added to library.Track struct
- sqlcgen Row types updated with new fields
Frontend:
- PlayCount + LastPlayed added to library.Track TypeScript model
- 'Plays' column added to track-list column definitions (60px, right-aligned, sortable)
Queries without play data (search, genre, album) pass 0/empty defaults.
2026-03-21 15:33:08 -04:00
yonlu
9c85cfcc7b
feat(M003/S02): smart playlist integration — play_count and days_since_played fields
...
Backend:
- Added play_count and days_since_played to rule engine field whitelist
- days_since_played uses julianday() expression with COALESCE for NULL handling
- Never-played tracks (NULL last_played) match 'greater_than' but not 'less_than'
- Added PlayCount + LastPlayed to library.Track struct
- Evaluate query selects play_count and last_played from track_metadata
- Added play_count to sort field options
Frontend:
- Added play_count and days_since_played to field and numeric field lists
- Added play_count to sort options
All 49 rule engine + 15 service tests pass unchanged.
2026-03-21 15:26:43 -04:00
yonlu
9bf2bbab2e
feat(M003/S01): play history tracking — schema, migration, recording hook
...
Migration 10:
- play_history table (audio_file_id FK, played_at DATETIME, CASCADE delete)
- play_count + last_played columns on audio_files (denormalized)
- Recreated track_metadata VIEW with play_count and last_played columns
Play recording:
- queue.recordPlay() inserts play_history row + updates denormalized columns
- Called from OnPlaybackFinished after queue advance completes
- Mutex released before DB write to avoid MaxOpenConns(1) deadlock
- Natural finish only — skip/stop does not count
Tests:
- TestMigration10PlayHistory: schema, columns, VIEW, round-trip verification
- All 49 smart playlist + 15 service + existing DB tests still pass
2026-03-21 15:23:18 -04:00
yonlu
ebaa856e0c
fix: align combobox height to operator select via grid stretch
...
- Grid rows use align-items: stretch so all cells share the select's height
- Combobox host, wrapper, and input all set height: 100% to fill the cell
- Remove button uses align-self: center to stay centered instead of stretching
2026-03-21 13:46:26 -04:00
yonlu
288215a97c
fix: match combobox input height to select dropdowns
2026-03-21 13:40:07 -04:00
yonlu
6972953649
fix: smart playlist UX polish — layout, defaults, free-form input, case-insensitive matching
...
Details view:
- Skip evaluation on new playlists (was returning all 25k tracks)
- Go straight to editor on auto-edit instead of awaiting loadTracks
Editor:
- Default sort to Random instead of None, remove None option
- Hide sort direction button when sort is Random
- Fixed-width field (160px) and operator (140px) columns, value fills remaining space
- Preview fills remaining vertical space (flex layout) instead of fixed 200px max-height
- Preview scrolls independently while rules/options stay pinned
Combobox:
- Accept free-form text on blur and Enter — no longer requires selection from dropdown
- Enables typing values like 'indie' that may not be exact DB entries
Backend:
- Case-insensitive text matching: COLLATE NOCASE on is/is_not/is_any_of operators
- Applies to both regular fields and genre subqueries
- LIKE operators were already case-insensitive (SQLite default)
2026-03-21 13:25:21 -04:00
yonlu
477b7ff6a2
feat(M002): smart playlists — rule engine, editor UI, sidebar integration
...
Recovered from orphaned worktree commits (complete-milestone failed to merge).
Backend:
- Migration 9: is_smart + smart_rules columns on playlists table
- smartplaylist package: parameterized WHERE clause builder, field whitelist, genre subquery
- playlist.Service: Create/Update/Evaluate/Preview/GetRules smart playlist methods
- 65 tests (49 rule engine + 15 service + 1 migration)
Frontend:
- yj-combobox: reusable typeable dropdown with keyboard nav, ARIA, blur-race fix
- smart-playlist-editor: row-based rule builder with live preview
- smart-playlist-details: evaluate, refresh, play, shuffle, edit rules
- Sidebar: filter icon, Smart badge, create button, routing
- Queue snapshot on play/shuffle
2026-03-21 12:53:00 -04:00
github-actions[bot]
cf92f10566
chore(release): 1.3.0 [skip ci]
...
## [1.3.0](https://github.com/onion-4-dinner/yellowjacket/compare/v1.2.3...v1.3.0 ) (2026-03-20)
### Features
* **09-01:** add scan control events and cancelled metrics field ([c695024 ](https://github.com/onion-4-dinner/yellowjacket/commit/c695024241a7513b8fedb3fbf7ff364d0515b392 ))
* **09-01:** add scan control fields and per-scan cancellable context ([cf22e52 ](https://github.com/onion-4-dinner/yellowjacket/commit/cf22e52a64850a80b9fcc63c21d81313e6bd56ab ))
* **09-02:** add frontend keyboard shortcut service, store, and controller ([40d4815 ](https://github.com/onion-4-dinner/yellowjacket/commit/40d48151dd798b57eed9f54a572ae4735356d09e ))
* **09-02:** add shortcuts config package with default bindings and Wails persistence ([6285ca9 ](https://github.com/onion-4-dinner/yellowjacket/commit/6285ca9dc4e6f211197e377d01c485b1ef65c300 ))
* **09-03:** add scan control UI with pause/resume/cancel and confirmation dialog ([3914369 ](https://github.com/onion-4-dinner/yellowjacket/commit/391436927c826f2f17a4523be7829aefc04a6b12 ))
* **09-04:** add keyboard shortcuts section to config page with conflict detection ([0451fb3 ](https://github.com/onion-4-dinner/yellowjacket/commit/0451fb38805ff2c27e43deb152daa892e733d2db ))
* **10-01:** implement migration 6 and pre-migration backup ([1179f56 ](https://github.com/onion-4-dinner/yellowjacket/commit/1179f56c3680112692e71e8dc7ce946446fa8a8a ))
* **10-01:** update SQL schema files for multi-library fresh installs ([535855b ](https://github.com/onion-4-dinner/yellowjacket/commit/535855b383a457dd2be3298b4361313bef22b39d ))
* **10-02:** add migration 6 integration tests and NewTestDBWithLibrary helper ([bc15189 ](https://github.com/onion-4-dinner/yellowjacket/commit/bc151891b50e59e41da2e00dbfafbecaad11b4ac ))
* **10-02:** add sqlc queries for libraries and update playlist queries for phantom support ([02548dd ](https://github.com/onion-4-dinner/yellowjacket/commit/02548dd55e59b28f3d6c8d9614f209140c979250 ))
* **11-01:** per-library scan pipeline with queue coordinator ([943db1c ](https://github.com/onion-4-dinner/yellowjacket/commit/943db1cf274bdf59daf28ab6c20f78ef5ef53105 ))
* **11-02:** update config-page with per-library progress display and queue-aware cancel dialog ([d01591d ](https://github.com/onion-4-dinner/yellowjacket/commit/d01591d6cc054a63b832c05a3164a72fdcaba342 ))
* **11-02:** update library-manager with per-library progress and Scan All button ([d61f122 ](https://github.com/onion-4-dinner/yellowjacket/commit/d61f122b567e8ac2b30fa96c637cbebc14493c89 ))
* **12-01:** add queue compaction method and wire removal hooks ([5995dfd ](https://github.com/onion-4-dinner/yellowjacket/commit/5995dfd01d61cd4d2c0749eeeee2a1f93b739d68 ))
* **12-01:** implement library CRUD methods and orphan cleanup pipeline ([bd44f83 ](https://github.com/onion-4-dinner/yellowjacket/commit/bd44f8306c9129b9420ad81938bcf8105a1cb55a ))
* **12-02:** make config sections collapsible with chevron dropdown ([12c6782 ](https://github.com/onion-4-dinner/yellowjacket/commit/12c678284c7582bd85cd52722f4d405b0bd0e20f ))
* **12-02:** remove Libraries sidebar nav item and view routing ([e199712 ](https://github.com/onion-4-dinner/yellowjacket/commit/e199712a56e1cb3c0fc43d3340abb892a6f5fa7b ))
* **12-02:** replace config-page library section with full library management UI ([ffc5d96 ](https://github.com/onion-4-dinner/yellowjacket/commit/ffc5d9639cf7c916a4f846590ae0d67cf13afe27 ))
* **12-02:** selectable library list with checkbox scan targeting ([13a42ae ](https://github.com/onion-4-dinner/yellowjacket/commit/13a42aea2287d7ed0ec9ff9856f52c1fa7767338 ))
* **12-02:** show scan progress bar inline in library list entry ([df824c6 ](https://github.com/onion-4-dinner/yellowjacket/commit/df824c6989e92b2aefaa1ddf05b131ee319612d8 ))
* **13-01:** add library-filtered Go query methods and FTS search ([5f7de50 ](https://github.com/onion-4-dinner/yellowjacket/commit/5f7de5060a5bc557b96203267de694ef366ed507 ))
* **13-01:** add library-filtered sqlc queries for all browse views ([5cc58ce ](https://github.com/onion-4-dinner/yellowjacket/commit/5cc58ce66ab70d8d5a570df5067f79ae2201037e ))
* **13-02:** add library filter dropdown and wire all views to respect active filter ([42b8cf9 ](https://github.com/onion-4-dinner/yellowjacket/commit/42b8cf9f52133499ffcd7363bd39dd0c1069e091 ))
* **15-01:** migrate FTS5 search_index to contentless_delete=1 ([cb5155b ](https://github.com/onion-4-dinner/yellowjacket/commit/cb5155b8906357ff77c5c579d57d02cf2eec6abe ))
* **15-02:** create backend/fileutil package with AtomicWrite ([4d64b5d ](https://github.com/onion-4-dinner/yellowjacket/commit/4d64b5dcfe43951e8ec63383bbf72c99107c63c4 ))
* **16-01:** add selectAll() to SelectionController and dispatch shortcut:select-all event ([f567762 ](https://github.com/onion-4-dinner/yellowjacket/commit/f5677628ef283b67370630b564f23178e43da3d2 ))
* **16-01:** wire shortcut:select-all listener in track-list, queue-panel, and playlist-view ([906ea28 ](https://github.com/onion-4-dinner/yellowjacket/commit/906ea28751ce9f96fdeeb9410ab5f6518f09fcb9 ))
* **16-02:** add go-flac dependencies and implement FLAC tag writer ([3642cbe ](https://github.com/onion-4-dinner/yellowjacket/commit/3642cbe0d58f8912a786a4fc5380c40403add94a ))
* **16-03:** implement DB sync module for tag write pipeline ([2966079 ](https://github.com/onion-4-dinner/yellowjacket/commit/2966079625cd42412411429af02184d015526e9b ))
* **16-03:** WriteTrackTags pipeline with player safety, scan mutex, events, and app wiring ([64322f9 ](https://github.com/onion-4-dinner/yellowjacket/commit/64322f93538515d5a3e486dc14691b9c9dcf6f66 ))
* **17-01:** add TrackMetadataChanged handler and remove selection gate on Track Details ([fc5cf70 ](https://github.com/onion-4-dinner/yellowjacket/commit/fc5cf70e4c1be3d3f1545c140db5202601a08109 ))
* **17-01:** add WriteTrackTagsByPath and ImageFilePicker backend methods ([4235b4a ](https://github.com/onion-4-dinner/yellowjacket/commit/4235b4a4d555882ce86628a88dd4e4eeee2c9097 ))
* **17-02:** implement save flow, cover art editing, and error handling ([265a9ea ](https://github.com/onion-4-dinner/yellowjacket/commit/265a9ea8ceba893f956a03546e9ac4189adc7716 ))
* **18-01:** add BatchWriteProgress event constant ([3dba0e1 ](https://github.com/onion-4-dinner/yellowjacket/commit/3dba0e143c091327d305d39d2fa7a687ec47e172 ))
* **18-01:** add BatchWriteTrackTags with progress, cancellation, and partial failure ([f557ffd ](https://github.com/onion-4-dinner/yellowjacket/commit/f557ffd652179b7cf8f8ff4a06824f30edf08007 ))
* **18-02:** add batch edit mode to track-details component ([6dab32b ](https://github.com/onion-4-dinner/yellowjacket/commit/6dab32b36b497d54e8645e969aa79737ad3523ab ))
* **18-02:** wire batch track-details to all 4 view context menus ([656985a ](https://github.com/onion-4-dinner/yellowjacket/commit/656985add92663440baebb871f8cd6d5723117fd ))
* **19-01:** implement WAV RIFF parser/writer and writeWavTags ([e6610ff ](https://github.com/onion-4-dinner/yellowjacket/commit/e6610ff15e041213b6898ad48ff63b7060b312e7 ))
* **20-01:** implement OGG Vorbis tag writer with custom page parser and CRC32 ([5e98c03 ](https://github.com/onion-4-dinner/yellowjacket/commit/5e98c036342b9e174abdc6d00db21c2e2901f18b ))
* **quick-17:** create playlist-details subpage component ([dc5c7d6 ](https://github.com/onion-4-dinner/yellowjacket/commit/dc5c7d6ca6cfbfac15546c048f1b33aaf47209c6 ))
* **quick-18:** replace track-info with multi-column grid layout in playlist-details ([ce23177 ](https://github.com/onion-4-dinner/yellowjacket/commit/ce2317722870f932792dc6456a63235ff4611466 ))
### Bug Fixes
* **09-05:** emit VolumeChanged event and persist state in ChangeVolume and MuteToggle ([bb3fd20 ](https://github.com/onion-4-dinner/yellowjacket/commit/bb3fd204f0895f357a14479b40754f397aae74c4 ))
* **10-01:** move library_id index to migration 6 to fix existing DB startup ([75b2a34 ](https://github.com/onion-4-dinner/yellowjacket/commit/75b2a349ebd6fada5cbc92bfae9854cc2cd53c63 ))
* **12-02:** claim orphaned tracks when adding library with matching path ([f60b6b5 ](https://github.com/onion-4-dinner/yellowjacket/commit/f60b6b525546ef77a3329fe92f03f336b7435a0e ))
* **12-02:** count failed saves as skipped so scan progress bar advances ([b36e472 ](https://github.com/onion-4-dinner/yellowjacket/commit/b36e472212957ff089f4f5d35f3978a754e23502 ))
* **12-02:** delete artist_credit_artist before artist_credit in removal pipeline ([890284d ](https://github.com/onion-4-dinner/yellowjacket/commit/890284ddb1d0fb95e423bddf27b40fb0db2d11e5 ))
* **12-02:** dismiss inline rename on click outside ([9272b06 ](https://github.com/onion-4-dinner/yellowjacket/commit/9272b060bf98118e37f19a8c0834034691bfe6a2 ))
* **12-02:** downgrade per-file save error to Debug, add warning count to scan summary ([cf18c39 ](https://github.com/onion-4-dinner/yellowjacket/commit/cf18c39dbd849d60218228cf1d2285ab2071e788 ))
* **12-02:** invalidate library store cache on LibraryRemoved event ([b093fbb ](https://github.com/onion-4-dinner/yellowjacket/commit/b093fbb10a24054c4ef62b0bd13f28d9bfe6f121 ))
* **12-02:** keep Add Library button visible during scan ([649e516 ](https://github.com/onion-4-dinner/yellowjacket/commit/649e516aa30090665e9f10e89c1ccce378e36b96 ))
* **12-02:** move Add Library button inline with scan buttons ([771345d ](https://github.com/onion-4-dinner/yellowjacket/commit/771345dd9d3870b3a907e1cce09c7456ab7ccd85 ))
* **12-02:** move scan buttons above library list, default to none selected ([ba3f840 ](https://github.com/onion-4-dinner/yellowjacket/commit/ba3f840a28fe2c6ca40c558305814d29c233d6e0 ))
* **12-02:** refresh library track counts after scan completes ([1f872aa ](https://github.com/onion-4-dinner/yellowjacket/commit/1f872aa005a9405d9bc1f64a4b1dd2f1f1d4a16c ))
* **12-02:** reorder orphan cleanup to delete FK children before recordings ([1d735c3 ](https://github.com/onion-4-dinner/yellowjacket/commit/1d735c3a5f5a78996d6ddbe5c787adf040fe2f21 ))
* **12-02:** replace removed Scan() import with ScanAllLibraries() ([0559822 ](https://github.com/onion-4-dinner/yellowjacket/commit/05598224e4d5532d2e2a3a7e5d3b5411240b1024 ))
* **12-02:** resolve phantom tracks caused by empty library root after TOML cleanup ([717e249 ](https://github.com/onion-4-dinner/yellowjacket/commit/717e249c368fd1cc8d5c8f945c352175708691cf ))
* **12-02:** serialize ScanWarning.Err as string instead of error interface ([ac8cbb3 ](https://github.com/onion-4-dinner/yellowjacket/commit/ac8cbb3296bd561a305627668c211dce7209df25 ))
* **12-02:** soft scan claims orphaned library_id=0 tracks on startup ([1ad099a ](https://github.com/onion-4-dinner/yellowjacket/commit/1ad099a9d35fc722475e238d3443fd5473566acd ))
* **12-02:** soft scan on launch — only scan libraries with changed file counts ([92c4d23 ](https://github.com/onion-4-dinner/yellowjacket/commit/92c4d23a9a1e545fab497816ee3dce43a181cded ))
* **12-02:** wait for scan to stop before library removal, surface errors in UI ([cf00498 ](https://github.com/onion-4-dinner/yellowjacket/commit/cf004986c95732d00208e83467267904ea3f2ef6 ))
* **13-02:** auto-resolve phantom playlist tracks after library scan ([93262b9 ](https://github.com/onion-4-dinner/yellowjacket/commit/93262b9ae0f737d2893839ac585776207b3b44b6 ))
* **13-02:** defer virtualizer event delegation until element exists ([f05d2bb ](https://github.com/onion-4-dinner/yellowjacket/commit/f05d2bb603f5ea827164466fd0795a6c6e662529 ))
* **13-02:** resolve phantom playlist tracks using M3U8 paths after scan ([9f595b7 ](https://github.com/onion-4-dinner/yellowjacket/commit/9f595b7ac10c2191b5469004901cbbc1331c1abb ))
* **14-01:** downgrade main-panel from contain:strict to layout+style+paint ([4b7d35d ](https://github.com/onion-4-dinner/yellowjacket/commit/4b7d35d7ec4c8b14453a8f8250cd154b8c4c2537 ))
* **14-perf:** fix scroll jumping and input latency ([3b2e189 ](https://github.com/onion-4-dinner/yellowjacket/commit/3b2e189e7d0e6d00393d087565190fd307774257 ))
* **17-02:** fix cover art replace and remove ([d7c2965 ](https://github.com/onion-4-dinner/yellowjacket/commit/d7c2965752ae0ac9009d00f2431d5919a24558b7 ))
* **17-02:** handle float64 numeric values from Wails JSON deserialization ([900db2e ](https://github.com/onion-4-dinner/yellowjacket/commit/900db2e56cca254873a3a5a7a384008feac4211b ))
* **17-02:** refresh cover art URLs after save ([8cd4914 ](https://github.com/onion-4-dinner/yellowjacket/commit/8cd4914842f61c0c6b49e0216c7816e201a3c94a ))
* **17-02:** refresh track-details dialog data after successful save ([ffcdc41 ](https://github.com/onion-4-dinner/yellowjacket/commit/ffcdc41b0d4fad8ed428dbaa55f6cdd38c096822 ))
* **18-02:** add field labels above title/artist/album inputs in batch edit mode ([9df2d67 ](https://github.com/onion-4-dinner/yellowjacket/commit/9df2d6764a0b0566dda33cff675debea4a61dea8 ))
* **18-02:** add field labels to all track-details states (single/batch, read/edit) ([d430ad8 ](https://github.com/onion-4-dinner/yellowjacket/commit/d430ad884bfd38bea93389d8be730ff00388a7be ))
* **19-01:** add album_artist TPE2 mapping to applyTextChanges ([8f4c4a0 ](https://github.com/onion-4-dinner/yellowjacket/commit/8f4c4a0c2b14eeeaeccb972a40addb11f3d65437 ))
* preserve scroll position in cached grid views ([54df917 ](https://github.com/onion-4-dinner/yellowjacket/commit/54df917ffdd69c4f7ffaeccf2d161261ca80d84e ))
* **queue-panel:** set flow layout _itemSize to match actual track item height ([288d9de ](https://github.com/onion-4-dinner/yellowjacket/commit/288d9deae22d437fcd7857b368827db7b62c24f6 ))
* **queue-panel:** suppress virtualizer scroll corrections during scrollbar drag ([0bd8cef ](https://github.com/onion-4-dinner/yellowjacket/commit/0bd8cefa00dcae2f8bd9579de2aefd58e0a9e6c9 ))
* **quick-19:** multi-root path resolution for playlist M3U8 tracks ([9144ded ](https://github.com/onion-4-dinner/yellowjacket/commit/9144dedc2742925dc252d491763b4f2929238d0e ))
* **S21/T01:** fix all lint warnings and upgrade wsl to wsl_v5 ([f16157a ](https://github.com/onion-4-dinner/yellowjacket/commit/f16157a2134cbeb1787ff851d4875d77f2f3f86b ))
### Performance
* **12-02:** increase scan batch size from 50 to 300 ([21ea71e ](https://github.com/onion-4-dinner/yellowjacket/commit/21ea71e2575d76258bd81d89ab8ac883aa3bed36 ))
* **12-02:** skip FTS5 rebuild during library removal ([30f4461 ](https://github.com/onion-4-dinner/yellowjacket/commit/30f4461e6957e20d3dc607fa0886a75b5c21b3cf ))
* **14-01:** add CSS containment to app shell layout boundaries ([efa06f7 ](https://github.com/onion-4-dinner/yellowjacket/commit/efa06f7edf1e4acdc3d8865cad264403257ae40d ))
* **14-01:** add GPU promotion and containment to all scroll containers ([ac8a52e ](https://github.com/onion-4-dinner/yellowjacket/commit/ac8a52e110f9f8ebdc3433b60594370352126a18 ))
* **14-02:** replace innerHTML navigation with view caching system ([ad91043 ](https://github.com/onion-4-dinner/yellowjacket/commit/ad9104374a628342e0ea30cf409ff43de2c2f86e ))
* **14-03:** add notification batching to queue store and granular change tracking to library store ([d0c05dc ](https://github.com/onion-4-dinner/yellowjacket/commit/d0c05dc1d43a4fe12cc07f3cff25375b08a74ba0 ))
* **14-03:** eliminate per-item closure allocation in scroll render paths ([2f7ed70 ](https://github.com/onion-4-dinner/yellowjacket/commit/2f7ed7030425ed0ebb7a1a186917a79a7b26b850 ))
* **14-04:** RAF-throttle scroll position saves and add overflow-anchor to queue panel ([6ca0b3c ](https://github.com/onion-4-dinner/yellowjacket/commit/6ca0b3c5a84769af064ebe45a6eaac014d1a270a ))
* auto-detect NVIDIA+Wayland for DMABuf workaround ([915591a ](https://github.com/onion-4-dinner/yellowjacket/commit/915591aea962beb60da2e96ac0f57307f646f675 ))
* inline SVGs, memoize grid slices, batch store notifications ([a4eac39 ](https://github.com/onion-4-dinner/yellowjacket/commit/a4eac394cebefd29d0ebcb4b1e331444dcb8fbaf ))
* reduce software rendering overhead for NVIDIA+Wayland ([199c910 ](https://github.com/onion-4-dinner/yellowjacket/commit/199c91013fd806f6aefce49357df8a32b46faaa0 ))
### Refactoring
* **quick-17:** simplify playlist-view to navigate instead of expand ([955cd68 ](https://github.com/onion-4-dinner/yellowjacket/commit/955cd68be2dbf7a9071ef1c93084d687b59b6bd7 ))
2026-03-20 19:03:30 +00:00
yonlu
0a87675dde
Merge pull request #88 from onion-4-dinner/wip
...
feat: tag writing enabled for all supported filetypes.
Adds multi-library support (schema migration, CRUD, per-library scanning with pause/cancel), keyboard shortcuts with configurable
bindings, and a full tag editing pipeline — single and batch track editing for MP3, FLAC, WAV, and OGG Vorbis formats with cover art
support. Also includes performance optimizations (CSS containment, view caching, scroll fixes, GPU promotion), library filtering across
all views, phantom track resolution, playlist detail subpages, and comprehensive lint cleanup.
2026-03-20 15:02:58 -04:00
yonlu
e974bd2a22
Merge remote-tracking branch 'origin/main' into wip
2026-03-20 14:58:19 -04:00
yonlu
f16157a213
fix(S21/T01): fix all lint warnings and upgrade wsl to wsl_v5
...
Files:
- .golangci.yml
- backend/events/cmd/genevents/main.go
- backend/fileutil/atomicwrite_test.go
- backend/library/library.go
- backend/player/buffered_streamer_test.go
- backend/player/player.go
- backend/tagwriter/dbsync.go
- backend/tagwriter/mp3_test.go
- backend/tagwriter/ogg.go
- backend/tagwriter/ogg_test.go
- backend/tagwriter/ogg_vorbis.go
- backend/tagwriter/pipeline.go
- backend/tagwriter/tagwriter.go
- backend/tagwriter/wav_test.go
2026-03-20 14:36:18 -04:00
yonlu
2409b3435a
docs(phase-20): complete phase execution
2026-03-19 14:07:56 -04:00
yonlu
712fa260dd
docs(20-02): complete OGG Vorbis tag writer tests plan
2026-03-19 14:04:52 -04:00
yonlu
f13aa7086b
test(20-02): add round-trip tests for all OGG requirements
...
- TestWriteOggTags_TextFields: all 9 text fields round-trip via dhowden/tag (OGG-01)
- TestWriteOggTags_CoverArt: METADATA_BLOCK_PICTURE embed verified (OGG-04)
- TestWriteOggTags_ClearCoverArt: cover art clear via nil (OGG-04)
- TestWriteOggTags_PartialUpdate: non-edited fields preserved (OGG-02)
- TestWriteOggTags_AudioPreservation: audio page data byte-identical (OGG-03)
- TestWriteOggTags_AtomicSafety: corrupt file untouched on failure (OGG-05)
- TestWriteOggTags_RejectNonVorbis: Theora OGG rejected (OGG-03 error path)
- TestWriteOggTags_RejectMultiStream: multi-serial rejected
2026-03-19 14:02:02 -04:00
yonlu
246a991c75
test(20-02): add OGG test fixture builder and CRC32 validation
...
- createTestOGG builds minimal valid OGG Vorbis file programmatically
- TestOggCRC_KnownVectors validates CRC32 against known vectors and fixture pages
- TestCreateTestOGG_Valid verifies fixture structure and metadata.ExtractTags compatibility
2026-03-19 14:00:47 -04:00
yonlu
d289390396
docs(20-01): complete OGG Vorbis tag writer implementation plan
...
- SUMMARY.md with implementation details and decisions
- STATE.md updated with position, metrics, and key decisions
- ROADMAP.md updated with Phase 20 progress (1/2 plans)
- REQUIREMENTS.md: OGG-01 through OGG-05 marked complete
2026-03-19 13:55:39 -04:00
yonlu
5e98c03634
feat(20-01): implement OGG Vorbis tag writer with custom page parser and CRC32
...
- Custom OGG page parser/writer with MSB-first CRC32 lookup table (ogg.go)
- Vorbis Comment packet parse/serialize with raw byte preservation (ogg_vorbis.go)
- METADATA_BLOCK_PICTURE base64 encoding for cover art with legacy field stripping
- Multi-stream and non-Vorbis OGG rejection with clear error messages
- Pipeline integration: FormatOGG constant, .ogg in DetectFormat, writeOggTags dispatch
- Lenient-read/strict-write: warn on CRC mismatch, always write correct CRCs
- Page sequence renumbering and crash-safe writes via AtomicWrite
2026-03-19 13:53:36 -04:00
yonlu
3face33a57
docs(20): create phase plan for OGG Vorbis tag writer
2026-03-19 13:20:16 -04:00
yonlu
676eede51e
docs(20): research phase domain
2026-03-19 13:15:12 -04:00
yonlu
707d759ced
docs(20): capture phase context
2026-03-19 13:06:07 -04:00
yonlu
1f0fe2cc2e
docs(phase-19): complete phase execution
2026-03-19 09:03:54 -04:00
yonlu
f7077b15df
docs(19-02): complete WAV tag writer tests plan
...
- SUMMARY.md with 7 test results and 2 deviations documented
- STATE.md: Phase 19 complete, all WAV requirements verified
- ROADMAP.md: Phase 19 marked complete
- REQUIREMENTS.md: WAV-06 marked complete
2026-03-19 09:00:29 -04:00
yonlu
f11b523afb
style(19-02): fix wsl lint warnings in WAV test and writer
...
- Add blank lines before cuddled expressions in wav_test.go
- Fix cuddled copy expression in wav.go writeRIFF
- All WAV lint issues resolved (remaining are pre-existing in other files)
2026-03-19 08:57:57 -04:00
yonlu
1b28882af4
test(19-02): add round-trip tests for all WAV tag writer requirements
...
- TestWriteWavTags_TextFields: 9 field round-trip (WAV-01)
- TestWriteWavTags_CoverArt: JPEG embed/read-back (WAV-04)
- TestWriteWavTags_ClearCoverArt: embed then clear (WAV-04)
- TestWriteWavTags_PartialUpdate: 2-of-9 change, 7 preserved (WAV-01)
- TestWriteWavTags_ChunkPreservation: fmt/data/LIST/bext preserved (WAV-02, WAV-03)
- TestWriteWavTags_AtomicSafety: failed write leaves file untouched (WAV-05)
- TestWriteWavTags_RejectsRF64: RF64 rejected with clear error (WAV-02)
- readWavID3Tags uses bogem/id3v2 ParseReader for reliable read-back
2026-03-19 08:53:36 -04:00
yonlu
21fe17212d
test(19-02): add WAV test fixture builder and read-back helper
...
- createTestWAV: builds minimal valid WAV with optional ID3v2 tag
- readWavID3Tags: extracts ID3v2 from RIFF via parseRIFF + dhowden/tag
- createTestWAVWithExtraChunks: adds LIST INFO and bext chunks for preservation tests
- makePCMFmtData: generates 16-byte PCM format data
2026-03-19 08:50:20 -04:00
yonlu
8794584b97
docs(19-01): complete WAV tag writer implementation plan
...
- SUMMARY.md with task commits, deviations, decisions
- STATE.md updated with position, metrics, decisions
- ROADMAP.md updated with phase 19 progress (1/2 plans)
- REQUIREMENTS.md: WAV-01 through WAV-05 marked complete
2026-03-19 08:47:04 -04:00
yonlu
e6610ff15e
feat(19-01): implement WAV RIFF parser/writer and writeWavTags
...
- Add FormatWAV constant and .wav DetectFormat case
- Add FormatWAV dispatch in pipeline WriteTrackTags switch
- Create wav.go with custom RIFF chunk parser/writer
- parseRIFF: lenient read, RF64 rejection, case-insensitive ID3 chunk detection
- writeRIFF: strict write with correct padding and 4GB size check
- writeWavTags: merge existing ID3v2, reuse applyTextChanges/applyCoverArtChanges
- Atomic write via fileutil.AtomicWrite for crash safety
2026-03-19 08:44:38 -04:00
yonlu
8f4c4a0c2b
fix(19-01): add album_artist TPE2 mapping to applyTextChanges
...
- Map FieldAlbumArtist to TPE2 frame via CommonID
- Follows same pattern as FieldComposer → TCOM
- Fixes latent gap in MP3 writing, enables WAV reuse
2026-03-19 08:42:53 -04:00
yonlu
d789c0b68e
docs(19): create phase plan for WAV tag writer
2026-03-18 20:37:24 -04:00
yonlu
c5184fed79
docs(19): research phase domain
2026-03-18 20:33:37 -04:00
yonlu
75e49a839e
docs(19): capture phase context
2026-03-18 19:56:59 -04:00
yonlu
5d37eb3a2a
docs: create milestone v1.2.1 roadmap (3 phases)
2026-03-18 16:30:15 -04:00
yonlu
6b4adf8690
docs: define milestone v1.2.1 requirements
2026-03-18 15:01:12 -04:00