Commit Graph
1415 Commits
Author SHA1 Message Date
vicrodh c1877cde75 Fix visual size matching for icons in SuggestionsPanel
- Adjust badge icons: QBZ 17px (was 22px), Qobuz 20px (was 18px)
  QBZ fills its viewBox completely while Qobuz has whitespace,
  so QBZ needs to be smaller to appear visually equal

- Adjust glyph icons: Playlist 32px (was 28px), Radio 26px (was 24px)
  Playlist SVG only fills ~77% of its 20x20 viewBox, needs larger
  pixel size to match Lucide Radio which fills its box completely
2026-01-31 14:55:15 -06:00
vicrodh 14f0cae1c1 feat(suggestions): major UX overhaul with popular tracks fallback
Backend:
- Add get_artist_tracks command for fetching artist's popular tracks

Frontend:
- Fallback to artist's popular tracks when tracks_appears_on is sparse
- Remove card hover movement, only image moves up on hover
- Add hover overlay with (add to queue) (play) (play next) buttons
- Use playlist.svg icon for playlist cards and glyph
- Radio glyph shown by default, replaced by action buttons on hover
- Fix icon sizes: QBZ (22px) vs Qobuz (18px) for visual balance
- Track playlist.svg asset
2026-01-31 14:48:26 -06:00
vicrodh d7c0af6297 fix(suggestions): relax deduplication to keep more variety
- Change from aggressive title normalization to exact title match only
- Keeps different versions (Remaster, Live, etc.) as valid options
- Add debug logging for sparse recommendation data
- This should fix the "only one recommendation" issue for some artists
2026-01-31 14:10:18 -06:00
vicrodh bcbd8ce27f fix(suggestions): fix CPU spike and improve card UX
- Fix $derived to $derived.by for complex logic (was causing CPU spike)
- Remove badge backgrounds from QBZ and Qobuz icons
- Move info icon (i) to top-left corner of radio card
- Add play button to radio card
- Increase badge icon sizes for visibility
2026-01-31 14:08:21 -06:00
vicrodh 1361f257f9 feat(suggestions): improve UX with deduplication, icons, and radio collage
- Dedupe recommended tracks by normalized title (filters remasters/editions)
- Use actual QBZ logo SVG instead of text "Q"
- Add playlist icon and "Playlist" label for clarity
- Add diamond-style collage layout for Song Radio card
- Pass currentArtwork for radio collage images
- Clean up unused error-text CSS in LyricsPanel
2026-01-31 13:59:05 -06:00
vicrodh 9c35c22567 fix: pass artistId to ImmersivePlayer for SuggestionsPanel
The SuggestionsPanel was showing "No track selected" because artistId
was not being passed from the page to ImmersivePlayer component.
2026-01-31 13:49:31 -06:00
vicrodh c0242356a1 fix(lyrics): show user-friendly message when lyrics unavailable
Replace technical error 'LRCLIB search request failed...' with
'No lyrics available' in both LyricsPanel and LyricsFocusPanel.
2026-01-31 12:31:02 -06:00
vicrodh 3228a6c76c fix(suggestions): use correct qobuz-logo-filled.svg path 2026-01-31 12:24:53 -06:00
vicrodh e479705803 feat(immersive): implement Suggestions panel with artist playlists and radio
Layout:
- Top section: Artist curated playlists (from Qobuz) + Song Radio card (QBZ)
- Bottom section: Recommended tracks from artist's discography

Features:
- Artist playlists fetched via get_artist_detail (includes curated playlists)
- Song Radio card with experimental badge and tooltip
- Recommended tracks shuffled from artist's tracks_appears_on
- Single API call per artist (efficient loading)
- Loading state with spinner, empty state handling
- Play buttons with hover effects

