Commit Graph
7005 Commits
Author SHA1 Message Date
vicrodh 490cd2f9ea fix: constrain search button height to prevent square expansion 2026-01-09 14:59:00 -06:00
vicrodh cdc06d8759 fix: multiple UX improvements and bug fixes
Playlist & Favorites:
- Fix playlist loading error (missing field `id` in JSON parsing)
- Add serde defaults for Track and PlaylistOwner optional fields
- Fix track favorites toggle to actually call backend API
- Add "Add to playlist" button on track rows in album view

Sidebar UI improvements:
- Increase sidebar width to 280px
- Reduce text size and margins throughout
- Normalize all icons to 14px (matching + and refresh buttons)
- Add text overflow with ellipsis and tooltip for playlist names

User card:
- Make user card more compact (smaller avatar, fonts, icons)
- Add collapsible toggle - when collapsed shows mini QBZ logo + username

Queue & Playback:
- Fix next_track spam when queue has only one song (queueEnded flag)

Other fixes:
- Fix TrackRow prop types (remove invalid hires, bitDepth, samplingRate props)
- Fix FavoritesView and PlaylistDetailView component prop types
- Add diagnostic logging to credential persistence
2026-01-09 14:55:53 -06:00
vicrodh 6eed045404 feat(auth): add secure credential persistence using system keyring
- Add keyring crate for secure credential storage (KWallet/GNOME Keyring)
- Create credentials module with save/load/clear functions
- Add auto_login command that uses saved credentials
- Add "Remember me" checkbox to login form (default: checked)
- Auto-login on app startup if credentials are saved
- Clear credentials from keyring on logout
- Show dynamic status during initialization (connecting, checking, logging in)
2026-01-09 14:37:49 -06:00
vicrodh 541f46e430 feat(integrations): add Discogs artwork fetch and fix Last.fm env loading
- Add Discogs API client for fetching missing album artwork
- Add UI button in Local Library settings to fetch missing artwork
- Load .env file at runtime using dotenvy for development
- Fix Last.fm to check runtime env vars as fallback to compile-time
- Use XDG Portal for dialog plugin (cross-desktop compatibility)
- Update README and .env.example with Discogs configuration
2026-01-09 14:30:35 -06:00
vicrodh f6dbf2ee2a feat(library): extract and display album artwork
- Extract embedded artwork from audio files during scan
- Save extracted artwork to cache directory (~/.cache/qbz/artwork)
- Fallback to folder artwork (cover.jpg, folder.jpg, front.jpg, etc.)
- Add get_artwork_cache_dir helper function
- Artwork now displays in album cards and detail views
2026-01-09 14:07:09 -06:00
vicrodh e8a61a45ce feat(library): improve local library UX and audio metrics
- Move Local Library section below Playlists in sidebar (Qobuz is main B.U.)
- Replace text input with native XDG folder picker dialog
- Add bit_depth and sample_rate to LocalAlbum model
- Display rich audio specs in album detail view (format, bit depth, sample rate, channels)
- Show format quality badge on album cards (e.g. "FLAC 24/96")
- Add Hi-Res visual indicator for 24-bit or >48kHz content
2026-01-09 14:05:17 -06:00
vicrodh b0a64b9caa feat: add tauri-plugin-dialog for file picker 2026-01-09 13:56:10 -06:00
vicrodh daaef7f0b1 fix: resolve Svelte component directive error and clarify README 2026-01-09 13:54:44 -06:00
vicrodh f7ca1a9557 feat(playlists): add local playlist enhancements
- Add playlist settings table for storing local-only features per playlist
- Add playlist local tracks table for mixing local tracks into Qobuz playlists
- Implement search within playlist (filters by title, artist, album)
- Add custom sorting (by title, artist, album, duration, ascending/descending)
- Add custom artwork selection with file picker
- Create .env.example for Last.fm credentials setup
- Update README with environment configuration instructions
2026-01-09 13:51:54 -06:00
vicrodh 24f551b571 feat(playlists): add playlist management UI
- Create PlaylistModal component for create/edit/add tracks
- Add "New Playlist" button to Sidebar
- Add refresh button for playlists in Sidebar
- Wire playlist creation modal into main page
- Support creating playlists and adding tracks to existing playlists
2026-01-09 13:41:46 -06:00
vicrodh caca535cc0 feat(playlists): add Qobuz playlist management API
- Add create_playlist API method and command
- Add delete_playlist API method and command
- Add add_tracks_to_playlist API method and command
- Add remove_tracks_from_playlist API method and command
- Add update_playlist API method and command
- Register all new commands in invoke_handler
2026-01-09 13:39:02 -06:00
vicrodh fb105948ac docs: update README branding and add LICENSE 2026-01-09 13:36:09 -06:00
vicrodh 768a267e86 chore: remove internal docs (moved to qbz-nix-docs) 2026-01-09 13:36:05 -06:00
vicrodh 80556e219f feat(library): add local library frontend UI
- Create LocalLibraryView component with albums, artists, tracks tabs
- Add folder management (add/remove library folders)
- Add library scan progress indicator
- Add album detail view with track list
- Integrate local track playback with queue system
- Track local vs Qobuz tracks for proper skip/advance behavior
- Update Sidebar with simplified Library navigation
2026-01-09 13:36:00 -06:00
vicrodh 20e4d1b0ed docs: refresh README positioning and features 2026-01-09 13:30:11 -06:00
vicrodh bcfd9bbf48 docs: add Codex prompt for Chromecast integration 2026-01-09 13:27:24 -06:00
vicrodh 1895812830 feat(library): integrate local library module from Codex
Full local library implementation with:
- Filesystem scanner for FLAC, WAV, AIFF, APE, ALAC files
- Metadata extraction using lofty crate
- CUE sheet parsing for single-file albums
- SQLite persistence with WAL mode
- 13 Tauri commands for library management

