Commit Graph
439 Commits
Author SHA1 Message Date
vicrodh c0ea039476 Add network folder detection and folder settings
- Add network folder detection module using /proc/self/mountinfo
  - Detect CIFS/SMB, NFS, SSHFS, rclone, WebDAV, GlusterFS, CephFS
  - Classify mount types (local, network, virtual, FUSE unknown)
  - Check mount accessibility

- Add library folder metadata
  - Alias for friendly naming (e.g., "NAS Music", "External Drive")
  - Network folder flag with auto-detection
  - User override for manual network folder marking
  - Network filesystem type (detected or user-defined)
  - Enabled toggle to disable folders without removing

- Add FolderSettingsModal component
  - Edit folder alias, enabled state, network settings
  - Show accessibility status for network folders
  - Scan single folder button

- Update LocalLibraryView folder list
  - Show network icon with connected/disconnected states
  - Display alias with path below if set
  - Edit button (enabled for single selection)
  - Visual badges for disabled/unavailable folders

- Add Tauri commands
  - library_get_folders_with_metadata
  - library_update_folder_settings
  - library_scan_folder (scan single folder)
  - check_network_path, check_mount_accessible
2026-01-16 04:40:06 -06:00
vicrodh f9ca1bd25e Add manual offline mode settings and disable import in offline mode
- Disable import playlists button when offline (shows disabled state)
- Add Cast, immediate scrobbling, and accumulated scrobbling toggles
- These settings only appear when manual offline mode is enabled
- Add time limit note for accumulated scrobbling (Last.fm 2 week limit)
- Persist new settings in SQLite with proper migrations
- Add i18n strings for all new settings (en/es)
2026-01-16 03:15:02 -06:00
vicrodh 6f3bcfe1cb Add offline mode track handling for playlists and queue
- Add batch check command for track local status in Rust
- Show unavailable tracks with grayed-out visual state in PlaylistDetailView
- Disable interactions for unavailable tracks (click, menu, play)
- Add WifiOff indicator for unavailable tracks
- Update QueuePanel to show unavailable track styling
- Implement auto-skip for unavailable tracks during playback
- Add offline mode sync to queue store
- Add offline-specific filter states to PlaylistManager:
  - Available Offline
  - Partially Available
  - Not Available Offline (view-only)
- Disable edit/drag for unavailable playlists in PlaylistManager
- Add i18n strings for offline states (en/es)
2026-01-16 03:01:15 -06:00
vicrodh d5f91db751 Remove NotLoggedIn check from offline detection
The login state check was causing race conditions on app startup because
offline status was being checked before auto_login completed. Since the
frontend already handles showing LoginView when not logged in, the
NotLoggedIn check in offline detection was redundant and problematic.

Now offline detection only checks:
1. Manual offline mode (from settings)
2. Network connectivity (via HTTP HEAD to qobuz.com)
2026-01-16 00:12:32 -06:00
vicrodh 373e61f0bd Fix offline mode toggle and add network verification
- Change OfflinePlaceholder icon to use offline.svg instead of Power icon
- Add flex-shrink protection to Toggle component to prevent collapsing
- Add network verification when disabling offline mode:
  - Check network connectivity before switching to online
  - Show semi-transparent overlay during check
  - Revert to offline and show toast if no internet available
- Add check_network Tauri command to verify connectivity
- Add i18n strings for noNetworkToast and checkingNetwork (en/es)
2026-01-15 23:55:45 -06:00
vicrodh a219a1dcb6 fix(offline): edge cases and code cleanup
- Fix online transition callback not triggering on manual mode disable
- Fix $derived pattern in DownloadButton (use $derived.by)
- Remove unused OptionalExtension import in offline/mod.rs
2026-01-15 23:33:24 -06:00
vicrodh e7f06fcd2f feat(offline): implement Last.fm scrobble queue for offline mode
Research findings:
- Last.fm API supports batch scrobbling (up to 50 tracks)
- Timestamps can be backdated up to 14 days

