Commit Graph
100 Commits
Author SHA1 Message Date
vicrodh 8565696d41 security: override cookie to 0.7.x
Fixes CVE for out of bounds characters (LOW)
All 7 dependabot alerts now resolved
2026-01-16 13:43:09 -06:00
vicrodh 3025c918f1 security: override esbuild to 0.25.x
Fixes CVE for dev server request vulnerability (MEDIUM)
svelte-i18n requires ^0.19.2, override forces ^0.25.0
2026-01-16 13:09:20 -06:00
vicrodh deeb26dc3f security: update svelte to 5.46.4
Fixes CVE for Cross-site Scripting vulnerability (MEDIUM)
2026-01-16 12:37:33 -06:00
vicrodh c81d03b5b0 security: update @sveltejs/kit to 2.49.5
Fixes:
- CVE for DoS/SSRF in prerendering (HIGH)
- CVE for memory amplification DoS (HIGH)
- Also updates devalue to 5.6.2 (2 HIGH CVEs)
2026-01-16 10:27:01 -06:00
vicrodh a68230fadc Make scrobbling options mutually exclusive in offline settings
Immediate and Accumulated scrobbling cannot be enabled at the same
time, but both can be disabled. When one is turned on, the other
is automatically turned off.
2026-01-16 10:07:05 -06:00
vicrodh 8a5d3e8971 Fix column alignment for unavailable tracks in playlist view
Show favorite and download indicators for unavailable Qobuz tracks
to maintain column alignment. The elements are already non-interactive
due to pointer-events: none on the wrapper.
2026-01-16 10:02:49 -06:00
vicrodh 3984f5b9a0 Fix track row alignment for unavailable tracks in playlist view 2026-01-16 09:56:25 -06:00
vicrodh 9499203c69 Refine offline mode UX for unavailable tracks and playlist filters
- Remove wifi-off icon from unavailable tracks in playlist detail view,
  keeping only the disabled styling for a cleaner look
- Rename "Available Offline" filter to "Fully Available Offline" to
  clarify it shows only playlists where all tracks are available
- Update filter logic to only show all_local playlists in the fully
  available filter, not partially available ones
- Fix visible filter in offline mode to respect showPartialPlaylists
  setting by using isPlaylistAvailableOffline function
2026-01-16 09:35:40 -06:00
vicrodh 93d886e1dd Fix partial playlist detection for offline mode
The hasLocalContent field was never being calculated - it was just
read from settings (always undefined). Now calculate it dynamically
from actual data:

- localTrackCounts.get(playlistId) - number of local tracks
- playlist.tracks_count - number of Qobuz tracks

Status calculation:
- 'no': localCount === 0 (not available offline)
- 'all_local': localCount > 0 && qobuzCount === 0 (fully available)
- 'some_local': localCount > 0 && qobuzCount > 0 (partially available)

This fixes Show partial playlists toggle and Partially available
filter in playlist manager.
2026-01-16 09:13:55 -06:00
vicrodh 73d022ae20 Add two-level audio cache system (L1: memory, L2: disk)
L1 (Memory): 300MB for ~3-4 Hi-Res tracks, instant access
L2 (Disk): 500MB playback cache at ~/.cache/qbz/playback/

Flow:
- When track evicted from memory, saved to disk cache
- When loading: check memory → disk → download cache → network
- Tracks promoted back to memory when accessed from disk

This reduces re-downloads when navigating back to recently played
tracks in mixed playlists.
2026-01-16 08:49:56 -06:00
vicrodh 2bdde3d592 Improve prefetch for mixed playlists
- Look ahead 15 tracks instead of 3 to find Qobuz tracks past local ones
- Prefetch up to 3 Qobuz tracks regardless of local track positions
- Count cached/fetching tracks toward limit to avoid over-prefetching

Example: [Local, Local, Qobuz, Qobuz, Local x4, Qobuz]
Before: Only prefetched tracks 3,4 (next 3 total)
After:  Prefetches tracks 3,4,9 (next 3 Qobuz)
2026-01-16 08:42:17 -06:00
vicrodh 94d7d78a22 Fix buffering UX when transitioning from local to Qobuz tracks
- Stop playback immediately when starting a Qobuz track to prevent
  previous track from continuing during download
