Commit Graph
507 Commits
Author SHA1 Message Date
yonlu 1f872aa005 fix(12-02): refresh library track counts after scan completes
loadLibraries() now runs on ScanComplete and ScanQueueDrained so newly
added libraries show their track count without navigating away.
2026-03-14 10:01:35 -04:00
yonlu b648307ac5 docs(12-02): record deferred bulk phantom matching improvement in STATE.md 2026-03-13 22:22:37 -04:00
yonlu 717e249c36 fix(12-02): resolve phantom tracks caused by empty library root after TOML cleanup
getLibraryRoot() returned "" after DirectoryPath was removed from
config.toml during multi-library migration. M3U8 relative paths could
not be resolved to absolute paths, causing every playlist track to
appear as phantom. Now falls back to the first library path from the
database when the legacy config field is empty.
2026-03-13 14:06:21 -04:00
yonlu 1ad099a9d3 fix(12-02): soft scan claims orphaned library_id=0 tracks on startup
Tracks from the pre-multi-library schema have library_id=0 and aren't
counted by CountAudioFilesByLibrary, causing a permanent count mismatch
that triggers a full scan on every launch. SoftScanAllLibraries now
claims matching orphans before comparing counts.
2026-03-13 13:59:18 -04:00
yonlu 92c4d23a9a fix(12-02): soft scan on launch — only scan libraries with changed file counts
SoftScanAllLibraries compares audio file count on disk vs DB track count
per library. Unchanged libraries are silently skipped (no progress bar,
no events). Only libraries where files were added or removed since the
last scan get queued for a full scan.
2026-03-13 13:53:46 -04:00
yonlu 1d735c3a5f fix(12-02): reorder orphan cleanup to delete FK children before recordings
recording_genres and release_group_recordings reference recordings.id,
so they must be deleted BEFORE the recordings table is cleaned.
Also extends toast duration to 8s for readability.
2026-03-13 13:38:39 -04:00
yonlu cf004986c9 fix(12-02): wait for scan to stop before library removal, surface errors in UI
RemoveLibrary now polls until the cancelled scan goroutine finishes
before proceeding with the removal transaction. Also show removal
errors as toast messages instead of only logging to console, and
explicitly reload library list after successful removal.
2026-03-13 11:17:37 -04:00
yonlu f60b6b5255 fix(12-02): claim orphaned tracks when adding library with matching path
Tracks from pre-multi-library schema have library_id=0 (default).
When AddLibrary creates a new library row, UPDATE orphaned tracks
whose file_path falls under the library's directory to use the new
library_id. This prevents the scan from hitting UNIQUE constraints
on every file and ensures track counts are correct immediately.
2026-03-13 10:50:34 -04:00
yonlu 13a42aea22 feat(12-02): selectable library list with checkbox scan targeting
- Add checkboxes to library list with select-all header
- Soft Scan operates on selected libraries (queues each individually)
- Full Rescan stays global (nukes all data, rescans all libraries)
- Remove redundant 'Scan All Libraries' button
- Fix FullRescan Go backend to scan all libraries after wipe, not just first
2026-03-13 10:33:15 -04:00
yonlu b36e472212 fix(12-02): count failed saves as skipped so scan progress bar advances
Files that fail to save (e.g. UNIQUE constraint from pre-existing
tracks with a different library_id) were not counted in any progress
counter, leaving the progress bar stuck at 0%. Now increments skipped
so processed = added + skipped + updated reflects all files visited.
2026-03-13 09:31:28 -04:00
yonlu 9272b060bf fix(12-02): dismiss inline rename on click outside 2026-03-13 09:24:32 -04:00
yonlu cf18c39dbd fix(12-02): downgrade per-file save error to Debug, add warning count to scan summary 2026-03-13 09:17:38 -04:00
yonlu 05598224e4 fix(12-02): replace removed Scan() import with ScanAllLibraries()
Scan() wrapper was deleted in Phase 11 but config-page.ts and
library-manager.ts still imported it. Use ScanAllLibraries() for
soft scan since multi-library model scans all libraries.
2026-03-13 08:27:47 -04:00
yonlu e199712a56 feat(12-02): remove Libraries sidebar nav item and view routing
- Remove 'libraries' from View type union in app-sidebar.ts
- Remove Libraries nav item from sidebar navigation list
- Remove case 'libraries' view routing in index.ts
- Remove library-manager component import from index.ts
2026-03-12 19:51:41 -04:00
yonlu ffc5d9639c feat(12-02): replace config-page library section with full library management UI
- Add library list with name, path, track count per library
- Add Library button opens folder picker, auto-creates library
- Inline rename with Enter/Escape via overflow menu
- Removal confirmation dialog with real impact counts (tracks, playlists, queue)
- Toast notification with removal summary after library removal
- Add GetAllLibrariesWithTrackCounts + Info type to backend Library struct
- Add Wails binding stubs for AddLibrary, RenameLibrary, RemoveLibrary, GetRemovalImpact
- Add Info, RemovalImpact, RemovalSummary types to models.ts
- Remove old single-directory library config UI (GetLibraryDirectory/SetLibraryDirectory)
2026-03-12 19:50:59 -04:00
yonlu 27c773b3d0 docs(12-01): complete library CRUD backend plan
- SUMMARY.md with 2 task commits, 6 files, 6 requirements completed
- STATE.md advanced to Phase 12 Plan 1/2, added Phase 12 decisions
- ROADMAP.md marked 12-01 complete (1/2 plans)
- REQUIREMENTS.md marked LIB-01, LIB-02, LIB-03, DATA-02, DATA-03, PLAY-04 complete
2026-03-12 19:42:41 -04:00
yonlu 5995dfd01d feat(12-01): add queue compaction method and wire removal hooks
- Add CompactAfterLibraryRemoval on Queue: reloads surviving tracks from DB, resets currentIndex, unloads player if current track was removed, clears shuffle order
- Wire RemovalHooks in app.go OnStartup: StopPlayback → player.UnloadTrack, CompactQueue → queue.CompactAfterLibraryRemoval
- All existing tests pass with no regressions
2026-03-12 19:38:36 -04:00
yonlu bd44f8306c feat(12-01): implement library CRUD methods and orphan cleanup pipeline
- Add AddLibrary, RenameLibrary, RemoveLibrary, GetRemovalImpact methods
- RemoveLibrary follows exact order: phantom populate → delete audio_files → orphan cleanup → commit → FTS5 rebuild → cover art file cleanup → queue compact → events
- Add cancelLibraryScan and currentTrackBelongsToLibrary helpers
- Add RemovalHooks type and removalHooks field on Library struct
- Add LibraryAdded, LibraryRenamed, LibraryRemoved event constants
- Regenerate frontend events.ts with new CRUD events
- All hand-crafted SQL has SAFETY comments per project convention
- Dual artist_credit FK check (recordings + release_groups) for orphan cleanup
2026-03-12 19:37:07 -04:00
yonlu e97b849602 docs(12): create phase plan for library CRUD and data integrity 2026-03-12 17:48:46 -04:00
yonlu 721442d1cb docs(12): create phase plan 2026-03-12 17:46:08 -04:00
yonlu de5ee4c301 docs(12): research phase domain 2026-03-12 17:39:32 -04:00
yonlu 10f97047e8 docs(12): capture phase context 2026-03-12 13:53:20 -04:00
yonlu 12f10c5fac docs(phase-11): complete phase execution 2026-03-09 16:23:50 -04:00
yonlu ead68cfb5d docs(11-03): complete wire auto-scan and legacy cleanup plan
- SUMMARY.md documents auto-scan wiring and legacy code removal
- STATE.md updated: plan 3/3 complete, Phase 11 done, session continuity
- ROADMAP.md updated: Phase 11 complete (3/3 plans)
2026-03-09 16:19:59 -04:00
yonlu 1aaf53630d docs(11-02): complete frontend scan UI plan
- SUMMARY.md documents per-library progress display and queue-aware cancel dialog
- STATE.md updated: plan 2/3, session continuity, new decisions
- ROADMAP.md updated: phase 11 progress 2/3
- REQUIREMENTS.md: LSCAN-03 marked complete
2026-03-09 16:13:45 -04:00
yonlu d61f122b56 feat(11-02): update library-manager with per-library progress and Scan All button
- Add libraryId, libraryName, queuedCount to ScanProgress interface
- Show library name in progress label (Scanning: [Library Name])
- Show queue count below progress bar when libraries queued
- Add Scan All Libraries button (calls ScanAllLibraries binding)
- Subscribe to LibraryScanQueued/LibraryScanQueueDrained events
- Scan state properly tracks queue draining (doesn't reset early)
2026-03-09 16:11:23 -04:00
yonlu d01591d6cc feat(11-02): update config-page with per-library progress display and queue-aware cancel dialog
- Add libraryId, libraryName, queuedCount to ScanProgress interface
- Replace CancelScan import with CancelCurrentScan, CancelAllScans
- Add ScanAllLibraries import and Scan All Libraries button
- Show library name in progress label (Scanning: [Library Name])
- Show queue count below progress bar when libraries queued
- Cancel dialog shows scope choice (Cancel This Library / Cancel All) when queue > 0
- Subscribe to LibraryScanQueued and LibraryScanQueueDrained events
- Track scanQueuedCount state for queue-aware UI behavior
2026-03-09 16:09:22 -04:00
yonlu 9308848936 docs(11-01): complete per-library scan pipeline plan
- Create 11-01-SUMMARY.md with execution results
- Update STATE.md: advance to phase 11 plan 1/3
- Update ROADMAP.md: phase 11 at 1/3 plans complete
- Mark LSCAN-01, LSCAN-02, LSCAN-04 complete in REQUIREMENTS.md
2026-03-09 16:05:55 -04:00
yonlu 943db1cf27 feat(11-01): per-library scan pipeline with queue coordinator
Task 1: Schema, events, and progress types
- Add library_id to CreateAudioFile SQL INSERT and regenerate sqlc code
- Add LibraryScanQueued and LibraryScanQueueDrained event constants
- Regenerate TypeScript events via genevents
- Add LibraryID, LibraryName, QueuedCount to ScanProgress
- Add LibraryID, LibraryName to ScanMetrics
- Add libraryID field to importResult for threading through pipeline

Task 2: Scan queue coordinator and per-library scanning
- Create scan_queue.go with ScanLibrary(id), ScanAllLibraries()
- Add CancelCurrentScan(), CancelAllScans() for queue-aware cancellation
- FIFO scan queue with silent dedup (same library already scanning or queued)
- Refactor Scan() -> scanInternal(libraryID, libraryName, libraryPath)
- Replace GetAllAudioFiles with GetAudioFilesByLibrary for per-library loading
- Thread libraryID through DB writer to set CreateAudioFileParams.LibraryID
- drainQueue auto-starts next queued library or emits LibraryScanQueueDrained
- Pause freezes current scan AND queue
- Add GetScanQueueLength() and QueuedLibraryNames() for UI
- Mark CancelScan() and Scan() as deprecated
2026-03-09 16:02:54 -04:00
yonlu 68463f3549 docs(11): create phase plan for per-library scan pipeline 2026-03-09 15:44:07 -04:00
yonlu 025da10d98 docs(11): capture phase context 2026-03-09 15:18:01 -04:00
yonlu 75b2a349eb fix(10-01): move library_id index to migration 6 to fix existing DB startup
On existing databases, CREATE TABLE IF NOT EXISTS audio_files is a no-op
but the standalone CREATE INDEX on library_id would fail because the
column doesn't exist until migration 6 runs. The migration already
creates this index, so removing it from the schema file is correct.
2026-03-09 10:48:11 -04:00
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