Implementation:
- Add scrobble_queue table to offline database
- Add queue_scrobble, get_queued_scrobbles, mark_scrobbles_sent commands
- Queue scrobbles when offline instead of skipping
- Flush queue automatically when transitioning to online
- Skip scrobbles older than 14 days (Last.fm limit)
- Cleanup sent scrobbles after 7 days
2026-01-15 23:24:24 -06:00
vicrodh dd5641e36b feat(offline): add pending playlist sync queue
Backend:
- Add PendingPlaylist struct for offline-created playlists
- Create pending_playlist_sync table in SQLite
- Add methods: create_pending_playlist, get_pending_playlists,
  mark_playlist_synced, delete_pending_playlist, get_pending_playlist_count
- Register Tauri commands for pending playlist management

Assets:
- Add offline.svg icon for offline mode indicator

cc
2026-01-15 22:52:02 -06:00
vicrodh 02240f41ac feat(offline): add playlist local content detection
- Add LocalContentStatus enum (unknown, no, some_local, all_local)
- Add has_local_content column to playlist_settings with migration
- Implement local track matching by Qobuz ID and by metadata (title+artist+album)
- Add commands: playlist_analyze_local_content, playlist_get_local_content_status,
  playlist_track_is_local, playlist_get_local_track_id, playlist_get_offline_available
- Add database functions for local content filtering and status updates

cc
2026-01-15 22:11:08 -06:00
vicrodh 21354f9b64 feat(offline): add offline mode detection backend
- Create offline module with OfflineReason enum and OfflineStatus struct
- Add OfflineSettings for manual mode and partial playlist preferences
- Implement network connectivity check via HEAD request to qobuz.com
- Add SQLite persistence for offline settings
- Register Tauri commands: get_offline_status, get_offline_settings,
  set_manual_offline, set_show_partial_playlists
- Add event emission for offline status changes

cc
2026-01-15 22:06:41 -06:00
vicrodh db49168623 feat(search): add carousel for artists and view more cards
- Albums: 30 results with view more card if total > 30
- Artists: 12 results with carousel navigation
- Artists carousel: same pagination logic as albums
- View more cards: 160x220px dashed border, navigate to tab
- Artists gap: reduced to 16px (same as albums)
- Separate page tracking for albums and artists

cp
2026-01-15 15:04:15 -06:00
vicrodh 8a3e8546bd fix(search): single row carousel and homogenize artist cards
- Albums carousel: display flex (one row only)
- Backend: 20 albums (was 16)
- Artist cards: all 160x220px (most popular and grid)
- Carousel buttons work with multiple pages

cp
2026-01-15 14:51:44 -06:00
vicrodh 919e72c0d2 fix(search): final adjustments for unified search view
- Artist cards: fixed spacing with 16px gap, 120x120 circular images
- Layout: Albums and Tracks now in separate full-width rows
- Carousel: Changed to single row (was 2 rows)
- Crown icon: Shimmer gradient effect (no glow/drop-shadow)
- Backend already at 16 albums

cp
2026-01-15 14:27:01 -06:00
vicrodh aa0e44d533 feat(search): add unified search view with all results tab
- Add search_all command to Rust backend (parallel search execution)
- Create SearchAllResults type for unified search results
- Add 'all' tab as new default in search view
- Implement unified results layout:
  - Most Popular section (top artist or album)
  - Artists section (up to 5 artist cards)
  - Albums carousel (horizontal scroll, 10 albums)
  - Tracks section (top 8 tracks)
- Add View all links to navigate to individual tabs
- Update search state store to include allResults
- Maintain existing tab functionality (albums, tracks, artists)
- Add responsive grid layout for unified view

cp
2026-01-15 12:38:41 -06:00
vicrodh afca54b683 fix: copy custom images to persistent storage
- Playlist artwork now copied to artwork cache directory
- Artist custom images now copied to artwork cache directory
- Prevents issues when source files are moved or deleted
- Uses MD5 hash for artist filenames to avoid special characters