- Show buffering toast while downloading Qobuz audio
- Skip buffering UI for local tracks since they load instantly
- Add is_local field to QueueTrack for prefetch optimization
- Update prefetch to skip local tracks (no network needed)
- Update all queue track builders to include is_local flag
2026-01-16 07:58:13 -06:00
vicrodh 3e3f89b6a8 Fix effect_update_depth_exceeded infinite loop in playlist loading
Remove reactive effect that was causing infinite re-renders due to
inline callback function recreation. Replace with imperative calls
to notifyParentOfCounts() after data loading completes.

The effect was reading onPlaylistCountUpdate which got recreated
on every parent re-render, triggering the effect again in a loop.
2026-01-16 07:48:34 -06:00
vicrodh aeb13b9ffc Connect playlist count callback for single source of truth
Wire onPlaylistCountUpdate from PlaylistDetailView to Sidebar's
updatePlaylistCounts method in +page.svelte. This ensures the
sidebar displays accurate track counts from the database instead
of calculated values that could drift out of sync.
2026-01-16 07:19:34 -06:00
vicrodh 7292635210 Fix displayTracks to handle local track positions beyond simple sum
Calculate totalCount as max of (qobuz+local count) or (highest local
position + 1) to ensure all local tracks are included regardless of
their position value
2026-01-16 07:13:09 -06:00
vicrodh 16486e4591 Fix playlist track ordering to respect insertion order
- Add PlaylistLocalTrack struct with playlist_position field
- Add playlist_get_local_tracks_with_position command
- Update PlaylistDetailView to merge tracks by position instead of
  appending local tracks at the end
- Update PlaylistModal to calculate correct position when adding local
  tracks (total count = qobuz + existing local)
- Local tracks now appear in the order they were added, interleaved
  with Qobuz tracks
2026-01-16 07:04:21 -06:00
vicrodh 24c9df3bce Fix TrackMenu z-index and edge clipping issues
- Use portal pattern to render menu in body (escapes stacking context)
- Increase z-index to 99999/100000 for menu/submenu
- Update click outside handler to work with portal
- Menu now properly appears above all track rows
2026-01-16 06:56:36 -06:00
vicrodh 9366388041 Fix local tracks not being added to queue from playlists
- Update handlePlayAll to include both Qobuz and local tracks
- Update handlePlayAllNext and handlePlayAllLater similarly
- Add onSetLocalQueue prop to mark local tracks in queue store
- Connect prop to handleSetLocalQueue in +page.svelte
2026-01-16 06:51:59 -06:00
vicrodh 825534621a Add login timeout mechanism and fix premature API calls
- Add 60-second timeout to login initialization in LoginView
- Show retry/offline options when login times out
- Move loadFavorites() to handleLoginSuccess to prevent API calls
  before authentication is complete
- Prevents errors when auto-login is slow or stuck
2026-01-16 06:49:03 -06:00
vicrodh 688d798b9d Fix local track quality badge showing Hz instead of kHz
Convert sample_rate to kHz in localTrackToDisplay function so local
tracks display correctly as 16bit/44.1kHz instead of 16bit/44100kHz
2026-01-16 06:40:23 -06:00
vicrodh 3297257a24 Fix tooltip updates and change Song to Track terminology
- Update onPlaylistUpdated callback to also refresh local track counts
- Change all Song/Songs references to Track/Tracks in Sidebar tooltips
- Ensure tooltip cache is properly invalidated when tracks are modified
2026-01-16 06:39:08 -06:00
vicrodh 5f4cfa5888 feat(playlists): include local tracks in counts everywhere
- Add playlist_get_all_local_track_counts command to get local track
  counts for all playlists efficiently
- PlaylistDetailView: show combined track count and duration in header,
  style local count with muted color, remove redundant count below
- Sidebar: load and display local track counts in tooltips
- PlaylistModal: show combined counts when selecting playlist to add to
- PlaylistManagerView: show combined counts in both grid and list views
- TrackRow: move local indicator to download column position, add
  placeholder for favorite column to maintain alignment, update tooltip
- Remove local tracks notice banner (info now in tooltip)

cc
2026-01-16 06:32:13 -06:00
vicrodh d731805eca refactor(playlists): unify track row appearance and add remove option
- Move local track indicator from quality column to favorite button position
  for consistent row alignment with Qobuz tracks
- Remove explicit delete button from playlist track rows (was easy to
  accidentally click)
