Commit Graph
100 Commits
Author SHA1 Message Date
vicrodh 3ea2bb937b fix: update playlist and local track play to use playerStore
handlePlaylistTrackPlay and handleLocalTrackPlay were still using
local state variables directly instead of playerStore functions,
causing the UI to not react to playback state changes.
2026-01-10 05:00:57 -06:00
vicrodh c60cfe0525 refactor: extract queue state into queueStore
Move queue management into dedicated store:
- Queue tracks, shuffle, repeat modes
- Local track ID tracking for library playback
- Queue operations: add, clear, sync, navigate
- Backend queue state synchronization
2026-01-10 04:53:00 -06:00
vicrodh 55ec44cdc2 refactor: extract player state into playerStore
Move playback state management into dedicated store:
- PlayingTrack interface
- isPlaying, currentTime, duration, volume, isFavorite
- Polling logic with setOnTrackEnded callback
- Playback controls (togglePlay, seek, setVolume)
2026-01-10 04:48:31 -06:00
vicrodh cef950b08b refactor: extract navigation state into navigationStore
- Create navigationStore.ts for view navigation and history
- Implement navigateTo, goBack, goForward actions
- Add selectPlaylist for playlist detail navigation
- Update +page.svelte to use store subscription and functions
- Simplify navigation wrapper functions
2026-01-10 04:32:44 -06:00
vicrodh e98ea146e3 refactor: extract authentication state into authStore
- Create authStore.ts for managing login state and user info
- Implement setLoggedIn and setLoggedOut actions
- Update +page.svelte to use store subscription
- Simplify handleLoginSuccess and handleLogout handlers
2026-01-10 04:30:11 -06:00
vicrodh 6edfb5db06 refactor: extract UI/overlay states into uiStore
- Create uiStore.ts for overlay and modal visibility states
- Centralize queue panel, fullscreen, focus mode, cast picker states
- Add playlist modal state management with mode and track IDs
- Implement handleEscapeKey for prioritized overlay closing
- Update +page.svelte to use store subscription and functions
2026-01-10 04:28:34 -06:00
vicrodh 0e8371d900 refactor: extract toast notifications into toastStore
- Create toastStore.ts with centralized toast state management
- Add auto-hide functionality with configurable durations per type
- Update +page.svelte to use store subscription instead of local state
- Maintains existing toast behavior with improved separation of concerns
2026-01-10 04:25:45 -06:00
vicrodh 95488014a6 feat: implement functional seek in audio player
- Add Seek command to AudioCommand enum
- Store audio data in audio thread for re-seeking
- Use rodio's skip_duration to seek to desired position
- Preserve play/pause state after seeking
- Update playback timer to account for seek position
2026-01-10 04:21:56 -06:00
vicrodh baa656a508 feat: add local library tracks to Qobuz playlists
- Create AddToPlaylistModal component for selecting playlists
- Update PlaylistDetailView to merge local and Qobuz tracks
- Add visual indicator (HardDrive icon) for local tracks
- Show notice that local tracks are device-specific
- Add "Add to Playlist" option in Local Library track menu
- Connect local track play handlers for playlists
- Hide download button for local tracks in playlists
2026-01-10 04:01:44 -06:00
vicrodh 93a6e9545a feat: hide download button for local library tracks 2026-01-10 03:50:29 -06:00
vicrodh 16939e02f4 fix: use asset:// protocol for local library artwork in players 2026-01-10 03:48:54 -06:00
vicrodh fbfa067b94 feat(cast): add multi-protocol support for Chromecast, DLNA, and AirPlay
- Update CastPicker to show protocol tabs with device counts
- Register DLNA and AirPlay state and commands in lib.rs
- Add Deserialize derive to DlnaMetadata and AirPlayMetadata
- Fix capabilities file (remove unavailable fs permissions)
- Remove unused IpAddr import in media_server.rs
2026-01-10 03:41:11 -06:00
vicrodh 762df3e122 fix: Last.fm scrobbling and LocalLibrary cover art
- Restore Last.fm session on app startup (not just when visiting Settings)
- Fix LocalLibrary artwork: use asset://localhost/ instead of file://
- Add fs:allow-read capability for asset protocol
- Enable assetProtocol in tauri.conf.json
2026-01-10 03:36:31 -06:00
vicrodh 2bf9856179 feat(favorites): add download button and search to all tabs
- Add download functionality to FavoritesView tracks tab
- Add search input for each tab (tracks, albums, artists)
- Filter displayed items based on search query
- Show "no results" message when search has no matches
- Display filtered/total counts in toolbar
- Use buildDisplayTrack helper for cleaner code
2026-01-09 20:20:27 -06:00
vicrodh 5a07408acf fix(download): persist download state across views
- Add downloadStateVersion prop to trigger reactivity in child components
- Use version in each block keys to force re-evaluation when state changes
- Ensures download status persists whether track was downloaded from
  album view or playlist view