Commands:
- library_add_folder, library_remove_folder, library_get_folders
- library_scan, library_get_scan_progress
- library_get_albums, library_get_album_tracks, library_get_artists
- library_search, library_get_stats, library_clear
- library_get_track, library_play_track (with CUE seek support)

Based on implementation by Codex in local-library worktree.
2026-01-09 13:23:32 -06:00
vicrodh 8b378ddb28 docs(casting): update with active rust-cast crate (azasypkin fork) 2026-01-09 13:08:02 -06:00
vicrodh 19bad7200b feat(lastfm): improve auth flow with embedded credentials support
- Add support for build-time credentials via LASTFM_API_KEY/LASTFM_API_SECRET env vars
- Add lastfm_has_embedded_credentials command to check for embedded keys
- Add lastfm_open_auth_url command to open browser via native opener
- Simplify UI flow: if embedded credentials exist, just click Connect
- Add cancel button during authorization flow
- Clean up UI when waiting for user to authorize in browser
2026-01-09 13:02:05 -06:00
vicrodh 480594c03c docs: add casting/streaming research document 2026-01-09 12:50:19 -06:00
vicrodh af44e14b0b feat(favorites): wire album favorite button to Qobuz API
- Add album id to AlbumDetail interface and conversion
- Add artist id to enable artist navigation from album view
- Wire heart button in AlbumDetailView to call add_favorite/remove_favorite
- Fix artist click to use actual artist id instead of hardcoded 0
2026-01-09 12:46:09 -06:00
vicrodh ddbe6b5706 fix(player): detect track completion to enable auto-advance
Change audio thread from blocking recv to recv_timeout, periodically
checking if the sink is empty. When playback finishes naturally, set
is_playing to false so the frontend can trigger auto-advance to next.
2026-01-09 12:43:58 -06:00
vicrodh 7a53d62341 fix(search): add offset parameter for proper pagination
- Add offset parameter to search_albums, search_tracks, search_artists
- Backend now properly passes offset to Qobuz API
- Fixes duplicate results when loading more search results
2026-01-09 12:35:29 -06:00
vicrodh 5669ae023a docs: add Codex implementation guide for local library feature 2026-01-09 12:29:27 -06:00
vicrodh 83654866f1 fix(playlist): fix state management in playlist commands
- Change playlist commands to use AppState instead of direct Arc<Mutex>
- Add playlist management endpoint paths for future use
2026-01-09 12:13:46 -06:00
vicrodh 8f4a47b2d8 fix(mpris): update progress during playback polling
- Update MPRIS position every time get_playback_state is polled (~500ms)
- Update MPRIS position when seeking
- Add Default derive to PlaybackState for error fallback
- System media controls now show accurate playback progress
2026-01-09 12:12:26 -06:00
vicrodh 0075b5fc60 feat(search): add lazy loading for search results
- Add Load More buttons for albums, tracks, and artists tabs
- Track pagination state with hasMore* derived values
- Accumulate results as users load more pages
- Style Load More button with hover and disabled states
2026-01-09 12:10:26 -06:00
vicrodh ff7b598522 Add song.link (Odesli) sharing integration
- Create share module with SongLinkClient for Odesli API
- Support for tracks via ISRC and albums via UPC
- In-memory cache with 1-hour TTL
- Commands: share_track_songlink, share_album_songlink
- Qobuz URL generators for tracks, albums, artists
- Proper error handling for missing identifiers
2026-01-09 12:07:48 -06:00
vicrodh 7e2740d297 Fix favorites commands using wrong state type
Commands were using State<Arc<Mutex<QobuzClient>>> directly instead of
State<AppState>. Changed to use AppState like all other commands.
2026-01-09 12:05:20 -06:00
vicrodh c7145e889b Add language setting and Last.fm integration
Settings:
- Add language dropdown (Auto, English, Español, etc.) with persistence

