- Create FavoritesView with tabs for tracks, albums, and artists
- Fetch favorites from backend API
- Support Play All and Add to Queue for tracks
- Display albums in grid with AlbumCard
- Display artists with circular avatars
- Wire up in +page.svelte
- Create PlaylistDetailView with header, artwork, and track list
- Fetch playlist data from backend on mount
- Support Play All, Shuffle, and Add to Queue actions
- Wire up track play handler in +page.svelte
- Display playlist owner, track count, and total duration
Backend:
- Add playlist.rs commands: get_user_playlists, get_playlist, search_playlists
- Add favorites.rs commands: get_favorites, add_favorite, remove_favorite
- Add API client methods: search_playlists, add_favorite, remove_favorite
Frontend:
- Remove Radio and New from sidebar (no API support)
- Sidebar now loads and displays user playlists dynamically
- Add playlist and favorites views (placeholder for now)
- Pass selectedPlaylistId and onPlaylistSelect to Sidebar
- Replace all Tauri icons with QBZ logo variants
- Update LoginView splash screen to use logo.png
- Add logo.png to static folder for web use
- Update favicon.png with QBZ icon
- Replaced 7 separate Mutex fields with single InternalState struct
- Prevents deadlock when multiple locks acquired in different orders
- Same pattern as AudioCache fix
- Fixed borrow checker issue in add_track method
- Add AudioCache module with LRU eviction (500MB default)
- Cache downloaded tracks in memory
- Prefetch next track in queue while current track plays
- Play from cache instantly when track is already cached
- Background prefetch task runs without blocking playback
- Add onPlayAll, onShuffleAll, onAddToQueue props to AlbumDetailView
- Implement handlePlayAllAlbum to play album from first track
- Implement handleShuffleAlbum to enable shuffle and play
- Implement handleAddAlbumToQueue to append album to existing queue
- Add QueueManager in Rust backend with shuffle, repeat modes, and history
- Create queue Tauri commands (add, remove, next, previous, play_index, etc.)
- Wire Next/Previous buttons to backend queue
- Auto-advance to next track when current track ends
- Sync queue state with frontend QueuePanel
- Wire shuffle and repeat toggles to backend
- Add queue population when playing from album detail view
Sidebar:
- Remove placeholder playlists (My Playlist 1/2/3)
- Keep only Favorites under Playlists section
NowPlayingBar:
- Remove hardcoded placeholder values (Irreplaceable, etc.)
- Add empty state when no track is playing
- Fix remaining time to be dynamic (duration - currentTime)
- Add artwork placeholder when image is missing
- Handle quality dots visibility properly
Backend (Rust):
- Add souvlaki crate for MPRIS support on Linux
- Create media_controls module with MediaControlsManager
- Track metadata (title, artist, album, duration, cover)
- Playback state (playing/paused/stopped)
- Wire pause/resume/stop commands to update MPRIS
- Add set_media_metadata Tauri command
Frontend (Svelte):
- Call set_media_metadata when track starts playing
- Send track info to MPRIS for system integration
Now shows track info in system media controls and
supports media key events (logged for now).
Backend (Rust):
- Add position tracking based on elapsed wall clock time
- SharedState now tracks playback start time and position at start
- get_state() returns real-time position instead of stale value
- Position automatically pauses/resumes with playback
Frontend (Svelte):
- Replace dumb setInterval timer with backend polling (500ms)
- Poll get_playback_state to sync position from Rust
- Add onSkipBack/onSkipForward handlers to NowPlayingBar
- Add onSkipBack/onSkipForward handlers to FullScreenNowPlaying
- Wire skip buttons to handlers (restart if >3s, otherwise previous)
- Add keyboard shortcuts: Ctrl+Left/Right for skip
The regex pattern for extracting info/extras from the Qobuz bundle
was incorrect. The pattern now:
- Dynamically builds timezone alternatives from extracted seeds
- Capitalizes timezone names to match bundle format (e.g., "Berlin")
- Correctly parses the name:"\w+/Timezone" format
- Converts back to lowercase for seed lookup
This enables successful FLAC streaming from Qobuz.
- Add track ID and duration to Track interface
- Update convertQobuzAlbum to include track metadata
- Add onTrackPlay prop to AlbumDetailView
- Create handleAlbumTrackPlay handler
- Improve error handling in playback (don't set isPlaying on error)
- Add app.css import to +layout.svelte (fixes broken/light UI)
- Add logging for audio debugging
- Add image fallbacks for album and track artwork
- Fix sidebar/main-content layout (flex-shrink, min-width)
- Remove placeholder data from HomeView
- Add LoginView and SearchView components
- Update window title and branding to QBZ
- Add svelte-i18n dependency
- Create i18n configuration with locale persistence
- Add complete translation files for EN and ES
- Create root layout with theme CSS variables
- Support 4 themes: dark (default), light, oled, warm
- Add global styles and spacing system