Commit Graph
475 Commits
Author SHA1 Message Date
yonlu 9ff850fe23 docs(phase-10): complete phase execution 2026-03-09 09:57:37 -04:00
yonlu 765204e8eb docs(10-02): complete sqlc queries & migration tests plan
- SUMMARY: Library CRUD queries, phantom-aware playlist queries, 5 migration tests
- STATE: Phase 10 complete (2/2 plans), ready for Phase 11
- ROADMAP: Phase 10 marked complete
- REQUIREMENTS: LIB-04, LIB-05 marked complete
2026-03-09 09:54:12 -04:00
yonlu bc151891b5 feat(10-02): add migration 6 integration tests and NewTestDBWithLibrary helper
- Add NewTestDBWithLibrary helper for tests needing a pre-created library
- TestMigration6FreshDB: verify all tables, columns, phantom cols, VIEW, and user_version
- TestMigration6LibraryQueries: verify CRUD operations and unique path constraint
- TestMigration6PhantomPlaylistTracks: verify SET NULL FK preserves phantom metadata
- TestMigration6AudioFilesLibraryFK: verify FK enforcement on library_id
- TestMigration6TrackMetadataViewHasLibraryID: verify VIEW includes library_id
2026-03-09 09:50:14 -04:00
yonlu 02548dd55e feat(10-02): add sqlc queries for libraries and update playlist queries for phantom support
- Create libraries.sql with 7 CRUD queries (create, get, get-by-path, list, update, delete, count)
- Update playlists.sql: AddPlaylistTrack now accepts 9 params including phantom metadata
- Update playlist queries to use LEFT JOIN for nullable audio_file_id
- Add GetTrackPhantomMetadata helper query for eager phantom population
- Add is_phantom computed column to metadata queries
- Add GetAudioFilesByLibrary and CountAudioFilesByLibrary queries
- Regenerate all sqlc code
2026-03-09 09:47:30 -04:00
yonlu 2c77368482 docs(10-01): complete schema & migration plan 2026-03-09 09:44:05 -04:00
yonlu 1179f56c36 feat(10-01): implement migration 6 and pre-migration backup
- Add backupDatabase() for timestamped .db file backup before migration
- Add migration6MultiLibrary() with all 14 steps: FK OFF, create libraries table,
  insert default library from TOML config, add library_id to audio_files, rebuild
  playlist_tracks with SET NULL FK and 6 phantom columns, backfill phantom metadata,
  recreate track_metadata VIEW with library_id, FK ON, clean TOML config