- Add "Remove from playlist" option to TrackMenu for all tracks (local and
  Qobuz)
- Qobuz track removal uses playlist_track_id from API response
- Clean up unused CSS and imports from PlaylistDetailView

cc
2026-01-16 06:18:32 -06:00
vicrodh 3915abd3bb fix(playlists): add local tracks to playlists correctly
- PlaylistModal now uses playlist_add_local_track command for local tracks
  instead of the Qobuz-only add_tracks_to_playlist command
- Added isLocalTracks prop to PlaylistModal and wired it through uiStore
- Updated LocalLibraryView to pass isLocal=true when adding tracks to playlists
- Added HardDrive icon indicator next to quality badge for local tracks in TrackRow

cc
2026-01-16 06:03:09 -06:00
vicrodh 81d2bdcf33 CRITICAL: Fix library clear to preserve Qobuz downloads
- clear_all_tracks now only deletes local library tracks
- Qobuz downloads (source = 'qobuz_download') are preserved
- Local library management is now completely separate from Qobuz downloads
2026-01-16 05:15:18 -06:00
vicrodh cd1319cea9 Fix critical bug in Clear Library Database function
- Prevent double execution with clearingLibrary flag
- Stop event propagation to prevent multiple triggers
- Convert to non-async function with explicit promise chain
- Disable button during operation
- Show "Clearing..." state while in progress
2026-01-16 05:11:16 -06:00
vicrodh 6b224ce0da Polish folder settings modal
- Increase width to 720px
- Reduce folder name font size to 13px
- Fix button labels (use actions.cancel/save instead of common)
- Add 'saving' i18n key (en/es)
- Wrap long hint texts in <small> tags
2026-01-16 05:09:18 -06:00
vicrodh ae7b32d70a Increase folder settings modal width to 660px 2026-01-16 05:05:22 -06:00
vicrodh 10cd38effb Improve folder settings modal UX
- Make modal larger (560px width, more padding)
- Add specific warnings when user override differs from detection:
  - Warning when marked as network but not detected
  - Danger when marked as local but detected as network
- Detect network status when modal opens for comparison
- Add i18n strings for override warnings (en/es)
2026-01-16 05:03:45 -06:00
vicrodh 6cabded79a Add network folder detection backfill and folder path editing
- Fix offline settings database migrations to run individually
- Add network detection refresh when loading folder list
- Add network detection during folder scan
- Show folder alias with path tooltip in folder list
- Add folder path change capability in FolderSettingsModal
- Add network content visibility toggle in offline settings
- Add i18n strings for new features (en/es)
2026-01-16 05:00:24 -06:00
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 6180fea08e Filter sidebar playlists in offline mode
Add offline mode filtering to sidebar playlist list to match behavior
in PlaylistManagerView. Playlists without local content are hidden
when in offline mode, respecting the showPartialPlaylists setting.
2026-01-16 02:47:05 -06:00
vicrodh ff0440f787 Fix settings navigation click and scroll tracking
The section refs were not reactive, so the derived array captured undefined
values at definition time. Changed to resolve refs at call time using a
getSectionEl() function instead of capturing them in a derived array.
2026-01-16 02:42:43 -06:00
vicrodh 3d1af852a9 Fix settings nav sticky position gap
Remove top padding from settings-view and add it to header instead,
so the sticky nav is flush with the top when scrolling.
2026-01-16 00:32:50 -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 51ca294d8e Fix offline detection on app startup
Refresh offline status after successful login to prevent false offline
detection. Previously, the offline status was checked during bootstrap
before auto_login completed, causing 'NotLoggedIn' reason even though
the user would be logged in moments later.
2026-01-16 00:11:15 -06:00
vicrodh 36067d96d5 Fix missing closing bracket in Audio section tag 2026-01-16 00:08:27 -06:00
vicrodh 779e0ff7f3 Add sticky navigation bar to Settings page
- Add navigation bar below Account section with links to all sections
- Navigation becomes fixed at top when scrolling (sticky position)
- Active section highlighted with accent underline
- Hover state shows lighter underline for contrast
- Scroll tracking updates active section automatically
- Small text labels to fit all sections horizontally
2026-01-15 23:59:21 -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 5c1fb23899 feat(offline): UI/UX polish and accessibility improvements
Toast notifications:
- "Offline mode activated" when going offline
- "Back online" when connectivity restored