Last.fm:
- Create lastfm module with API client for authentication and scrobbling
- Add commands for auth flow, now playing, and scrobbling
- Full OAuth-style authentication with token exchange
- UI for entering API credentials and authorizing
- Automatic scrobbling after 50% of track or 4 minutes
- Update 'now playing' when tracks start
- Session persistence in localStorage
2026-01-09 11:23:01 -06:00
vicrodh 9d040fee55 Add audio device enumeration and streaming quality persistence
- Add get_audio_devices command to list available output devices
- Show real audio devices in Settings dropdown
- Persist streaming quality preference in localStorage
- Persist 'prefer highest available' setting
2026-01-09 11:13:43 -06:00
vicrodh 9b8e1352eb Wire settings: account info, themes, and cache management
- Account section now shows real user name and subscription
- Logout button connected to logout handler
- Theme switching with persistence (Dark/Light/OLED Black/Warm)
- Theme loads on app startup from localStorage
- Cache stats display (size, max, track count)
- Clear cache functionality with disabled state
2026-01-09 11:10:41 -06:00
vicrodh ef8feebc45 Add system notifications for track changes
- Add notify-rust dependency for desktop notifications
- Create notification.rs commands module with show_track_notification and show_notification
- Register notification commands in lib.rs
- Wire up notifications in frontend for all playback scenarios:
  - Search results playback
  - Album track playback
  - Playlist track playback
  - Queue navigation and auto-advance
2026-01-09 11:04:03 -06:00
vicrodh ddbedf6ab0 Implement FavoritesView component
- 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
2026-01-09 11:00:32 -06:00
vicrodh 5debf9c327 Implement PlaylistDetailView component
- 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
2026-01-09 10:51:39 -06:00
vicrodh bda4ea5b76 Add playlist and favorites commands, update sidebar
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
2026-01-09 10:49:43 -06:00
vicrodh dd2600feaa Add QBZ branding icons and logo
- 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
2026-01-09 10:35:24 -06:00
vicrodh 53e0fd0e10 Improve caching and UI sync
- Add skip operation guard to prevent concurrent track changes
- Implement aggressive prefetch (3 tracks ahead instead of 1)
- Add peek_upcoming method to queue for multi-track prefetch
2026-01-09 10:20:13 -06:00
vicrodh 5f7c0bb4fa Fix QueueManager deadlock: consolidate multiple mutexes into single state struct
- 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
2026-01-09 10:14:25 -06:00
vicrodh 913b80e09a fix: resolve deadlock in audio cache with single mutex 2026-01-09 10:05:29 -06:00
vicrodh 28bd316c89 feat: implement audio caching with prefetch
- 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
2026-01-09 09:59:21 -06:00
vicrodh 740a3a64fe feat: wire album Play, Shuffle, and Add to Queue buttons
- 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
2026-01-09 09:56:18 -06:00
vicrodh b5c853d945 feat: implement queue management system
- 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
2026-01-09 09:46:17 -06:00
vicrodh 2399f34103 chore: remove dummy text and improve empty states
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
2026-01-09 09:37:36 -06:00
vicrodh 62e59f599a feat: add MPRIS media controls integration
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).
2026-01-09 09:30:26 -06:00
vicrodh d1a13110ea feat: add real-time playback position sync and skip buttons
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
2026-01-09 09:26:02 -06:00
vicrodh b354161d82 chore: add mount logging to SearchView 2026-01-09 09:15:36 -06:00
vicrodh c454eeddbe fix: correct app secret extraction regex pattern
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.
2026-01-09 09:15:32 -06:00
vicrodh 09e1696d99 fix: add pointer-events: none to search button children 2026-01-09 09:00:04 -06:00
vicrodh 9b6fb7c0b8 debug: add logging to track search button click issues 2026-01-09 08:58:42 -06:00