cp
2026-01-15 11:55:32 -06:00
vicrodh 80ad1d45e2 fix(cache): clear artist cache on language change
Artist biographies were being cached per locale but not refreshed
when user changed language settings. Now automatically clears artist
cache when language is changed to force refetch in new language.

cp
2026-01-15 10:53:49 -06:00
vicrodh dd1df5bfee feat(library): implement persistent artist images with Discogs fallback
- Add loadCachedArtistImages() to load from database
- Add fetchMissingArtistImages() with Qobuz + Discogs fallback
- Add discogs_search_artist command for artist lookups
- Artist images now persist between sessions
- Discogs used as fallback when Qobuz has no image

cp
2026-01-15 10:06:52 -06:00
vicrodh a5200d5d05 feat(cache): add locale support for artist cache
- Modify cached_artists table to include locale in primary key
- Update get_artist and set_artist methods to consider locale
- Add get_locale() method to QobuzClient for cache key generation
- Ensure artist descriptions respect language settings

cp
2026-01-15 10:02:25 -06:00
vicrodh 42349f14dd fix(api): respect user locale for artist biography
- Add locale field to QobuzClient for API language preference
- Pass lang parameter to Qobuz artist detail endpoints
- Create set_api_locale command to update client locale
- Sync API locale with UI i18n settings automatically
- Render artist biography HTML tags properly using @html
- Fix syntax error in FavoritesView (missing comma)

cp
2026-01-15 08:57:13 -06:00
vicrodh e281932340 feat(artist): increase album and track limits
- Increase initial artist albums fetch from 500 to 1000
- Increase load more albums batch from 50 to 200
- Increase top tracks display from 5 to 20
- Prefer full biography content over summary
- Increase bio truncate threshold from 500 to 800 characters

cp
2026-01-15 08:25:03 -06:00
vicrodh bf4050a592 feat(ux): increase artist album limits and add Others section
- 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
2026-01-15 08:00:16 -06:00
vicrodh 7952bbb7d6 feat(downloads): add album download status to grid overlays (partial)
- 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
2026-01-15 00:23:58 -06:00
vicrodh 932d13829e fix(download): resolve file_path field access error in open_album_folder
CachedTrackInfo struct does not have file_path field exposed.
Use db.get_file_path() method instead to retrieve track path.

cp
2026-01-15 00:14:18 -06:00
vicrodh c30c16145e feat(downloads): add smart download menu for fully downloaded albums
- Add submenu to album download option when album is fully downloaded
- New options: Open containing folder and Re-download album
- Backend command to open album folder in file manager
- Helper function to check if album is fully downloaded
- Works in both AlbumCard overlay and AlbumDetailView menus

cp
2026-01-15 00:07:54 -06:00
vicrodh 5f725195c2 fix: unify data paths to use qbz instead of qbz-nix
Changes all application data paths from qbz-nix to qbz:
- Cache directory: ~/.cache/qbz-nix -> ~/.cache/qbz
- Config directory: ~/.config/qbz-nix -> ~/.config/qbz
- Data directory: ~/.local/share/qbz-nix -> ~/.local/share/qbz

This fixes path inconsistencies between development and production builds
and resolves asset protocol permission issues with downloaded album artwork.

cp
2026-01-14 23:49:30 -06:00
vicrodh 94e26cd593 fix(library): prevent duplicate entries for re-downloaded tracks
- Remove existing qobuz_track_id entry before inserting new one
- Ensures clean database state when re-downloading same track
- Prevents artwork and metadata confusion from duplicates

cp
2026-01-14 23:32:55 -06:00
vicrodh 6ac622d69b fix(audio): use UltraHiRes quality for downloads and playback
- Changed download quality from HiRes to UltraHiRes to support 24-bit/192kHz
- Updated playback streaming to use UltraHiRes for highest quality
- Added debug logging for artwork path storage and retrieval
- Quality fallback will still work for lower subscription tiers

