svelte-i18n requires { values: { key: value } } format for variable
interpolation, not { key: value } directly. Fixed across all toast
and greeting calls.
- Add time-based greeting translations (goodMorning, goodAfternoon,
goodEvening, goodNight) to homeSettings section
- Update homeSettingsStore to export getGreetingInfo for i18n support
- Update HomeView.svelte to use translated greetings
- Add comprehensive toast translations (~60 keys) for all user-facing
notifications including queue, playback, offline, favorites, etc.
- Update +page.svelte to use $t() for all showToast calls
- Complete Spanish translations for all new keys
- TrackRow: Add isBlacklisted prop with grayout styling and ban icon
- VirtualizedTrackList: Check blacklist status for each track
- PlaylistDetailView: Gray out and restrict actions for blacklisted tracks
- AlbumDetailView: Apply album-level blacklist check to all tracks
- HomeView: Gray out blacklisted tracks in Continue Listening section
- ArtistDetailView: Banner shown when viewing blacklisted artist page
Blacklisted tracks show reduced opacity, ban icon instead of track
number, and restricted menu actions (navigation only, no playback).
- Default view shows only parent genres (less cluttered like Qobuz)
- When selecting a parent, filtering includes all its sub-genres
- Added "Show all sub-genres" toggle for granular control
- Store now tracks parent/child relationships for proper filtering
- getFilterGenreNames() returns selected + children for filtering
- Allow multiple genre selection (checkbox behavior)
- Add getSelectedGenreNames() for multiple name retrieval
- Merge results from multiple API calls for featured albums
- Clear button now closes the popup
- Button shows "N genres" when multiple selected
- Add getSelectedGenreName() to genre filter store
- Add filterAlbumsByGenre() helper in HomeView
- Apply genre filter to Recently Played and Favorite Albums
- Fetch 3x more items when filtering to ensure enough results
- Add GenreFilterButton to home header
- Pass genre_id to fetchFeaturedAlbums API calls
- Reload home content when genre filter changes
- Featured sections now filter by selected genre
- 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.
- Use size="large" (180px) for all AlbumCard instances
- Change album grids from CSS grid with 1fr to flexbox
- Fix LocalLibrary gap issue by using consistent spacing
- Align VirtualizedAlbumList, ArtistDetailView, SearchView,
FavoritesView, HomeView, and AlbumDetailView
- Add onTrackShowInfo to HomeView (Continue Listening tracks)
- Add onShowInfo to VirtualizedTrackList (for FavoritesView)
- Add onTrackShowInfo to FavoritesView and wire to VirtualizedTrackList
- Pass showTrackInfo to HomeView and FavoritesView in +page.svelte
- Add clickable artist name to TrackInfoModal header
- Artist link navigates to artist page and closes modal
Pass sidebarExpanded prop to HomeView to dynamically position the
loading overlay based on sidebar width (280px expanded, 64px collapsed).
Added smooth transition for left position.
- Created open_track_folder Rust command to open folder containing downloaded track
- Added frontend wrappers: openTrackFolder and reDownloadTrack in downloadState.ts
- Updated all Qobuz views to support Download submenu:
- HomeView: Added track download props and handlers
- AlbumDetailView: Added onTrackOpenFolder and onTrackReDownload
- SearchView: Added track download actions to both TrackMenu usages
- FavoritesView: Added download submenu to both track list variants
- Downloaded tracks now show submenu with 'Open containing folder' and 'Re-download' options
- Completes Phase 2 Task 2.1: Context Menu Homogenization (Download)
Multiple critical fixes for context tracking:
1. Add 'local_library' to backend context type parser
- Was rejecting 'local_library' causing "Invalid context type" error
- Now properly recognized in set_playback_context command
2. Fix shuffle to not always start with first track
- Removed logic that moved current track to front of shuffle
- Now finds current track position in shuffled order instead
- Shuffle is truly random, not biased to original order
3. Add missing await to all setPlaybackContext calls
- PlaylistDetailView: await context creation
- FavoritesView: make setFavoritesContext async + await calls
- ArtistDetailView: await context creation
- HomeView: await context creation
- SearchView: await + use home_list type (search type doesn't exist)
This fixes intermittent context tracking (race condition)
Fixes: shuffle starting with first song, Local Library context error,
intermittent playlist/favorites/artist/home/search context tracking
cc
Context creation:
- Creates 'home_list' context for Continue Listening section
- Uses 'continue_listening' as ID and 'Continue Listening' as label
- Tracks user's listening history in a context
- Stack icon will show "Playing from: Continue Listening"
Home view now fully integrated with context system.
cp
- Increase artist detail album fetch from 100 to 500
- Increase bio truncation from 300 to 500 chars
- Add Others category for greatest hits/anthologies
- Add configurable limits for Home sections
- Update HomeSettingsModal with limits grid UI
cp
Add downloadStateVersion prop to AlbumCard component to make download
status reactive in all grid views. This fixes the issue where the
download menu submenu would not appear in Home, Search, and Artist
Detail views even when albums were fully downloaded.
cp
- Force Map reactivity by re-assigning after .set()
- Add missing downloadStateVersion effect in SearchView
- Ensures download menu updates across all grid views
cp
Load download status for all albums when they are first loaded
in grid views (Home, Search, Artist Detail, Favorites) so the
'Download Album' menu shows correct state immediately.
cp
- Add backend command to check if album is fully downloaded
- Add frontend functions to check album download status
- Pass download handlers to HomeView
- Update HomeView AlbumCards with download status props
cp
- Add consistent scrollbar styling to all view components
- Scrollbar is visible (subtle) by default, brighter on hover
- Position scrollbar 8px from right edge
- Each view now handles its own scroll container
- Add compact prop to TrackRow: smaller height (44px), artist as column
- Apply compact mode to Continue Listening section in Home
- Reduces vertical space and improves scannability
- Create favoritesStore.ts for centralized favorites state management
- Refactor TrackRow to be self-sufficient with internal favorites handling
- TrackRow now subscribes to store and toggles favorites internally
- Remove redundant favoriteTrackIds state from AlbumDetailView and PlaylistDetailView
- Remove manual onAddFavorite prop drilling from all views
- Add trackId prop to TrackRow for store lookup (optional for local tracks)
- Add hideFavorite prop for local tracks that don't have Qobuz IDs
- Load favorites once on app init in +page.svelte
Loading overlay:
- Wait for ALL visible sections to finish loading before hiding overlay
- Count total visible sections and track when each finishes
- Content renders behind overlay, then overlay fades out smoothly
Continue Listening:
- Add menuActions with onAddFavorite to TrackRow
- Import handleAddToFavorites from trackActions service
- Favorite button now works in Continue Listening section
TrackRow:
- Convert favorite indicator div to interactive button
- Add stopPropagation to prevent row click (play) when clicking favorite
- Add hover state and proper button styling
HomeView:
- Add loading overlay that waits for at least 2 sections to load
- Overlay fades out smoothly when content is ready
- Prevents jarring "sections appearing and reordering" effect
- Add qobuzissimes and editorPicks sections (disabled by default)
- Conditional loading to save API calls when sections are hidden
- Note: These API types may not be confirmed working
- Add mostStreamed section using album/getFeatured most-streamed
- Optimize API calls by only fetching visible sections
- Default to hidden (enable via Home settings)
- Remove immediate listener call in subscribe() to prevent effect loop
- Use onMount instead of $effect for subscriptions to avoid reactive tracking
- Combine onMount callbacks in HomeView