- Removed early return that blocked Various Artists clicks
(album header already protected via HTML condition)
- Added special case in selectedArtistAlbums: when user selects
"Various Artists", show all albums with that artist name
- Remove background from artist column, integrate with main background
- Add vertical border line separating artist list from albums view
- Wrap artists tab content in flex container for proper height
- Artist list now fills full available height (no gaps at top/bottom)
- Adjusted padding and margins for better visual integration
- Adjusted artist two-column layout height to account for NowPlayingBar
(was calc(100vh - 320px), now calc(100vh - 424px))
- Added 100ms delay before scrolling to artist card to ensure content
is fully rendered after tab switch
- Artist name in album header now clickable (except for Various Artists)
- Clicking artist navigates to Artists tab, scrolls to artist card,
and shows their albums
- Track artist links (when different from album artist) work the same
- Added IDs to artist cards for scroll targeting
- Navigation history updated so back button returns to album view
- Handle undefined/null values in cache stats with nullish coalescing
- Show "No cached artwork" when both counts are 0
- Use outlined style for Clear All button (consistent with others)
- Simplified description text
1. Play button fix: After resuming on cast device, update playerStore.isPlaying
so the UI shows the correct playing state immediately.
2. Disconnect handoff: When disconnecting from Chromecast/DLNA while playing:
- Captures current track and position from cast state
- Shows confirm dialog asking if user wants to continue locally
- If yes, starts local playback and seeks to saved position
- If no, just resets player state
This provides seamless transitions in both directions:
- Local → Cast: auto-resumes with position
- Cast → Local: asks user, then resumes with position
When user connects to a Chromecast/DLNA device while local playback is
active, the local stream was conflicting with the cast stream.
Now connectToDevice():
1. Captures current track info and position
2. Stops local playback completely
3. Establishes the cast connection
4. Automatically resumes the track on the cast device
5. Seeks to the saved position (if > 5 seconds)
This provides seamless handoff from local to cast playback.
- Added artwork thumbnails cache stats and clear button
- Shows legacy artwork files count if old cache exists
- Added "Clear All Caches" button that clears all cached data at once
- Danger button styling for destructive action
- metadata.rs now creates 500px thumbnails instead of copying full images
- Added cache management commands: library_get_cache_stats,
library_clear_artwork_cache, library_clear_thumbnails_cache
- Thumbnails stored in ~/.local/share/qbz/thumbnails/ (was ~/.cache/qbz/artwork)
- Reduces cache size from GB to MB for large libraries
Quality was hardcoded to UltraHiRes in backend. Now:
- Frontend passes quality from localStorage to play_track command
- Backend parses quality string to Quality enum
- All prefetch and stream URL calls use the user's preferred quality
- Add all_artists field to LocalAlbum for accurate artist matching
- Consolidate duplicate artists with case differences (e.g., "Alice in Chains" / "Alice In Chains")
- Fix album count calculation to avoid double-counting
- Show Various Artists albums under contributing artists
- Handle multi-artist names (e.g., "A, B, C") with union matching
- Add cleanup missing files feature in settings maintenance section
- Improve settings UI with side-by-side Maintenance/Danger Zone layout
- Add status indicator during cleanup operations
- Remove background/border from Qobuz badge, show icon at full 24px
- Keep background only for local badge (HardDrive icon)
- Add console logging when selecting artist to debug mismatch:
- Shows selected artist name (original and normalized)
- Shows which albums match
- Shows artist data from the artists array
- Add Local and Offline cache filters to the filter panel
- Icons: HardDrive for local, Qobuz logo for offline cache
- Remove CSS filter from Qobuz badge icon (display as-is with proper size)
- Fix alphabetical index scroll to work within the artist list container
- Add scroll reference binding to artist-list-scroll
- Fix group header ID (was duplicating prefix)
- Include multi-artist albums when selecting an artist:
- Exact match on album artist
- Partial match (artist name appears in album artist string)
- Split by common separators (,&feat.ft.featuring, etc.)
- Move alphabetical index from vertical (right) to horizontal (top)
- Replace full-width grid with two-column layout:
- Left: Single-column artist list with compact cards and scroll
- Right: Selected artist's albums in a grid
- Hide group dropdown and view mode toggle (kept in code for future use)
- Click artist to select and show their albums (instead of navigating to Qobuz)
- Defaults to alphabetical grouping and grid view
Albums now show a small badge indicating their source:
- HardDrive icon for local files (source='user')
- Qobuz logo for offline cached content (source='qobuz_download')
Badge appears in bottom-right corner of album artwork.
Flatpak uses the <releases> section in metainfo.xml to display the
application version. Added a placeholder release entry and updated
the workflow to inject the actual version and date during build.
When deleting a cached track (individually, via clear all, or via LRU
eviction), the audio file was deleted but cover.jpg remained orphaned.
Now the system removes the entire album folder if no audio files remain,
and recursively removes the artist folder if it also becomes empty.
- Add getTrackOfflineCacheStatus prop to HomeView
- Pass downloadStatus and downloadProgress to TrackRow
- Use reactive cache status function that depends on downloadStateVersion
Tracks in Continue Listening now correctly show their cached state.
Include downloadStateVersion in the each loop key to force re-render
when offline cache state changes, fixing tracks showing gray icons
even when cached.
- Add preview (play) button to suggested tracks
- Remove pagination info for cleaner UX ("Showing X of Y")
- Remove "Load more" links (auto-loads when cycling)
- Add onPreviewTrack callback to play suggested tracks
- Convert SuggestedTrack to DisplayTrack for playback
- Add artist_id field to SuggestedTrack for navigation
- Make artist names clickable to navigate to artist view
- Make album names clickable to navigate to album view
- Add TrackInfo button (info icon) to view track credits
- Integrate TrackInfoModal component with suggestions
- Update PlaylistDetailView to pass navigation callbacks
The build_vector function was calling build_from_musicbrainz and
build_from_qobuz while holding the store lock. These functions also
try to acquire the store lock, causing a deadlock.
Fixed by saving the vectors from the first call and reusing them
for storage, instead of calling the functions again.
Major optimizations:
- Extract only top 5 artists by track frequency instead of all artists
- Use faster rate limiter (200ms) when using MusicBrainz proxy
- Remove skip_vector_build since we now have manageable artist count
Expected load time: ~5-8 seconds for first load with 5 artists
vs previous: 50+ seconds with 50 artists
Instead of showing 'No suggestions available' message, the entire
suggestions section is now hidden when there are no results.
Better UX - less frustrating for users.
When skip_vector_build is enabled, also skip network calls for MBID
resolution of uncached artists. This prevents rate limiting (429) errors
that were causing 55+ second delays on initial load.
Tradeoff: First load with empty cache may have no results, but
subsequent loads will be instant using cached data.
- Add skip_vector_build config option to SuggestionConfig
- When true, skips ensure_vector calls (which can be very slow)
- Uses only cached/existing vectors for similarity search
- Frontend now uses skip_vector_build=true for initial load
- Add timestamped logging helper in frontend component
- Move MBID resolution from frontend to backend
- Eliminates multiple sequential IPC calls
- Uses MusicBrainz cache for faster resolution
- Logs resolution progress for debugging
- Implement progressive loading in UI
- Initial load: 18 tracks (3 pages)
- "Load more" expands to 60 tracks on demand
- Better feedback during loading states
- Fix refresh button styling
- Remove background while spinning
- Update title based on available actions
- Add "Load more" link in pagination area
- Create PlaylistSuggestions.svelte component with:
- Pool management (60 tracks, show 6 at a time)
- Pagination/rotation on refresh
- Loading, empty, and error states
- Add (+) and dismiss (-) track actions
- Album art display
- Reason tooltip support (dev mode)
- Create playlistSuggestionsService.ts with:
- MBID resolution from artist names (batched)
- TypeScript types for SuggestedTrack, SuggestionResult
- localStorage helpers for dismissed tracks
- Qobuz album art URL generation
- Integrate into PlaylistDetailView:
- Show suggestions at bottom of playlist track list
- Extract unique artists from playlist for suggestions
- Add track to playlist via add_tracks_to_playlist command
- Hide when searching
- Add weights.rs with configurable RelationshipWeights
- Add builder.rs with ArtistVectorBuilder for constructing vectors
- Integrate MusicBrainz relationships (members, groups, collaborators)
- Integrate Qobuz similar artists API
- Add ensure_vector() with TTL for lazy building
- Add resolve_qobuz_to_mbid() for ID resolution via name search
- 21 tests passing (sparse_vector, store, weights, builder)