cp
2026-01-14 23:32:09 -06:00
vicrodh 2d82d74b7f fix(downloads): add cover art path to local library for Qobuz downloads
Downloaded albums now properly display cover art in local library by
passing artwork_path when inserting tracks to database. Cover art is
saved as cover.jpg in album directory during post-processing.

cp
2026-01-14 23:20:36 -06:00
vicrodh 481b1d18d7 feat(downloads): add album cover art file alongside embedded artwork
Save cover.jpg in album directory for local library scanning
to properly display album art in grid/list views

cp
2026-01-14 23:12:40 -06:00
vicrodh b414301df3 feat: add automatic legacy download migration system
Migration service for users with old numeric FLAC files:
- Detect legacy downloads (123456.flac in tracks/ folder)
- Fetch complete metadata from Qobuz API
- Apply FLAC tags and embed artwork
- Organize files into Artist/Album/Track structure
- Insert to library DB with proper grouping keys
- Delete legacy files after successful migration
- Progress tracking via events

Commands:
- detect_legacy_downloads: Check if migration needed
- start_legacy_migration: Start background migration task

Events:
- migration:progress: Real-time status updates
- migration:complete: Final report with success/failure counts

Architecture:
- Non-destructive (keeps originals until success)
- Async with progress callback
- Error recovery (continues on failures)
- Proper cleanup after success

Next steps:
- Add UI banner in Settings when legacy files detected
- Show migration progress dialog
- Display results after completion

cp
2026-01-14 23:10:25 -06:00
vicrodh f1dcd96e14 fix: complete database insertion for Qobuz downloads
Critical bug fix:
- insert_qobuz_download_with_grouping() was missing required NOT NULL fields
- Added file_size_bytes, last_modified, indexed_at to INSERT
- Extract bit_depth and sample_rate from FLAC file properties
- Proper type conversion for bit_depth (u8 -> u32)

Root cause:
- INSERT statement incomplete vs schema requirements
- Silent failure in post_process_track()
- Downloaded tracks organized correctly but never inserted to library DB
- Local Library view empty despite toggle ON

Now working:
- Download completes successfully
- FLAC tags and artwork embedded
- Files organized as Artist/Album/Track.flac
- Track inserted to local_tracks with source='qobuz_download'
- Albums appear in Local Library when toggle ON

cp
2026-01-14 23:07:54 -06:00
vicrodh 0b72c3fba9 fix(downloads): add album grouping keys for proper library display
Critical fix for downloads not appearing in library:

Problem: Downloads inserted without album_group_key/album_group_title
Result: Albums not grouped/displayed in Local Library UI

Solution:
1. Create insert_qobuz_download_with_grouping() method
2. Pass all metadata: album_artist, track_number, year, etc.
3. Generate album_group_key: 'album|album_artist'
4. Set album_group_title for proper display

Now downloads will:
- Group correctly by album in Local Library
- Show proper album artist (not track artist)
- Display track numbers and year
- Appear in UI when toggle is ON

cp
2026-01-14 22:51:03 -06:00
vicrodh 01be29133a feat(downloads): smart library integration with visibility toggle
Implement intelligent library insertion:
- Downloads ALWAYS inserted to library DB (persistence)
- Visibility controlled by toggle in Settings
- Downloads NOT added to scan folders (separate from local files)

Backend changes:
1. Simplified post_process_track to always insert
2. Created get_albums_with_filter() method
3. Added source filter: exclude 'qobuz_download' when toggle off
4. Wire download_settings_state to library_get_albums command
5. Read show_in_library setting and pass to DB query

Database filtering:
- When toggle ON: show all albums (local + downloads)
- When toggle OFF: filter out source='qobuz_download'
- Hidden albums filter still works independently

Design benefits:
- Downloads folder never scanned by Local Library
- Tracks always in DB for potential future features
- Clean separation: local files vs Qobuz downloads
- Toggle only affects UI visibility, not data persistence