2026-01-09 20:11:39 -06:00
vicrodh 6de37c296b feat(download): add download button to playlist view and album download button
- Add download functionality to PlaylistDetailView (track-by-track)
- Add handleDisplayTrackDownload handler for playlist tracks
- Add "Download Album" button to AlbumDetailView header actions
- handleDownloadAlbum queues all non-downloaded tracks for download
2026-01-09 20:02:59 -06:00
vicrodh 97951b2189 fix: use file storage as primary for credentials (more reliable in dev) 2026-01-09 19:53:02 -06:00
vicrodh 087fbbd567 fix: verify keyring save and fallback if verification fails 2026-01-09 19:48:36 -06:00
vicrodh 1aaf360bd5 fix: add logging to credential checking for debugging 2026-01-09 19:47:24 -06:00
vicrodh 9111165ee9 fix(share): fall back to song.link direct url 2026-01-09 19:44:46 -06:00
vicrodh 20c34caed0 feat: add download management section in Settings
- Download stats display (tracks count, size used)
- Storage limit dropdown (500MB to Unlimited)
- Clear downloads button
- Open folder button (sneaky feature)
2026-01-09 19:44:02 -06:00
vicrodh 7149cf5c4b feat: add download UI for offline listening
- DownloadButton component with status indicators
- TrackRow now shows download button on hover
- downloadState store for managing download states
- Tauri event listeners for download progress
- Integration with AlbumDetailView
2026-01-09 19:42:35 -06:00
vicrodh 45fb498b8b chore: move plan doc to qbz-nix-docs 2026-01-09 19:37:22 -06:00
vicrodh 3864fa8e4b feat: add download cache for offline listening
- SQLite-based index for tracking cached tracks
- Disk-based storage for audio files (~/.cache/qbz-nix/audio/)
- Download progress events via Tauri events
- LRU eviction with configurable cache size limit
- Integration with play_track for automatic local playback
- Open cache folder command for system file manager
2026-01-09 19:18:06 -06:00
vicrodh 5bf69bc877 fix(share): fall back to song.link url lookup 2026-01-09 19:05:12 -06:00
vicrodh 1ccb78ef52 fix: multiple UI and integration fixes
1. Credential storage fallback - when keyring (KWallet) unavailable,
   falls back to obfuscated file in config directory

2. Heart icon always visible - shows outlined when not favorite,
   filled when favorite, with hover states

3. Player favorite state - checks favorite status when track plays
   and updates the heart icon in NowPlayingBar

4. Song.link ISRC lookup - uses Spotify/Deezer search URLs with ISRC
   since Qobuz isn't directly supported by Odesli