Technical:
- Uses existing create_track_radio command for radio generation
- Tracks loadedArtistId to prevent duplicate requests
- Added translations for songRadio, radioExperimental, recommendedTracks
2026-01-31 12:22:39 -06:00
vicrodh 2058fab287 fix(immersive): prevent multiple unnecessary track info requests
- Track loadedTrackId to avoid re-fetching same track
- Only request when trackId actually changes from loaded one
- Clear state only when track ends (trackId becomes null)
- Remove broken common.loading translation (spinner is enough)
2026-01-31 11:19:03 -06:00
vicrodh fe274c466d feat(immersive): replace Credits panel with Track Info panel
- Create TrackInfoPanel with full track metadata and credits
- Display: duration, quality, ISRC, label, and all performer credits
- Uses same backend as TrackInfoModal (get_track_info command)
- Rename tab from 'Credits' to 'Track Info' (player.trackInfo)
- Update keyboard shortcut from 'C' to 'T' for Track Info tab
- Fix actions.clearQueue -> player.clearQueue translation key
- Add i18n translations for trackInfo in EN/ES
- Delete old placeholder CreditsPanel
2026-01-31 11:12:25 -06:00
vicrodh 282fffc6a4 perf(immersive): improve background quality while maintaining low CPU
- Increase canvas size from 8x8 to 64x64 to reduce visible pixelation
- Add small CSS blur(40px) to smooth the result
- Key: blur(40px) on 64x64 is much cheaper than blur(120px) on full image
- Adjusted brightness slightly darker (0.55x) for better text contrast
2026-01-31 11:06:23 -06:00
vicrodh f012ba33f4 perf(immersive): fix critical CPU usage issue in background blur
Performance problem:
- WebKitWebProcess consuming 97% CPU on one core
- Cause: CSS filter: blur(120px) on large image is extremely expensive
  in WebKit/GTK which cannot GPU-accelerate this operation

Solution:
- Replace CSS blur with Canvas-based tiny thumbnail approach
- Draw image to 8x8 canvas, apply color adjustments, scale up via CSS
- Natural pixelation creates blur-like effect with ZERO CPU cost
- Remove backdrop-filter: blur() from header elements (use solid bg)

Also fixed:
- Change Mic icon to Mic2 to match rest of app
- Add missing i18n translations for player.credits and player.suggestions
2026-01-31 11:01:34 -06:00
vicrodh 4d5a78ff24 refactor(immersive): clean up controls and improve split view layout
- Remove track info (artwork, title, artist) from ImmersiveControls bottom bar
- Add track title and artist below album artwork in split view mode
- Change Lyrics Focus icon from MessageSquareText to Mic (microphone)
- Remove unused compact mode from ImmersiveControls
- Simplify props and cleanup CSS
2026-01-30 23:11:06 -06:00
vicrodh 0fc0723804 refactor(immersive): remove visualizer feature entirely
- Remove VisualizerPanel component
- Remove visualizer-focus display mode
- Remove visualizer tab from split view
- Remove enableVisualizer prop
- Remove keyboard shortcut 5 and v for visualizer
- Clean up unused imports and CSS
2026-01-30 22:32:33 -06:00
vicrodh 14ed60bb94 Revert "feat(immersive): full-screen visualizer with multiple modes"
This reverts commit d13278785d.
2026-01-30 22:29:27 -06:00
vicrodh d495c43c39 Revert "feat(visualizer): real-time audio FFT visualization"
This reverts commit 16b35c33fd.
2026-01-30 22:29:05 -06:00
vicrodh 7e17b74f99 fix(visualizer): improve responsiveness and visibility
- Increase FFT emit rate: ~21fps → ~60fps (interval 2048 → 735 samples)
- Boost scale factor: 4x → 50x for more visible response
- Gentler log mapping: powf(2.0) → powf(1.4) for better spread across bars
- Faster smoothing: attack 0.7→0.85, decay 0.15→0.5
- Faster CSS transitions: 80ms → 35ms
- Solid colors instead of gradients for better visibility
2026-01-30 22:20:11 -06:00
vicrodh 16b35c33fd feat(visualizer): real-time audio FFT visualization
Backend (Rust):
- Add rustfft crate for Fast Fourier Transform
- Create visualizer module with FFT computation (1024 samples, Hann window)
- VisualizerSource wrapper taps into audio stream without modifying playback
- Logarithmic frequency bin mapping for perceptual accuracy
- Emit audio-spectrum events to frontend (~20-30fps)
- Tauri commands: set_visualizer_enabled, get_visualizer_enabled