Accessibility (ARIA):
- role="status" and aria-label on offline indicator in NowPlayingBar
- role="alert" and aria-live="polite" on OfflinePlaceholder
- role="alert" on PlaylistImportModal offline warning
- aria-label on DownloadButton
- aria-hidden="true" on decorative icons
2026-01-15 23:38:20 -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 b4af6f6e9f feat(offline): add NowPlayingBar offline indicators
- Add offline indicator icon in right section when offline
- Disable lyrics button with tooltip when offline
- Skip Last.fm scrobbling when in offline mode
- Use offline-small.svg for compact indicator
2026-01-15 23:11:33 -06:00
vicrodh 4891b9bcbc feat(offline): disable external services when offline
- DownloadButton: show CloudOff icon and disable when offline
- LyricsStore: skip fetching and show "unavailable offline" message
- LocalLibraryView: skip artist image fetching from Qobuz/Discogs
- PlaylistImportModal: disable import with warning when offline
2026-01-15 23:07:16 -06:00
vicrodh 6e0d7486b0 feat(offline): add offline mode link to login screen
- Add "Start in offline mode" link below login form
- Enable offline mode without authentication
- Navigate directly to local library when starting offline
- Add i18n strings for offline start link (en/es)
2026-01-15 22:59:30 -06:00
vicrodh 6bcb1fc7a6 feat(offline): add playlist filtering and local content badges
Frontend:
- Filter playlists by local content when offline
- Respect showPartialPlaylists setting for filtering
- Add local content badges (green=all, yellow=partial) in grid/list views
- Subscribe to offline state in PlaylistManagerView
- Add pending playlist functions to offlineStore

Assets:
- Add offline-small.svg icon for compact indicators

cc
2026-01-15 22:56:32 -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 78d35785ed feat(offline): add offline mode settings section
- Add Offline Mode section to SettingsView
- Display current offline status with reason
- Toggle for manual offline mode (Enable Offline Mode)
- Toggle for showing partial playlists in offline mode
- Subscribe to offlineStore for real-time status updates
- Add status indicator styling (green=online, yellow=offline)

cc
2026-01-15 22:43:18 -06:00
vicrodh b7c1af6123 feat(offline): add view access restrictions for offline mode
- Create OfflinePlaceholder component with reason-specific messaging
- Add i18n strings for offline mode (en/es)
- Subscribe to offlineStore in +page.svelte
- Show OfflinePlaceholder for home, search, favorites views when offline
- Provide quick navigation to local library from placeholder

cc
2026-01-15 22:19:17 -06:00
vicrodh 1b9fff3746 feat(offline): add frontend offline state store
- Create offlineStore.ts with status and settings management
- Add 30-second polling for offline status checks
- Listen for backend offline-status-changed events
- Integrate with app bootstrap for initialization and cleanup
- Export getters: isOffline, getOfflineReason, getStatus, getSettings
- Export actions: setManualOffline, setShowPartialPlaylists, refreshStatus

cc
2026-01-15 22:12:59 -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 99aba9a76a feat(artist): add search navigation with prev/next buttons
- Add navigation to search results with smooth scrolling
- Show result counter (X/Y) with prev/next chevron buttons
- Support keyboard navigation (Enter, Shift+Enter, Escape)
- Add searchId prop to AlbumCard for DOM targeting
- Style search toggle button without background
- Remove focus outline from search input
2026-01-15 18:20:32 -06:00
vicrodh 98f1209e37 feat(artist): add page search and improve bio truncation
Page search:
- Add search button in sticky jump-nav bar
- Slide-in animation from right when opened
- Filter albums, EPs, live, compilations, tributes, others, playlists
- Show result count or "No results" message
- Press Escape to close

Bio improvements:
- Reduce truncation to 530 chars (was 800, now 2/3)
- Only show "Read more" if text actually needs truncation

Live detection - additional languages:
- German: Konzert, liveopname
- Japanese: ライブ (raibu)
- Korean: 라이브 (laibeu), 콘서트 (konseuteu)
- Dutch: liveopname
2026-01-15 18:06:01 -06:00
vicrodh 80579e29fa fix(artist): improve live and interview detection patterns
Live albums:
- Add "On Stage" pattern (Market Square Heroes On Stage Vol.1/2)
- Add multilingual support: en vivo, en directo (ES), ao vivo (PT),
  dal vivo (IT), en direct (FR)