cp
2026-01-14 22:46:21 -06:00
vicrodh 49da0832b9 feat(downloads): add library integration to post-processing
Complete the downloads-library integration:
- Add library_db parameter to post_process_track()
- Accept show_in_library flag
- Insert processed tracks into local library automatically
- Pass library_state to download_track command
- Clone library_db for async task

Post-processing pipeline now:
1. Download → mark complete
2. Fetch metadata from Qobuz
3. Write FLAC tags with all metadata
4. Download and embed artwork
5. Organize to Artist/Album/Track.flac structure
6. Update download cache DB with new path
7. **Insert into local library if show_in_library enabled**
8. Emit processed event

Files are now:
- Properly tagged with metadata
- Organized in artist/album folders
- Available in Local Library (if toggle on)
- Ready for playback with artwork

cp
2026-01-14 22:32:46 -06:00
vicrodh e12783a50e feat(downloads): implement complete post-processing pipeline
Wire up Phase 3 functionality to download completion:
- Add post_process_track() function with full pipeline
- Fetch complete metadata from Qobuz API
- Write FLAC tags with all metadata fields
- Embed artwork from Qobuz
- Organize files into Artist/Album/Track structure
- Update database with new organized path
- Emit download:processed event for UI

Post-processing now runs automatically after download:
1. Download completes → mark_complete()
2. Fetch metadata from Qobuz API
3. Write tags to FLAC file
4. Download and embed artwork
5. Move file to: <root>/<Artist>/<Album>/NN - Title.flac
6. Update database with new path
7. Emit processed event

Files now properly organized with full metadata!

cp
2026-01-14 22:31:21 -06:00
vicrodh f69a283b31 wip(downloads): identify missing post-processing pipeline
Problem identified: Downloads complete but do not trigger:
1. Metadata enhancement from Qobuz API
2. FLAC tag writing
3. File organization (artist/album structure)
4. Library insertion

Current state:
- Files saved as {track_id}.flac in tracks/ folder
- No metadata embedded
- Not added to local library
- Phase 3 code exists but not wired to download completion

Next steps:
- Wire post-processing to download completion
- Or create manual command to process existing downloads
- Ensure proper state passing (settings, library)

cp
2026-01-14 22:28:59 -06:00
vicrodh 2cc47a80c4 feat(downloads): phase 5 complete - cleanup integration
Add library cleanup integration for download cache:
- Add remove_qobuz_download() method to LibraryDatabase
- Add remove_all_qobuz_downloads() method to LibraryDatabase
- Update remove_downloaded_track command to also remove from library
- Update clear_download_cache command to remove all from library
- Properly scope database locks to avoid deadlocks
- Log removal count when clearing all downloads

When downloads are removed from cache, they are automatically
removed from the local library to maintain consistency.

Phase 5 complete.

cp
2026-01-14 21:08:11 -06:00
vicrodh a890802d8c feat(downloads): phase 4 complete - library integration backend
Complete library integration for Qobuz downloads:
- Add conn() method to DownloadCacheDb for direct SQL access
- Implement insert_qobuz_download_direct with proper parameters
- Complete library_backfill_downloads command with Send-safe async
- Properly scope database locks to avoid Send trait issues
- Register library_backfill_downloads command in Tauri
- Add BackfillReport struct for migration tracking
- Query ready downloads directly from download_cache DB
- Insert downloads into library with source = 'qobuz_download'
- Check for existing tracks before insertion

Phase 4 backend complete. UI integration pending.

cp
2026-01-14 20:49:28 -06:00
vicrodh daa07ef9ce feat(downloads): phase 4 partial - library integration foundation
Add foundation for Qobuz downloads in local library:
- Extend get_albums to filter by source (user vs qobuz_download)
- Add include_qobuz_downloads parameter from download settings
- Create library_backfill_downloads command with report
- Add track_exists_by_qobuz_id method
- Add insert_qobuz_download method (WIP - needs file path resolution)
- BackfillReport struct for tracking migration

Phase 4 in progress - needs completion for file path handling and
UI integration. Will continue in next session.