2026-01-09 19:00:12 -06:00
vicrodh 657682fc5e fix(share): use Qobuz track URL for song.link instead of ISRC
Odesli API doesn't support direct ISRC lookup. Changed to use
Qobuz track URL (https://open.qobuz.com/track/{id}) which Odesli
can properly resolve to song.link.
2026-01-09 18:50:30 -06:00
vicrodh 2efa107aa7 fix(lastfm): handle subscriber field as integer from API
Last.fm returns subscriber as 0/1 integer, not boolean.
Added custom deserializer to convert integer to bool.
2026-01-09 18:44:45 -06:00
vicrodh 9d3304879a docs: add CLAUDE.md with critical CSS warning
Document the main-content flex issue that has broken the app
multiple times to prevent future occurrences.
2026-01-09 18:40:35 -06:00
vicrodh 2c4e6cf983 fix: revert main-content CSS changes that caused content collapse
The display: flex; flex-direction: column; caused child views to
collapse to zero height. Reverted to original CSS.
2026-01-09 18:39:53 -06:00
vicrodh fae1bd7eec fix: add fallback view and improve main-content CSS
- Add fallback rendering when activeView doesn't match any condition
- Add min-height and flex layout to main-content for better visibility
2026-01-09 18:35:53 -06:00
vicrodh ad32e8ab75 feat(cast): add CastPicker UI component and wire up cast buttons
- Add CastPicker.svelte component for device discovery and selection
- Update onCast callbacks in NowPlayingBar and FullScreenNowPlaying
- Replace 'Coming Soon' toast with functional device picker modal
2026-01-09 18:28:16 -06:00
vicrodh 8b10a47a03 Enable Chromecast casting with thread-safe architecture
- Add ChromecastHandle with dedicated thread for rust_cast operations
- Fix thread safety issue (rust_cast uses Rc, not Arc) using channels
- Enable rupnp full_device_spec feature for DLNA discovery
- Fix media_server response type consistency
- Register all cast commands in lib.rs
- Add Deserialize to MediaMetadata for Tauri command args
2026-01-09 18:24:55 -06:00
vicrodh 2e0aaa4296 Fix Last.fm .env variable naming and add debug logging
- Support both LAST_FM_* and LASTFM_* naming conventions
- Match .env.example variable names (LAST_FM_API_KEY, LAST_FM_API_SHARED_SECRET)
- Add detailed logging for auth.getSession to help troubleshoot failures
- Include raw response in error messages for debugging
2026-01-09 18:12:15 -06:00
vicrodh f07fc51651 Fix favorite state detection - correct API response structure
Qobuz API returns { albums: { items: [...] }, tracks: { items: [...] } }
not { items: [...] } directly. Updated AlbumDetailView and
PlaylistDetailView to correctly access nested structure.
2026-01-09 18:10:14 -06:00
vicrodh 8f26ce7df7 Add Cast button to NowPlayingBar and FullScreenNowPlaying
- Add Cast icon from lucide-svelte
- Add onCast callback prop to both components
- Show "Casting coming soon" toast when clicked
- Backend cast module is disabled pending fixes
2026-01-09 18:01:56 -06:00
vicrodh 334f05b870 Add favorite heart indicator to tracks in track lists
- Add isFavorite prop to TrackRow component
- Show filled heart icon for favorited tracks
- Fetch favorite tracks on mount in AlbumDetailView
- Fetch favorite tracks on mount in PlaylistDetailView
- Always show heart in FavoritesView tracks (already favorited)
2026-01-09 17:59:28 -06:00
vicrodh 1fc7664cef Add quality badges (CD, HiRes, MAX) to replace dot indicators
- Create QualityBadge component with tier detection
- CD badge shows disc icon for 16-bit lossless
- HR badge for 24-bit Hi-Res audio
- MAX badge for 24-bit >96kHz Hi-Res+
- Update NowPlayingBar and FullScreenNowPlaying to use badges
- Pass bitDepth and samplingRate props through components
2026-01-09 17:56:37 -06:00
vicrodh d6ca09cda3 feat: UI improvements for menus and favorites
- Remove blue circle from fullscreen play button (match other controls)
- Add icons to TrackMenu items (Play, ListPlus, Heart, Share2, Disc3, User)
- Check album favorite status on mount in AlbumDetailView
- Improve control button styling with flexbox alignment
2026-01-09 17:52:40 -06:00
vicrodh e8c6f7372f fix: add clipboard write permission to capabilities 2026-01-09 17:43:04 -06:00
vicrodh 145186a06a feat: add casting module scaffolding (disabled)
Import Chromecast, AirPlay, and DLNA casting scaffolding from separate
branches. The module is currently disabled due to:

- Thread safety issues: rust_cast uses Rc internally (not Send)
- API compatibility: rupnp methods have changed

The scaffolding includes:
- Chromecast: mDNS discovery, device connection, media server
- AirPlay: Discovery scaffolding (RAOP playback pending)
- DLNA/UPnP: SSDP discovery scaffolding (playback pending)

To enable casting in the future:
1. Fix rust_cast thread safety (or use spawn_blocking)
2. Update rupnp API calls for current version
3. Add Deserialize derive to metadata types
4. Uncomment cast module in lib.rs
5. Wire up commands in invoke_handler
2026-01-09 17:40:26 -06:00
vicrodh e908d334c1 fix: use Tauri clipboard plugin for reliable share links
- Add tauri-plugin-clipboard-manager for reliable clipboard access
- Replace browser clipboard API with Tauri plugin
- Improve error messages in share functions to be more specific
- Add loading indicator for Song.link fetch
2026-01-09 17:35:18 -06:00
vicrodh 31549828e6 fix(track-menu): keep menus in view 2026-01-09 17:18:52 -06:00
vicrodh e9151b6c55 feat(tracks): add share and queue actions menu 2026-01-09 17:15:55 -06:00
vicrodh cf584aa1b2 fix(playlists): include tracks in playlist fetch 2026-01-09 16:44:37 -06:00
vicrodh db0113ee02 feat(search): add clear button and alt navigation 2026-01-09 16:38:57 -06:00
vicrodh b6a3f2127b feat(search): preserve results and support mouse navigation 2026-01-09 16:34:56 -06:00
vicrodh fbb0b10be3 feat: artist top tracks and play button simplification
- Remove blue circle from play/pause, now uses same style as other controls
- Add Popular Tracks section to ArtistDetailView with Play All
- Search tracks by artist name and filter results
- Connect onTrackPlay to play tracks from artist view
2026-01-09 16:23:16 -06:00
vicrodh 5d5566102c fix: sidebar reorganization and play button icon
- Move Favorites to its own section outside Playlists
- Add collapsible chevron to Playlists section
- Fix play/pause button with explicit fill and color props
2026-01-09 16:20:24 -06:00
vicrodh 15fe8ac3fe feat: connect artist view from search and favorites
- Add onArtistClick prop to SearchView and FavoritesView
- Convert artist cards to buttons with click handlers
- Wire up handleArtistClick in main page
2026-01-09 15:38:04 -06:00
vicrodh 905825177c fix: play button icon, playlist modal styling, and JSON parsing
- Fix play button by removing fill props and using CSS to style svg
- Add custom dropdown arrow and dark theme styling for select element
- Add #[serde(default)] to many model fields to handle missing data
- Add Default implementations for Artist, PlaylistOwner, ImageSet
2026-01-09 15:35:35 -06:00
vicrodh fa1ce98fc0 feat: add collapsible Local Library section in Sidebar
- Add chevron toggle to Local Library header
- Content collapses/expands on click
- Matches styling of other sidebar sections
2026-01-09 15:11:58 -06:00
vicrodh ffadf70c8b fix: track list layout and HomeView content rendering
- Add explicit flex-direction: row and width: 100% to TrackRow
- Add missing .track-list and .tracks container styles in AlbumDetailView
- Add gap: 16px to table header to match TrackRow alignment
- Add box-sizing: border-box for consistent sizing
2026-01-09 15:11:07 -06:00
vicrodh 12a53a63d1 fix: adjust main-content height for proper layout 2026-01-09 15:06:33 -06:00
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