Unofficial releases:
- Fix interview detection to include plural "interviews"
- Add "Remaining Memories: The Interviews" pattern
2026-01-15 17:54:58 -06:00
vicrodh 74483f2b10 feat(artist): add Tributes section and improve album categorization
Major improvements to album categorization logic:

Detection improvements:
- Broadcasts: detect plural forms, "Radio Broadcasts", "The Beast Radio"
- Live albums: detect "Alive", city+year patterns (Seattle 1989, Tokyo 1986)
- Podcasts: detect "Report Episode X", single-track 20+ min releases
- Singles: 1-4 tracks (classic 45rpm), explicit markers in title

New Tributes section:
- Albums by different artists now go to "Tributes & Covers"
- Separates tribute/cover albums from legitimate artist content
- Keeps Others clean for compilations, B-sides, unofficial releases

Categorization priority:
1. Different artist -> Tributes
2. Broadcasts/bootlegs/podcasts -> Others
3. Compilations (greatest hits, B-sides) -> Others
4. Live albums -> Live
5. Studio albums (7+ tracks, 25+ min, deluxe) -> Discography
6. EPs/Singles (1-4 tracks, <15 min) -> EPs & Singles
2026-01-15 17:25:16 -06:00
vicrodh ecf85bbd0b fix(artist): rewrite album categorization logic for accuracy
- Add artist ID comparison to filter albums from different artists
- Create separate detection for unofficial releases (broadcasts, bootlegs)
- Create separate detection for compilations (greatest hits, tributes)
- Make EP/Single detection more conservative (1-3 tracks or <15min)
- Add studio album detection to keep deluxe/remaster editions in Discography
- Prioritize categorization: different artist > unofficial > compilation > live > studio > EP
- Fix broadcasts incorrectly going to Live Albums (now go to Others)
- Fix deluxe box sets incorrectly going to Others
- Fix full-length albums with 8 tracks being classified as EPs
2026-01-15 16:59:17 -06:00
vicrodh f2c236b861 fix(artist): improve album categorization logic
- Live albums: detect broadcasts, tour dates, concert recordings
- Others: include FM broadcasts, bootlegs, compilations, tributes
- Others: detect soundtracks, various artists releases
- Filters: cover albums, demos, rehearsals, radio sessions
- Pattern matching: more comprehensive regex for edge cases

Fixes issue with Metallica FM Broadcasts and live albums not
being properly categorized.

cp
2026-01-15 16:45:51 -06:00
vicrodh 8a010800dc Merge feature/search-enhancement into main
Enhanced search view with unified results display, intelligent carousels,
and improved navigation. See branch commits for full details.

cp
2026-01-15 16:38:59 -06:00
vicrodh 0343ca2b1e fix(search): refine layout and tab navigation styling
- Most Popular: reduced to 176px width (4px less)
- Artists section: receives extra space
- Carousel buttons: cursor default when disabled (no not-allowed)
- Tab navigation: bottom border indicator (like artist view)
- Tab active state: accent color border, no background change
- Tab count badges: bg-tertiary background

cp
2026-01-15 15:54:49 -06:00
vicrodh b9310d8994 fix(search): fine-tune spacing in top section
- Reduced gap between Most Popular and Artists (18px, was 24px)
- Reduced gap between artist cards (15px, was 16px)

cp
2026-01-15 15:50:58 -06:00
vicrodh 3c44ecf742 fix(search): align most popular card to left
- Most popular wrapper: justify-content flex-start (was center)
- Card now aligns with artists carousel cards

cp
2026-01-15 15:33:58 -06:00
vicrodh 6a00cbea87 fix(search): adjust most popular container width
- Most Popular: fixed width 180px (was minmax 90px, 1fr)
- Artists: takes remaining space with 1fr
- Improves visual alignment between sections

cp
2026-01-15 15:27:28 -06:00
vicrodh f642f0532a fix(search): most popular section header alignment
- Most popular section-header: explicit flex properties
- Most popular h3: margin 0 instead of margin-bottom 0
- Ensures vertical alignment matches artists section