cp
2026-01-14 20:17:44 -06:00
vicrodh b4ba435878 feat(downloads): phase 3 - metadata enhancement and FLAC tagging
Add complete metadata handling for downloaded tracks:
- Create metadata.rs module with CompleteTrackMetadata struct
- Implement fetch_complete_metadata from Qobuz API
- Add write_flac_tags using lofty crate (Vorbis comments)
- Implement embed_artwork with MIME type detection
- Add sanitize_filename for ASCII-safe names
- Create organize_download with artist/album structure
- Handle filename conflicts with counter
- Add update_file_path and update_artwork_path to DB
- Parse year from release_date_original format

Phase 3 of downloads-library integration plan.

cp
2026-01-14 20:14:07 -06:00
vicrodh 1296ee4a4b feat(downloads): phase 2 - download path management
Add path validation and file moving capabilities:
- Create path_validator module with validation logic
- Check write permissions via test file
- Detect mount status with canonicalize check
- Implement move_downloads_to_new_path with report
- Add mount status cache (30s TTL)
- Add Tauri commands: check_mount, validate_path, move_downloads
- Recursive FLAC file collection for moving

Phase 2 of downloads-library integration plan.

cp
2026-01-14 20:10:25 -06:00
vicrodh 494d3d184e feat(downloads): phase 1 - database schema and settings store
Add foundation for Qobuz downloads integration:
- Create DownloadSettings store (download_root, show_in_library)
- Add migration for local_tracks: source and qobuz_track_id columns
- Add database indices for source and qobuz_track_id
- Register Tauri commands for download settings
- Commands: get/set download_settings, validate_download_root

Phase 1 of downloads-library integration plan.

cp
2026-01-14 20:01:51 -06:00
vicrodh 3eb80c7840 feat(library): remove album limit and add album hide feature
- Remove 100 album cap from library_get_albums query
- Add album_settings table with hidden flag per album
- Add commands to hide/show albums
- Add UI toggle in settings to view hidden albums
- Add hide button to album list view
- Update LocalLibraryView to support hidden albums view

cp
2026-01-14 14:57:58 -06:00
vicrodh 2568862aa6 chore: bump version to 1.1.5 2026-01-14 08:29:42 -06:00
vicrodh 544b295fa1 fix(api): increase initial album fetch limit to 100
When loading artist details, the API now fetches 100 albums instead of 50.
This ensures each album type section (Discography, EPs & Singles, Live Albums, etc.)
has enough albums loaded initially, preventing the issue where only 2 albums
appeared in each section with the rest requiring additional loading.

cc
2026-01-14 08:17:20 -06:00
vicrodh b8e3bca6f8 feat(settings): separate toasts and system notifications toggles
- Split "Notifications" setting into "In-app Toasts" and "System Notifications"
- In-app toasts control the toast messages within the app
- System notifications control desktop notifications on track change
- Both settings persist to localStorage and load on app startup
- Migrates old 'qbz-notifications-enabled' key to new 'qbz-toasts-enabled'

feat(library): add stop scanning button

- Add library_stop_scan command in Rust backend
- Add cancel flag (AtomicBool) to LibraryState
- Check cancel flag during scan loop for both CUE and audio files
- Add "Cancelled" status to ScanStatus enum
- Add stop button in LocalLibraryView scan progress UI
- Button appears red on hover for clear visibility

cc
2026-01-14 08:05:13 -06:00
vicrodh 3a7b05b859 feat(settings): add notifications toggle
Users can now disable toast notifications (buffering, track changes, etc.)
from Settings > Appearance. Error notifications are always shown.

cc
2026-01-14 04:41:13 -06:00
vicrodh 827c033e6c chore: bump version to 1.1.3 2026-01-14 03:14:01 -06:00
vicrodh 05ef074e4f feat(ui): add HiDPI zoom controls and hotkeys 2026-01-14 02:44:27 -06:00
vicrodh 540844de9f feat(downloads): limit concurrent downloads to 3 2026-01-14 02:42:22 -06:00