Frontend (Svelte):
- CSS-based rendering (GPU accelerated via transform/transition)
- Three visualization modes: bars, wave, mirror
- Dynamic colors extracted from album artwork
- Listens to audio-spectrum Tauri events
- ~0% CPU usage (GPU handles all transforms)
2026-01-30 21:51:25 -06:00
vicrodh fcc11e2966 fix(immersive): remove reflection effect from coverflow view 2026-01-30 17:31:42 -06:00
vicrodh d13278785d feat(immersive): full-screen visualizer with multiple modes
- Rewrite VisualizerPanel for full-screen display with 3 modes:
  - Bars: vertical audio bars with rounded corners
  - Wave: smooth waveform with mirrored reflection
  - Circular: radial bars emanating from center
- Extract colors from album artwork for dynamic coloring
- Add performance optimizations: 32 bars, 20fps throttling
- Pass artwork prop to enable color extraction
- Add mode switcher button to cycle through visualizations
2026-01-30 17:30:33 -06:00
vicrodh 34b172d83a fix(immersive): animate Now Playing indicator and improve Coverflow centering 2026-01-30 17:27:44 -06:00
vicrodh 8537b67d4d polish(immersive): add glass effect to header controls and keyboard shortcuts 2026-01-30 17:10:19 -06:00
vicrodh 8f16085676 polish(immersive): improve LyricsFocus animation and text glow 2026-01-30 17:08:54 -06:00
vicrodh 168b6f4354 polish(immersive): add reflection effect to Coverflow panel 2026-01-30 17:08:12 -06:00
vicrodh 4fea0dee17 polish(immersive): improve panel styling and add canvas visualizer
- Replace emoji icons with Lucide icons in placeholder panels
- Add styled "Coming Soon" badges
- Create animated canvas visualizer (reacts to isPlaying state)
- Visualizer shows frequency bars with smooth animation
2026-01-30 17:07:19 -06:00
vicrodh 9ea9d66681 fix(immersive): use symbol instead of missing i18n key 2026-01-30 17:04:01 -06:00
vicrodh b7e08cc4cb feat(immersive): add multiple display modes like Cider
Display modes:
- Coverflow: centered album art with track info
- Split: artwork + panel side by side (current default)
- Lyrics Focus: single line at a time, large centered text
- Queue Focus: full screen queue view
- Visualizer Focus: full screen visualizer

Background:
- Heavy CSS blur (120px) for abstract color blobs
- No recognizable image, just colors

Keyboard shortcuts: 1-5 to switch modes

Inspired by Cider 3's immersive player design.
2026-01-30 17:02:17 -06:00
vicrodh 484ef87ee7 feat(immersive): use full artwork background like Cider
Replace blur approach with full resolution artwork:
- Artwork scaled 115% to hide edges
- Strong vignette overlay fading to black at edges
- Gradient overlays for text readability (header, controls, lyrics)
- Slight desaturation for better contrast
- Simpler and more visually impactful
2026-01-30 16:53:14 -06:00
vicrodh eb0166b709 fix(immersive): use smaller canvas with heavy blur for abstract background 2026-01-30 16:47:26 -06:00
vicrodh 442ccae6a5 fix(immersive): increase blur canvas to 512px for smoother background 2026-01-30 16:45:50 -06:00
vicrodh 223a7f5e1d fix(immersive): improve background quality and polish UI
- Increase canvas blur size from 64x64 to 256x256 for smoother background
- Fix lyrics horizontal scroll by adding word-wrap and overflow-x: hidden
- Remove queue button from controls (use header tab instead)
- Add queue sync effect when immersive player is open

Addresses visual quality issues with pixelated background and long
German lyrics causing horizontal overflow.
2026-01-30 16:40:20 -06:00
vicrodh 07b7228538 feat(immersive): add Queue tab to stay in immersive mode
- Create QueuePanel component for immersive mode
- Add queue tab to ImmersiveHeader with ListMusic icon
- Update ImmersivePlayer to render QueuePanel and pass queue data
- Add Q keyboard shortcut to switch to queue tab
- Pass queue tracks from +page.svelte to ImmersivePlayer