cp
2026-01-15 15:23:57 -06:00
vicrodh 83a55df7ef fix(search): align most popular header and improve view more styling
- Reduced most popular container width (90px min, was 140px)
- Artists section gets more space (4fr vs 3fr)
- Most popular h3: margin-bottom 0, section-header has 16px
- View more border: solid instead of dashed
- View more text: centered, bold, 14px (matches album title size)

cp
2026-01-15 15:22:21 -06:00
vicrodh 03d330e1d0 fix(search): align headers and redesign view more cards
- Most Popular: added section-header wrapper for alignment
- Most Popular card: centered with wrapper div
- View more cards: redesigned as cover art (160x160) with description
- View more text: shows remaining count (e.g. '20 more albums to discover')
- Removed background/border from card container, moved to cover button

cp
2026-01-15 15:16:24 -06:00
vicrodh 41939e295d fix(search): carousel buttons, alignment and view more injection
- Carousel buttons: transparent background, only hover has bg
- Most Popular card: centered in container
- View more cards: injected into carousel as items (not appended)
- Albums/Artists with view more merged into carousel data
- Pagination includes view more card in calculations

cp
2026-01-15 15:08:48 -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 c466a0817c fix(search): carousel pagination and artist card layout
- Carousel: bind container, use visibleAlbums slice for pagination
- Artist cards: fixed 160x220px with circular 120x120 images
- Artist names: 2-line clamp with ellipsis for long names
- Grid spacing: 24px gap between artist cards
- Prevent image deformation with min-height and flex-shrink

cp
2026-01-15 14:57:01 -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 b04cc8fb16 fix(search): improve carousel pagination and crown styling
- Crown: simple gold color (no complex animation)
- Albums carousel: dynamic page-based navigation
- Calculate albums per page based on container width
- Navigation buttons now paginate instead of scroll
- Reset to page 0 on new search results
- Remove carousel overflow/scrollbar

cp
2026-01-15 14:46:43 -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 922be5f2b5 fix(search): implement dynamic carousel with proper layout
- Add dynamic carousel column calculation based on container width
- Carousel calculates visible columns on mount and resize
- Scroll amount adjusts to show full pages (no partial cards)
- Fix padding-right to restore margin from sidebar (24px)
- Remove glow from Most Popular card
- Add shimmering animation to Crown icon (gold drop-shadow)
- Homologate all artist cards to same size (160x220px)
- Add play button overlay on track artwork (hover)
- Reduce album gap from 20px to 16px
- Fix overflow-x only on carousel wrapper (not entire page)
- Maintain 50/50 layout for albums/tracks sections

cp
2026-01-15 13:21:45 -06:00
vicrodh cd3016ed05 feat(search): add carousel navigation and improve Most Popular styling
- Add Crown icon to Most Popular header
- Homologate Most Popular card size with Artists section
- Add subtle glow effect to Most Popular card (box-shadow)
- Implement albums carousel with navigation buttons (< >)
- Carousel displays 2 rows of albums, scrollable horizontally
- Albums grid auto-adjusts columns based on viewport width
- Add carousel control buttons with hover effects
- Carousel buttons disable when at boundaries (canScrollLeft/canScrollRight)
- Remove overflow scrolling, replace with button navigation
- Align albums section height with tracks section (6 items baseline)
- Responsive carousel adjusts card size: 180px -> 160px -> 140px

cp
2026-01-15 13:01:30 -06:00
vicrodh 7b9320ac3a refactor(search): improve unified search layout and UX
- Fix Most Popular card height to match Artists section cards
- Add scrollable overflow to Artists grid for small windows
- Move Albums and Tracks to same row (50/50 split)
- Replace carousel with responsive grid for Albums section
- Grid auto-adjusts album count based on screen width
- Reduce tracks display to 6 items for better balance
- Add hover underline effect to View all links
- Improve responsive breakpoints for mobile/tablet
- Remove large artist card styles (unified sizing)
- Add custom scrollbar to Artists grid

cp
2026-01-15 12:51:08 -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 437027790e fix(ui): improve Light theme contrast for quality badges and play buttons
- Quality badge in AlbumCard: inverted colors for better visibility
- Quality badge in NowPlayingBar: added Light theme specific styles
- Play button in TrackRow: changed color for better contrast
- Fixed Recently Played section badge height to prevent border clipping