- Add readLibraryDirFromTOML() and removeLibraryDirFromTOML() helpers
- Update runMigrations signature to accept dbPath for backup
- Add sentinel library row in NewTestDB for FK constraint satisfaction
2026-03-09 09:41:08 -04:00
yonlu 535855b383 feat(10-01): update SQL schema files for multi-library fresh installs
- Create _libraries.sql with libraries table (name, path, created_at)
- Add library_id FK column and index to audio_files.sql
- Update playlist_tracks.sql with nullable audio_file_id, SET NULL FK, and 6 phantom columns
- Add af.library_id to track_metadata VIEW
- Regenerate sqlc code for updated schemas
- Fix playlist.go to use sql.NullInt64 for nullable audio_file_id
2026-03-09 09:36:47 -04:00
yonlu 6f44512ebc docs(10): create phase plan — schema & migration 2026-03-09 09:27:02 -04:00
yonlu 44f41785bb docs(10): capture phase context 2026-03-09 09:05:01 -04:00
yonlu 8ecb1de306 docs: create multi-library roadmap (4 phases, 23 requirements)
Phases 10-13 for v1.1 Multi-Library Support:
- Phase 10: Schema & Migration (libraries table, library_id FK, phantom columns)
- Phase 11: Per-Library Scan Pipeline (sequential coordination, per-library progress)
- Phase 12: Library CRUD & Data Integrity (add/rename/remove, orphan cleanup, FTS5)
- Phase 13: Library Views & Phantom Tracks (unified views, filtering, phantom display)
2026-03-08 12:12:50 -04:00
yonlu cdf8bff01a docs: restructure v1.1 milestone for multi-library support
- Rename milestone from 'Features & Extensibility' to 'Multi-Library Support'
- Replace old phases 10-14 (TAG/SMRT/GAP/MB/LAYOUT/PLUG) with 20 multi-library requirements (LIB/LSCAN/VIEW/PLAY/DATA)
- Move deferred features to Future Requirements
- Update research files with multi-library research (Stack, Features, Architecture, Pitfalls)
- Architecture: hybrid model (library_id on audio_files only), libraries in DB, sequential scanning, phantom tracks
2026-03-08 11:54:37 -04:00
yonlu 595b5e1529 docs(quick-18): add multi-column metadata display to playlist-details track list 2026-03-08 09:37:11 -04:00
yonlu cab0f082cf docs(quick-18): complete multi-column metadata display plan
- Add 18-SUMMARY.md with execution results
- Update STATE.md quick tasks table
2026-03-08 09:36:50 -04:00
yonlu ce23177228 feat(quick-18): replace track-info with multi-column grid layout in playlist-details
- Remove track-info component, add formatMilliseconds import
- Add 5-column grid (#, Title, Artist, Album, Duration) with header row
- Display 1-indexed playlist order numbers in # column
- Phantom tracks span full grid width with grid-column: 1 / -1
- Add column-specific CSS: tabular-nums, text truncation, alignment
2026-03-08 09:35:59 -04:00
yonlu 8570f76400 docs(quick-17): complete playlist subpage refactoring
- Summary documenting playlist-details creation and playlist-view simplification
- Updated STATE.md with quick task 17 completion
2026-03-07 22:11:28 -05:00
yonlu 955cd68be2 refactor(quick-17): simplify playlist-view to navigate instead of expand
- Plain click now navigates to playlist-details subpage instead of toggling expand/collapse
- Removed all inline track expansion: renderPlaylistBody, track-item rendering, chevron icons
- Removed SelectionController, ContextMenuController, PlayerController (track-level interactions moved to playlist-details)
- Removed track-info, track-details, phantom-resolver imports (all live in playlist-details now)
- Simplified search to filter by playlist name only (no inline track search)
- Kept: playlist list, context menu (rename/delete/set-default), Ctrl/Shift multi-select, drag-drop target, create/import, sort toolbar
2026-03-07 22:10:24 -05:00
yonlu dc5c7d6ca6 feat(quick-17): create playlist-details subpage component
- New playlist-details component with header (back button, playlist icon, title, track count)
- Full track list with all interactions: select, play, context menu, drag, phantom handling
- Drop target support for adding tracks from other views
- Search filtering for tracks within the detail view
- Navigation routing in index.ts for playlist-details view
- Added playlist-details to SEARCHABLE_VIEWS in search-store
2026-03-07 22:06:53 -05:00
yonlu 2bdabf0940 docs(quick-17): plan playlist view subpage refactor 2026-03-07 22:03:11 -05:00
yonlu 0bd8cefa00 fix(queue-panel): suppress virtualizer scroll corrections during scrollbar drag
lit-virtualizer's flow layout has a scroll error correction mechanism that
calls scrollTo() to fix sub-pixel estimation errors. On large lists (20k+),
even with fixed-height items, floating-point differences from
getBoundingClientRect() (e.g. 49.000003px vs 49px) accumulate across items
and trigger corrections that fight the native scrollbar drag gesture,
causing the thumb to desync from the mouse.

Detect scrollbar drag by checking if mousedown occurs in the scrollbar
gutter (clientX > element clientWidth), then monkey-patch the virtualizer's
_correctScrollError method to discard accumulated errors during drag
instead of calling scrollTo(). Items continue to render/recycle normally
since layout updates are not suppressed -- only the scroll position
corrections are skipped.
2026-03-07 11:14:54 -05:00
yonlu 288d9deae2 fix(queue-panel): set flow layout _itemSize to match actual track item height
The previous fix (fixed CSS height on .track-item) was insufficient because
lit-virtualizer's flow layout defaults to estimating items at 100px tall.
With 20k items, the difference between 100px estimate and 49px actual creates
a ~1M px scroll height that collapses as items get measured, triggering
scroll error corrections (programmatic scrollTo calls) that fight the native
scrollbar during drag.

Setting _itemSize to { height: 49 } via the flow() config ensures the initial
scroll size estimate matches reality, eliminating the scroll error corrections
that caused the scrollbar thumb to desync from the mouse when dragging down.
2026-03-07 10:49:06 -05:00
yonlu 01fe39cc04 docs(quick-16): add ctrl+a hotkey to multi-select views to select all items 2026-03-07 10:20:57 -05:00
yonlu 8576999ae3 now-playing component scrolls text when hovering 2026-03-07 10:20:51 -05:00
yonlu 043c74c8b3 docs(quick-16): complete Ctrl+A select-all hotkey implementation 2026-03-07 10:20:16 -05:00
yonlu 906ea28751 feat(16-01): wire shortcut:select-all listener in track-list, queue-panel, and playlist-view
- Add handleSelectAll bound handler calling selection.selectAll() in all three components
- Register/unregister event listeners in connectedCallback/disconnectedCallback
2026-03-07 10:19:07 -05:00
yonlu f5677628ef feat(16-01): add selectAll() to SelectionController and dispatch shortcut:select-all event
- Add selectAll() method to SelectionController that selects all items via host interface
- Change app.selectAll dispatch from document.execCommand('selectAll') to CustomEvent('shortcut:select-all')
2026-03-07 10:18:08 -05:00
yonlu 13321b531d docs(quick-16): plan Ctrl+A select-all for multi-select views 2026-03-07 10:16:58 -05:00
yonlu e503fb3b67 docs(phase-09): complete phase execution 2026-03-07 10:13:03 -05:00
yonlu 8c8dca31e5 docs(09-05): complete integration testing & verification plan
- Created 09-05-SUMMARY.md documenting build verification and human approval
- Updated STATE.md: Phase 9 complete (5/5 plans, 1 phase done)
- Updated ROADMAP.md: Phase 9 and all plans marked complete
- Documented volume data flow bug fix (bb3fd20) as deviation
2026-03-07 10:08:35 -05:00
yonlu bb3fd204f0 fix(09-05): emit VolumeChanged event and persist state in ChangeVolume and MuteToggle 2026-03-07 02:06:08 -05:00
yonlu 77328e95dc docs(09-04): complete keyboard shortcuts settings UI plan
- SUMMARY.md with task commits and deviation documentation
- STATE.md advanced to Plan 5 of 5 (80% complete)
- ROADMAP.md updated with 4/5 plans progress
- Requirements KEY-02 and KEY-03 marked complete
2026-03-06 22:00:38 -05:00
yonlu 0451fb3880 feat(09-04): add keyboard shortcuts section to config page with conflict detection
- Keyboard Shortcuts section with shortcuts grouped by Player, Navigation, App categories
- All 16 default shortcuts listed with human-readable labels
- shortcut-capture widget for each action enables record-style rebinding
- Conflict detection warns before overwriting existing bindings with Overwrite/Cancel
- Reset All to Defaults button calls store.resetAll()
- Panel-specific shortcuts display scope label (e.g. track-list)
- ShortcutsController provides reactive state updates
2026-03-06 21:58:13 -05:00
yonlu 0706f804a4 docs(09-03): complete scan control UI plan
- SUMMARY.md with scan control UI outcomes and deviations
- STATE.md updated to plan 4 of 5 (60% progress)
- ROADMAP.md updated with 3/5 plan progress
2026-03-06 21:57:47 -05:00
yonlu 391436927c feat(09-03): add scan control UI with pause/resume/cancel and confirmation dialog
- Pause/Resume buttons replace Soft Scan/Full Rescan during active scan
- Cancel button shows confirmation dialog with Keep/Discard/Continue options
- Register LibraryScanPaused/Resumed/Cancelled event handlers
- Status bar shows 'Scan paused.' with accent color when paused
- Add CancelScan/PauseScan/ResumeScan Wails binding stubs
- Cancel dialog overlay dismissible by clicking outside or Continue Scanning
- Add cancelled field to ScanMetrics TypeScript interface
2026-03-06 21:54:50 -05:00
yonlu 6bb266e234 docs(09-02): complete keyboard shortcuts config & service plan
- Create 09-02-SUMMARY.md with execution metrics and decisions
- Update STATE.md: advance to plan 3, record metrics
- Mark KEY-01, KEY-04, KEY-05 requirements complete
2026-03-06 21:51:21 -05:00
yonlu 40d48151dd feat(09-02): add frontend keyboard shortcut service, store, and controller
- Create keyboard-shortcut-service.ts singleton with keydown listener
- Shadow DOM active element resolution for scope detection
- Text input suppression (only Escape passes through)
- Scope resolution: text-input > panel-specific > global
- Action dispatch to player/queue stores and Wails bindings
- Create shortcuts-store.ts with Wails persistence and event sync
- Create shortcuts-controller.ts for Lit component integration
- Export store and controller from store/index.ts
- Replace hardcoded Ctrl+F handler in index.ts with service
- Initialize service via import in frontend/index.ts
2026-03-06 21:48:52 -05:00
yonlu 6285ca9dc4 feat(09-02): add shortcuts config package with default bindings and Wails persistence
- Create backend/shortcuts/config.go with DefaultBindings(), ApplyDefaults(), Validate()
- Wire Shortcuts field into main Config struct with TOML persistence
- Add GetShortcuts, SetShortcuts, SetShortcut, ResetShortcuts Wails binding methods
- Regenerate Wails TypeScript bindings for new config methods
- Fix wsl lint in library.go (blank line before logger call)
2026-03-06 21:46:09 -05:00
yonlu 42add7fec4 docs(09-01): complete scan control backend plan
- Create 09-01-SUMMARY.md with execution metrics and decisions
- Update STATE.md with plan progress and session continuity
- Update ROADMAP.md: mark 09-01 plan complete
- Mark SCAN-01, SCAN-02, SCAN-03 requirements complete
2026-03-06 21:35:39 -05:00
yonlu cf22e52a64 feat(09-01): add scan control fields and per-scan cancellable context
- Add scanActive, scanCancel, scanPaused, scanPauseCh fields to Library struct
- Create scan_control.go with CancelScan, PauseScan, ResumeScan, IsScanActive, IsScanPaused
- Thread per-scan scanCtx through walk and worker pipeline
- Add waitIfPaused checkpoint before each worker extraction
- Skip orphan cleanup and variant generation on cancelled scan
- Emit LibraryScanCancelled instead of LibraryScanComplete when cancelled
2026-03-06 21:30:49 -05:00
yonlu c695024241 feat(09-01): add scan control events and cancelled metrics field
- Add LibraryScanCancelled, LibraryScanPaused, LibraryScanResumed events
- Regenerate frontend/src/events.ts via go generate
- Add Cancelled bool field to ScanMetrics struct
2026-03-06 21:28:37 -05:00
yonlu 08ff00f029 docs(09): create phase plan — 5 plans in 3 waves for scan cancellation & keyboard shortcuts 2026-03-06 13:20:35 -05:00
yonlu 71c200bc5b docs(09): research phase domain 2026-03-06 11:39:48 -05:00
yonlu 170f6b1b84 docs(state): record phase 9 context session 2026-03-06 11:32:40 -05:00
yonlu 7c30e87895 docs(09): capture phase context 2026-03-06 11:32:22 -05:00
yonlu e0b88f1a72 docs: create milestone v1.1 roadmap (6 phases) 2026-03-06 11:08:30 -05:00
yonlu fc7ef4213f docs: define milestone v1.1 requirements 2026-03-06 11:04:49 -05:00
yonlu 224411bbed docs: complete v1.1 project research 2026-03-06 10:49:03 -05:00
yonlu ac3bd4beb4 docs: start milestone v1.1 Features & Extensibility 2026-03-06 10:31:05 -05:00
yonlu 32a8d07644 fixed makefile to workaround obfuscation bug, changed gpu policy to fix wayland issue 2026-03-06 09:53:46 -05:00
github-actions[bot] c6c5ece956 chore(release): 1.2.2 [skip ci]
## [1.2.2](https://github.com/onion-4-dinner/yellowjacket/compare/v1.2.1...v1.2.2) (2026-03-06)

### Bug Fixes

* recover from go-mp3 seek panic on startup ([#86](https://github.com/onion-4-dinner/yellowjacket/issues/86)) ([2f9d9f8](https://github.com/onion-4-dinner/yellowjacket/commit/2f9d9f8508b90b6188fe894c282c5b8e330e8046))
2026-03-06 06:08:50 +00:00
logan 2f9d9f8508 fix: recover from go-mp3 seek panic on startup (#86)
The go-mp3 library (v0.3.4) has a bug where Seek panics with a slice
bounds error for certain byte positions. This crashes the app when
restoring a saved playback position on startup.

Add bounds clamping and a recover wrapper around the seek call in
seekLocked to convert the panic into a graceful error. When the seek
fails, playback starts from the beginning instead of crashing.
2026-03-06 00:08:11 -06:00