Users can now manage their queue without leaving immersive mode.
2026-01-30 16:26:10 -06:00
vicrodh f744615b0e fix(immersive): fallback to CSS blur when canvas fails (CORS) 2026-01-30 16:18:17 -06:00
vicrodh 24a09a88ab feat(immersive): integrate ImmersivePlayer into main page
Replace ExpandedPlayer and FocusMode with unified ImmersivePlayer:
- Single component handles both fullscreen modes
- Tab-based UI (Lyrics, Credits, Suggestions, Visualizer)
- Auto-hide controls after 4s inactivity
- Optimized blur background (pre-computed)

Removed imports:
- ExpandedPlayer.svelte
- FocusMode.svelte

Note: Old components not deleted yet for rollback safety
2026-01-30 16:16:09 -06:00
vicrodh 7c9f1820f8 feat(immersive): create unified ImmersivePlayer component
New component architecture:
- ImmersivePlayer.svelte: Main container with tab system
- ImmersiveHeader.svelte: Tabs (lyrics/credits/suggestions/visualizer)
- ImmersiveControls.svelte: Bottom bar with all playback controls
- ImmersiveArtwork.svelte: Album art with floating/vinyl variants
- ImmersiveBackground.svelte: Optimized blur background (from Phase 1)

Panel components:
- LyricsPanel: Wrapper for existing LyricsLines
- CreditsPanel: Placeholder (Phase 3)
- SuggestionsPanel: Placeholder (Phase 4)
- VisualizerPanel: Placeholder (Phase 5)

Shared components:
- ProgressBar: Reusable seek bar with keyboard support
- VolumeSlider: Reusable volume control

Features:
- Tab-based navigation (L/C/S/V keyboard shortcuts)
- Auto-hide UI after 4 seconds of inactivity
- Full keyboard control (Space, Arrows, Escape)
- Responsive layout (desktop/tablet/mobile)
- Accessibility: ARIA roles, focus management
2026-01-30 16:11:03 -06:00
vicrodh 513614466e perf: optimize fullscreen player for low-end hardware
Lyrics optimization:
- Adaptive update interval (80-200ms based on lyrics density)
- Increased progress threshold (3% vs 1%) reduces re-renders by 60%
- Remove will-change from inactive lines (only active + next get GPU layers)
- Remove font-weight from transitions (expensive property)
- Debug logs now dev-only

Background optimization:
- Add imageBlur utility for pre-computed blur backgrounds
- 64x64 canvas blur vs CSS blur(100px) = ~95% GPU reduction
- Add color extraction for gradient fallback (even lighter)
- LRU cache for blurred images (max 20)

New components:
- ImmersiveBackground.svelte with blur/gradient/solid modes

Addresses issue #33
2026-01-30 16:11:03 -06:00
vicrodh 3926209b0d fix(auth): persist ToS acceptance in Rust/SQLite backend
ToS acceptance was stored in localStorage which gets cleared on app
updates, causing users to re-login frequently. Now stores ToS state
in SQLite (~/.local/share/qbz/legal_settings.db) which survives
updates.

- Add legal_settings.rs with SQLite storage for ToS acceptance
- Update qobuzLegalStore.ts to use Rust invoke commands
- LoginView now loads ToS from Rust before auto-login check
- Migration from localStorage for existing users

Closes #31
2026-01-30 14:49:39 -06:00
vicrodh fe7816f6c6 feat(audio): add S/PDIF (iec958:) devices to bit-perfect category
Digital outputs like S/PDIF transmit audio as-is without DA/AD conversion,
making them bit-perfect by nature. Now iec958: devices get the BP badge.

Updated group label to "Bit-perfect (Hardware / Digital)" to reflect
both direct hardware access (hw:) and digital outputs (iec958:).
2026-01-30 11:55:31 -06:00
vicrodh 5b03af41bc feat(audio): add alsa-utils help modal with distro-specific install commands
- Add check_alsa_utils_installed and get_linux_distro Tauri commands
- Detect Linux distribution from /etc/os-release
- Show appropriate package manager command for each distro
- Add (?) help icon next to ALSA Direct device dropdown in Settings
- Modal explains why alsa-utils is needed for bit-perfect detection
- Updated PKGBUILDs to list alsa-utils as optdepend
2026-01-30 11:43:34 -06:00
vicrodh 2838b25738 Replace 'Downloading' with 'Caching' in logs 2026-01-30 11:37:55 -06:00
vicrodh f67b13e27e Add grouped device dropdown for PipeWire with USB/HDMI categorization
Backend changes:
- Add device_bus and is_hardware fields to AudioDevice
- Parse PipeWire Flags (HARDWARE) and device.bus property from pactl output