cp
2026-01-15 12:15:27 -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 9de28b8480 fix: quality badge contrast in Light theme and artist image upload parameter
- Quality badge now has dark background with white text in Light theme
- Fixed parameter name in artist image upload (customImagePath)
- Improved visibility on both AlbumCard and QualityBadge components

cp
2026-01-15 11:48:09 -06:00
vicrodh 60180c179b fix(ui): improve contrast and theme consistency
- Fix Dropdown selected option contrast in Light and Warm themes
- Improve QualityBadge border contrast in Light theme (AlbumCard and NowPlayingBar)
- Add custom artist image upload button in LocalLibrary (visible only when settings panel is open)
- Position upload button at top-right of artist card, consistent with other edit buttons

cp
2026-01-15 11:37:16 -06:00
vicrodh 031cc3e081 fix(ui): improve queue toggle, theme sensitivity
- Queue button in NowPlayingBar now acts as toggle (open/close)
- Queue sidebar uses theme-aware background instead of glassmorphic effect
- Dropdown hover and selected states now use CSS variables for theme support
- Fixes contrast issues in Light and Warm themes

cp
2026-01-15 11:25:41 -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 d0a30c7175 fix(local-library): remove non-existent AddToPlaylistModal import
- Remove broken AddToPlaylistModal component import
- Use existing PlaylistModal infrastructure from parent component
- Pass onTrackAddToPlaylist callback from +page.svelte to LocalLibraryView
- Follow existing pattern used in AlbumDetailView and other views

cp
2026-01-15 09:43:40 -06:00
vicrodh 0b439bff14 fix(ui): use existing PlaylistModal for now playing add to playlist
- Remove duplicate AddToPlaylistModal component
- Reuse PlaylistModal component that TrackRow already uses
- Consolidate playlist management UI patterns

cp
2026-01-15 09:32:42 -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 72693e184f feat: use proper quality badges in favorites view
Added maximum_bit_depth and maximum_sampling_rate fields to FavoriteAlbum interface.
Implemented getQualityLabel function to display proper quality info (e.g., 24bit/192kHz) instead of generic Hi-Res label.
Applied to both album and track views in Favorites.

cp
2026-01-15 08:50:09 -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 bba12f2832 feat(ui): improve home settings layout and add playlist modal to now playing
- Move item limits inline with section toggles in home settings modal
- Remove separate limits section for cleaner, more compact layout
- Add add-to-playlist functionality to now playing bar Plus button
- Wire up AddToPlaylistModal to current playing track

cp
2026-01-15 08:22:16 -06:00
vicrodh c6b8ab686a Merge UX improvements
- Increased artist album limit from 100 to 500
- Added Others category for compilations/greatest hits
- Added configurable Home section limits in settings
- Added grouping toggle for LocalLibrary albums and tracks

cp
2026-01-15 08:02:43 -06:00
vicrodh b7e328d8dc feat(local-library): add grouping toggle for albums and tracks
- Add albumGroupingEnabled and trackGroupingEnabled states
- Add Off option to grouping dropdown menus
- Conditionally render group headers and alpha index based on grouping state
- Match UX behavior from Favorites view

cp
2026-01-15 08:02:29 -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 dd9eb90343 fix(ui): prevent simultaneous opening of download and share menus
Ensure that opening the download menu closes the share menu and vice versa to avoid overlapping UI elements.

cc
2026-01-15 07:40:17 -06:00
vicrodh 9443708aad fix(ui): ensure album download state updates reactively in Home and Search views
Added downloadStatusTick counter to force Svelte 5 reactivity when albumDownloadStatuses Map changes.

cp
2026-01-15 07:28:20 -06:00
vicrodh a1df7095fb fix(downloads): ensure album download status is reactive in grid overlays
Add downloadStateVersion prop to AlbumCard component to make download
status reactive in all grid views. This fixes the issue where the
download menu submenu would not appear in Home, Search, and Artist
Detail views even when albums were fully downloaded.

cp
2026-01-15 01:00:55 -06:00
vicrodh f15316533f fix: album download menu not updating in grid views
- Force Map reactivity by re-assigning after .set()
- Add missing downloadStateVersion effect in SearchView
- Ensures download menu updates across all grid views

cp
2026-01-15 00:51:43 -06:00
vicrodh 6cc625c0f1 fix: reload download states in HomeView and ArtistDetailView when download state changes
cp
2026-01-15 00:45:25 -06:00