Commit Graph
2719 Commits
Author SHA1 Message Date
vicrodh f0748910c2 feat(lyrics-ui): add isolated lyrics UI components 2026-01-10 06:19:36 -06:00
vicrodh 489d73496a feat(lyrics): add backend cache and provider chain 2026-01-10 06:19:31 -06:00
vicrodh 71156e9d0a feat: replace polling with Tauri events and add unit tests
- Backend now emits playback:state events every 250ms when state changes
- PlayerStore uses listen() instead of setInterval for real-time updates
- Added Vitest testing framework with mocked Tauri APIs
- Added 53 unit tests for playerStore and queueStore
2026-01-10 06:14:59 -06:00
vicrodh 6dfcc8adaa refactor: extract app bootstrap to $lib/app/bootstrap.ts
Create bootstrap module with:
- loadSavedTheme() - theme initialization
- restoreLastfmSession() - Last.fm session restore
- setupMouseNavigation() - mouse back/forward handlers
- bootstrapApp() - combined init with cleanup

+page.svelte: 1,229 → 1,194 lines (-35 lines)
2026-01-10 05:56:33 -06:00
vicrodh 7580948e8c refactor: remove unnecessary navigation wrappers
- Remove goBack(), goForward(), handlePlaylistSelect() wrappers
- Use navGoBack, navGoForward, selectPlaylist directly from store
- Keep navigateTo() wrapper (has debug logging)

+page.svelte: 1,241 → 1,229 lines (-12 lines)
2026-01-10 05:54:36 -06:00
vicrodh 58db1bedc1 refactor: consolidate playback handlers to use playTrack service
- Simplify handleTrackPlay: 55 → 20 lines
- Simplify handleAlbumTrackPlay: 82 → 36 lines
- Simplify playQueueTrack: 58 → 18 lines

All playback handlers now use the unified playTrack() service which
handles MPRIS, notifications, Last.fm, and favorites automatically.

+page.svelte: 1,361 → 1,241 lines (-120 lines, -9%)
2026-01-10 05:53:22 -06:00
vicrodh 5be437dd4e refactor: extract Qobuz adapters and unify DisplayTrack type
- Create $lib/adapters/qobuzAdapters.ts with:
  - formatDuration/formatDurationMinutes (removed duplicates)
  - getQobuzImage helper
  - formatQuality/formatAlbumQuality helpers
  - convertQobuzAlbum converter
  - convertQobuzArtist converter

- Add unified DisplayTrack type to $lib/types/index.ts

- Update +page.svelte:
  - Import adapters instead of inline functions
  - Remove duplicate converter functions (−57 lines)
  - Add handleDisplayTrackPlay for view components

- Fix TypeScript type narrowing in view closures
2026-01-10 05:51:48 -06:00
vicrodh 30a33cfc95 refactor: extract track actions to trackActions service
Centralize common track actions that components can import directly:
- Queue operations (queueTrackNext, queueTrackLater)
- Convenience queue functions for different track types
- Favorites handling
- Playlist modal integration
- Sharing (Qobuz link, Song.link)

Removes 100+ lines of duplicate wrapper functions from +page.svelte.
Reduces +page.svelte from 1525 to 1418 lines.
2026-01-10 05:16:32 -06:00
vicrodh ea066ded97 refactor: extract playback logic to playbackService
Move core playback operations to centralized service:
- playTrack() - unified track playback with all side effects
- MPRIS metadata updates
- System notifications
- Last.fm scrobbling and now playing
- Favorite status checking and toggling

Simplifies handlers: handlePlaylistTrackPlay, handleLocalTrackPlay, toggleFavorite.
Reduces +page.svelte from 1675 to 1525 lines.
2026-01-10 05:12:04 -06:00
vicrodh d3ea80c5d4 refactor: extract shared types to $lib/types/
Move type definitions to centralized location:
- Qobuz API types (QobuzTrack, QobuzAlbum, QobuzArtist)
- UI display types (Track, AlbumDetail, ArtistDetail, PlaylistTrack)
- Local library types (LocalLibraryTrack)
- External API types (SongLinkResponse)

Reduces +page.svelte from 1806 to 1675 lines.
2026-01-10 05:07:26 -06:00
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