Frontend changes:
- DeviceDropdown now supports both ALSA and PipeWire backends
- ALSA grouping: Defaults, Bit-perfect, Plugin Hardware, Other
- PipeWire grouping: Defaults, USB Audio (BP capable), HDMI/DisplayPort, Other HW, Virtual
- BP badge shown for USB Audio devices in PipeWire mode
2026-01-30 11:18:09 -06:00
vicrodh 0ccdd9981f Add supported sample rates detection and display for ALSA devices
Backend changes:
- Add supported_sample_rates field to AudioDevice struct
- Detect common audio sample rates (44.1, 48, 88.2, 96, 176.4, 192, 352.8, 384 kHz)
- Use CPAL's supported_output_configs() to check rate support for hw: devices

Frontend changes:
- Display sample rates as subtitle in DeviceDropdown (e.g., "44.1, 48, 96, 192 kHz")
- Only shown for bit-perfect devices where detection is available
- Search not sensitive to sample rates field (per user request)
2026-01-30 11:11:05 -06:00
vicrodh 91fa7c7f5f Add grouped device dropdown for ALSA Direct audio output selection
- New DeviceDropdown component with grouped options:
  - Defaults (System Default, default ALSA)
  - Bit-perfect (Auto-detected) - hw:X,Y devices with BP badge
  - Plugin Hardware - plughw:X,Y devices
  - Other Outputs - remaining devices
- Only shows for ALSA Direct backend, other backends use regular dropdown
- Pure UI change, no backend modifications
2026-01-30 11:01:16 -06:00
vicrodh df8bdb7ac0 Add ticker animation for artist names and sorting to album sections in Favorites browse view
- Artist names in sidepanel now animate with ticker effect on hover when text overflows
- Each album section (Discography, EPs & Singles, Live Albums) now has a sort dropdown
- Sort options: Default, Newest, Oldest, A-Z, Z-A
- Use sorted arrays for rendering instead of raw grouped arrays
2026-01-30 10:17:06 -06:00
vicrodh 8840da39a5 feat(favorites): show Discography, EPs & Singles, and Live Albums in browse view
- Group albums by category: Discography, EPs & Singles, Live Albums
- Exclude tributes and compilations (others) from display
- Each section has its own header that scrolls with content
- Updated footer: "To view compilations and other content, go to..."
- All content scrolls together (sections + footer)
2026-01-30 09:53:31 -06:00
vicrodh bf836a6bfb fix(favorites): remove redundant artist count from sidepanel column 2026-01-30 09:10:21 -06:00
vicrodh efe0f7143b fix(favorites): full height layout and remove horizontal scrollbar
- Add no-outer-scroll class when sidepanel mode is active
- Set up proper flex container hierarchy for full height:
  - .favorites-view becomes flex column container
  - .content gets flex: 1 with min-height: 0
  - ViewTransition wrapper gets flex: 1 via :global selector
- Fix negative margins to match parent padding (was -32px, now -8px/-18px)
- Reduce artist column width to 240px (matches LocalLibrary)
- Fix album column right padding to 8px
2026-01-30 09:07:52 -06:00
vicrodh 93baa9f47c fix(favorites): artist column height and scroll container structure
- Add artist count header like LocalLibrary
- Remove sticky positioning from group headers (caused overlap)
- Restructure albums area with scroll wrapper containing both grid and footer
- Footer now scrolls with album grid (visible at bottom after scrolling)
- Match LocalLibrary CSS patterns for proper independent scrolling
2026-01-30 08:55:13 -06:00
vicrodh b7c4684f03 fix(favorites): independent scrolling and button style in browse view
- Fix toggle button to use control-btn icon-only style (matches Library)
- Add proper background/hover states to the toggle button
- Fix two-column layout for independent scrolling:
  - Artist list scrolls independently from albums grid
  - Added scroll optimization properties (overscroll-behavior, contain)
  - Adjusted padding and margins for edge-to-edge layout
- Increased album card grid size to 180px (matches LocalLibrary)
2026-01-30 08:45:34 -06:00