123 Commits

Author SHA1 Message Date
Geert Rademakes
9249a5a4a7 feat(reorder): support dragging multiple selected songs to a specific position and to end (block move) 2025-08-08 14:55:06 +02:00
Geert Rademakes
ac52441dd1 fix(reorder): only show end-of-list drop zone during active reorder drag; reset hover indicators on drag end 2025-08-08 14:53:26 +02:00
Geert Rademakes
d0a83a85f5 feat(reorder): add end-of-list drop zone to move track to end; show hover indicator 2025-08-08 14:52:48 +02:00
Geert Rademakes
2d42c6da71 fix(reorder): stop overwriting server move with stale client order; just refresh after move; improve dnd effectAllowed/dropEffect 2025-08-08 14:47:20 +02:00
Geert Rademakes
e2d6d55433 chore(reorder-debug): add server/client logs for move and playlist order slice to diagnose ordering issue 2025-08-08 14:37:45 +02:00
Geert Rademakes
484d191201 fix(playlist-order): honor custom order in playlist songs endpoint by slicing trackIds and mapping results 2025-08-08 14:33:42 +02:00
Geert Rademakes
8136bbb959 fix(reorder): backend move endpoint and frontend use precise move to persist order reliably; refresh after move 2025-08-08 14:30:58 +02:00
Geert Rademakes
61d4ca16de feat(playlists): track custom order in separate 'order' array; reading API honors 'order' while preserving 'tracks' 2025-08-08 14:25:50 +02:00
Geert Rademakes
5a396d774e fix(playlists): markModified on children/tracks to persist order; API response confirms update 2025-08-08 14:20:48 +02:00
Geert Rademakes
5a21243f5b chore(reorder): add client debug logs; refresh playlist after reorder; backend keeps missing ids at end when reordering 2025-08-08 14:15:55 +02:00
Geert Rademakes
50a486f6d8 feat(playlist-reorder): enable intra-playlist row drag&drop with landing indicator; persist order via backend 2025-08-08 14:09:36 +02:00
Geert Rademakes
32d545959d feat(playlists): support custom per-playlist track order; backend /playlists/reorder; playlist songs endpoint honors order; frontend intra-playlist row DnD with reorder persist 2025-08-08 14:03:03 +02:00
Geert Rademakes
91fd5077d4 chore(dnd): remove debug logs and globals; keep clean drag/drop with proper handlers and UX; no functional changes 2025-08-08 13:52:32 +02:00
Geert Rademakes
e622219e12 fix(dnd): pass onDropSongs into top-level PlaylistItem instances as well (not only nested) 2025-08-08 13:48:23 +02:00
Geert Rademakes
dc11487a9f fix(dnd): bubble drop handler through nested folders; add debug log on handler invoke; harden /playlists/batch insertMany 2025-08-08 13:39:39 +02:00
Geert Rademakes
6eabfdedd0 perf(jobs): adaptive polling (2s with active jobs, 10s when idle) 2025-08-08 13:36:50 +02:00
Geert Rademakes
3f57904dd7 fix(dnd): ensure drop triggers by preventing default and stopping propagation; set dropEffect=copy on dragover 2025-08-08 13:35:54 +02:00
Geert Rademakes
0c8e00389b fix(playlists): modify full playlist tree when adding tracks (avoid structure-only overwrite); then reload structure for counters 2025-08-08 13:29:58 +02:00
Geert Rademakes
5a6710b0eb fix(dnd): robust drop parsing with window fallback; keep previous sidebar border look; add global payload for reliability 2025-08-08 13:27:46 +02:00
Geert Rademakes
8394f4b42f ui(playlists): restore subtle borders; use box-shadow for drag highlight without altering base border styles 2025-08-08 13:25:16 +02:00
Geert Rademakes
4e123d2597 fix(dnd): avoid parsing during dragover; only inspect types; parse on drop with guards and log raw length 2025-08-08 13:24:13 +02:00
Geert Rademakes
b534485bde chore(dnd-debug): add console.debug logs for dragover/drop, fix highlighting conditions, log drag payload 2025-08-08 13:22:20 +02:00
Geert Rademakes
8a9f51a0c6 fix(dnd): align drop flow with modal add; use same backend save and show success toast; improve payload parsing for drop targets 2025-08-08 13:17:15 +02:00
Geert Rademakes
c7dd2e6d33 fix(dnd): ensure drop detects payload; set text/plain fallback; refresh playlist structure after add 2025-08-08 13:11:40 +02:00
Geert Rademakes
597c8f994f feat(dnd): highlight playlist drop target; show drag count badge; refine drag payload and lifecycle 2025-08-08 13:08:22 +02:00
Geert Rademakes
6917c22b94 feat(dnd): drag songs (with multiselect) into sidebar playlists; drop handler adds to playlist with duplicate confirm (allow or skip) 2025-08-08 13:00:40 +02:00
Geert Rademakes
3bd110884c feat(admin): add /api/music/fix-content-types to correct MIME types; ensure sync sets proper contentType for FLAC and others 2025-08-08 12:04:05 +02:00
Geert Rademakes
5144df2e93 fix(flac): set correct contentType for FLAC and other types in S3 sync; include contentType hint in stream endpoint response 2025-08-08 12:02:03 +02:00
Geert Rademakes
dbf9dbcb8c fix(sync): reference correct processed count in job result; fix(search): keep focus in search while playing by blurring audio and focusing search; cleanup lints 2025-08-08 11:30:59 +02:00
Geert Rademakes
70485e8808 fix(player): prevent audio element from stealing focus while playing (blur and tabIndex=-1) so search input remains usable 2025-08-08 11:15:47 +02:00
Geert Rademakes
2e21c3b5f5 fix(matching): strip diacritics in matching and quick match so accented letters (e.g., é) match plain equivalents 2025-08-08 11:06:48 +02:00
Geert Rademakes
07044c7594 fix(matching): URL-decode filenames and Rekordbox locations during quick match and location matching (%20, %27 etc.) 2025-08-08 11:00:08 +02:00
Geert Rademakes
fe282bf34f feat(frontend): show Rekordbox path in SongDetails for selected song 2025-08-08 10:52:38 +02:00
Geert Rademakes
9c8bf11986 fix(background-jobs): poll job list continuously so newly started jobs appear immediately in the floating widget 2025-08-08 10:20:30 +02:00
Geert Rademakes
7618c40a77 fix(frontend): center loading spinner on large screens by using full-viewport container and removing #root max-width constraint 2025-08-08 09:49:02 +02:00
Geert Rademakes
4f440267bd feat(frontend): start S3 sync via background job API and rely on progress widget instead of direct endpoint; remove unused MusicStorage page 2025-08-08 09:37:41 +02:00
Geert Rademakes
31a420cf5c perf(backend): reduce projection for playlist total duration calculation; fewer fields fetched 2025-08-08 09:18:48 +02:00
Geert Rademakes
940469ba52 chore(refactor): remove unused files (TwoPhaseSyncService, unused frontend types) 2025-08-08 09:18:06 +02:00
Geert Rademakes
f6ecd07d98 feat(duplicates): add filter to show only groups where at least one song is in a playlist 2025-08-08 09:09:31 +02:00
Geert Rademakes
f7f44f2c48 feat(duplicates): add backend delete-duplicates and UI action to delete redundant songs after merging playlists 2025-08-08 09:07:45 +02:00
Geert Rademakes
549fd8d525 feat(duplicates): horizontal scroll table, keep-one merge playlists action, add length/BPM/bitrate columns\n\n- Backend: include averageBpm, bitRate in duplicates payload\n- Frontend: scrollable table with Keep action to merge playlists to selected song; show length/BPM/bitrate 2025-08-08 08:59:54 +02:00
Geert Rademakes
7dc70c3bdf feat(duplicates): add backend endpoint to detect possible duplicates and new Config tab to display them\n\n- Backend: GET /api/songs/duplicates groups by normalized title+artist and lists playlists + paths\n- Frontend: DuplicatesViewer component and new tab in Configuration; fetch on open; adjustable min group size\n- API client: add getDuplicateSongs() 2025-08-08 08:51:23 +02:00
Geert Rademakes
83b4682b0e chore(frontend): remove live song-list refresh during S3 sync per request; refresh now only on manual actions/page reload 2025-08-08 08:47:39 +02:00
Geert Rademakes
482460a8b7 feat(frontend): live-refresh song list during S3 sync so newly matched tracks show play button immediately
- BackgroundJobProgress exposes onTickWhileS3Sync callback
- App wires callback to usePaginatedSongs.refresh() to pull fresh song data while sync runs
2025-08-07 23:47:58 +02:00
Geert Rademakes
d231073fe0 feat(frontend/config): UX improvements
- Disable 'Sync S3' buttons when no S3 config present; add hint
- Remember active config tab via localStorage; enable isLazy Tabs
- Lazy-load Music Library data only when its tab is opened
- Clarify 'Auto-Link' as a cleanup action; disable when nothing to link
- Limit matching tab API calls with ?limit to reduce payloads
2025-08-07 23:41:33 +02:00
Geert Rademakes
b436d1dabc feat: implement immediate song document updates for perfect sync resilience
- Remove end-of-job cleanup phases from S3 sync and song matching jobs
- Update Song documents immediately after each successful match in both Phase 1 and Phase 2
- Ensure hasS3File flag is set to true immediately for each matched song
- Enable play buttons to appear instantly as songs are processed
- Make system perfectly resilient to interruptions - no orphaned files
- Allow seamless resume capability for long-running sync jobs
- Provide real-time availability of matched songs without waiting for job completion
- Maintain system consistency regardless of when sync gets interrupted
2025-08-07 23:36:30 +02:00
Geert Rademakes
96c43dbcff feat: implement infinite scroll with 100 songs per page
- Update pagination from 50 to 100 songs per page for better UX
- Frontend: Update usePaginatedSongs hook default pageSize to 100
- Frontend: Update API service default limits to 100
- Frontend: Update App.tsx pageSize configuration to 100
- Backend: Update songs routes default limit to 100 for both main and playlist endpoints
- Maintain existing infinite scroll functionality with larger batch sizes
- Improve performance by reducing number of API calls needed
- Verified API endpoints return correct pagination info and song counts
2025-08-07 20:23:05 +02:00
Geert Rademakes
3cd83ff2b5 feat: improve S3 sync and song matching with better FLAC support, NaN validation, and enhanced logging
- Enhanced AudioMetadataService with comprehensive NaN handling for all numeric fields
- Added validation for year, duration, bitrate, sampleRate, and channels
- Improved FLAC format detection and error handling with fallback support
- Added detailed logging for S3 sync process with progress tracking and file statistics
- Enhanced song matching service with progress indicators and confidence scoring
- Added comprehensive logging for auto-match and link operations
- Improved error handling and graceful degradation for metadata extraction
- Added test scripts for metadata service validation
- Updated S3 service to use configuration from s3-config.json file
- Added automatic S3 service reload when configuration is updated

The S3 importer now provides much better visibility into file processing
and song matching operations, making it easier to debug issues and
monitor performance. FLAC files are properly handled and invalid
metadata values are filtered out to prevent database corruption.
2025-08-07 17:14:57 +02:00
Geert Rademakes
050e31288a chore: Remove debug endpoint after playlist issue resolution
- Remove /api/songs/debug/playlist/:name endpoint
- Debug endpoint was temporary and no longer needed
- Playlist loading issue resolved by database reload
- Clean up code after successful troubleshooting
2025-08-07 08:57:10 +02:00
Geert Rademakes
176c2b1574 feat: Add debug endpoint for playlist troubleshooting
- Add /api/songs/debug/playlist/:name endpoint
- Debug endpoint shows playlist structure and track data
- Lists all available playlists when target not found
- Shows track IDs and whether songs exist for those IDs
- Helps diagnose playlist loading issues
- Useful for troubleshooting missing songs in playlists

This will help identify why songs are not showing in playlists like 'Disco'.
2025-08-06 16:04:44 +02:00