Commit Graph
1387 Commits
Author SHA1 Message Date
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
vicrodh 8341d2bb63 feat(favorites): add browse view for artists with Qobuz albums
Implements a two-column sidepanel view for Favorites > Artists:
- Left column shows artists grouped A-Z with sticky headers
- Right column shows selected artist's Discography albums
- Albums are filtered to show only studio albums (not EPs, Singles, Live)
- Proper AlbumCard with artwork, favorite button, and quality badge
- Footer link to navigate to full artist page for other album types
- Alpha index in toolbar for quick navigation
- Toggle button to switch between grid and browse views
- View mode persists to localStorage

Also exports categorizeAlbum from qobuzAdapters for reuse.
2026-01-30 08:40:08 -06:00
vicrodh 7b5cf5e0a6 feat(settings): add theme filter, collapsible sections, and compact account
- Add Kurosaki light theme (cream/gold color palette)
- Add theme type filter button (dark/light/all) to cycle through themes
- Make Offline Library and Storage sections collapsible with descriptions
- Compact Account section with inline layout and subscription badge
- Navigation items now use i18n translation keys for reactive labels
2026-01-30 08:40:01 -06:00
vicrodh 2e9bbf2558 fix(sidebar): move favorites popover outside aside to fix z-index
The popover appeared behind other elements when the sidebar was
collapsed because it was inside the .content div which has
overflow:hidden. Moving it outside the aside tag resolves this.
2026-01-30 08:39:54 -06:00
vicrodh 15c9b17222 fix(sidebar): add proper nav-item styles for Favorites inline layout 2026-01-30 00:32:38 -06:00
vicrodh 71d5a4c53a fix(sidebar): hybrid Favorites style like Home with expandable items
- Use nav-item style with heart icon (like Home)
- Add chevron button next to label for expand/collapse
- Show indented sub-items (Artists, Albums, Tracks) when expanded
- Collapsed sidebar shows heart icon with popover menu
2026-01-30 00:25:45 -06:00
vicrodh 5bb27b919f fix(sidebar): match Favorites section style with Playlists
- Restructure Favorites to use same layout as Playlists section
- Use section header with collapse button on the right
- Use NavigationItem components for sub-items
- Match padding, fonts, and hover states
2026-01-30 00:19:17 -06:00
vicrodh 442794fa81 fix(sidebar): button nesting and persist collapse state
- Change nested button to span with role="button" for favorites chevron
- Add localStorage persistence for collapse state of:
  - Favorites section (expanded/collapsed)
  - Playlists section (collapsed/expanded)
  - Local Library section (collapsed/expanded)
- Folder collapse state intentionally not persisted
2026-01-30 00:12:12 -06:00
vicrodh 75aab4edb5 feat(sidebar): add collapsible Favorites section
- Add chevron button to expand/collapse Favorites sub-items
- Show Artists, Tracks, Albums as nested items when expanded
- Respect user's tab order from favorites preferences
- Add popover menu for collapsed sidebar mode
- Use translations for all labels
2026-01-30 00:07:27 -06:00
vicrodh 0ef72c2499 remove debug logging for track metadata 2026-01-29 23:34:11 -06:00
vicrodh 9790e43b48 hide unimplemented playback settings, widen TrackInfoModal
- Hide Crossfade and Normalize Volume (not implemented in backend)
- TrackInfoModal: 560px -> 728px (30% wider)
2026-01-29 23:25:34 -06:00
vicrodh 822e42f484 fix(modals): use theme CSS variables instead of hardcoded colors
TrackInfoModal and AlbumCreditsModal now properly respect theme colors:
- background: var(--bg-secondary) instead of rgba(26, 26, 26, 0.95)
- border: var(--border-subtle) instead of rgba(255, 255, 255, 0.08)
- text colors: var(--text-muted) instead of #888888
2026-01-29 23:23:33 -06:00
vicrodh b412f6c448 hide gapless playback setting until properly implemented (issue #29) 2026-01-29 23:04:39 -06:00
vicrodh 10788f877f feat(tracks): add streamable field infrastructure for unavailable tracks
Adds streamable field throughout the stack to detect tracks that have
been removed from Qobuz but still appear in playlists/favorites:

Backend (Rust):
- QueueTrack: add streamable field with default true
- PersistedQueueTrack: add streamable for session persistence
- radio.rs: log warning when non-streamable track is encountered

Frontend:
- BackendQueueTrack: add streamable? field
- QobuzTrack, Track, PlaylistTrack types: add streamable
- qobuzAdapters.ts: include streamable in track conversions
- trackActions.ts: all queue builders now include streamable
- +page.svelte: debug logging includes streamable field

This prepares the infrastructure for graying out unavailable tracks
in the UI (to be implemented when we can reproduce the issue).

Refs: User report about "Failed to fetch audio" for removed tracks
2026-01-29 22:50:02 -06:00
vicrodh 7ce5b402c4 fix(player): reset player UI when queue ends
When the last track in the queue finishes playing, now properly:
- Stop playback via backend
- Clear current track (removes "now playing" indicator)
- Reset player bar state
2026-01-29 22:00:47 -06:00
vicrodh 12801eabed refactor(sort): improve sort dropdown UX with inline direction toggle
FavoritesView Albums:
- Change from combined sort modes to sortBy + sortDirection
- Click option to select, click again to toggle direction
- Show arrow indicator on selected option

PlaylistDetailView:
- Remove separate Ascending/Descending options
- Integrate direction toggle into each sortable option
- Default and Custom Order remain direction-insensitive
2026-01-29 21:52:27 -06:00
vicrodh 96b0d12bfe style(LocalLibrary): homogenize filter dropdown and artist alpha-index
- Reduce filter panel text sizes from 13px to 12px for consistency
- Update artist alpha-index to use same styling as albums/tracks tabs
- Replace boxed buttons with clean text-only alpha letters
2026-01-29 21:36:16 -06:00
vicrodh 154b39b6a8 refactor(ui): compact filter and sort buttons, two-column filter panel in LocalLibrary 2026-01-29 21:30:06 -06:00
vicrodh 16adbd4682 refactor(ui): move alpha-index inline in LocalLibrary albums and tracks tabs 2026-01-29 21:22:52 -06:00
vicrodh fcde0a90b3 refactor(ui): redesign Favorites header layout with inline alpha-index 2026-01-29 21:14:36 -06:00
vicrodh 0ca6d923a2 fix(ui): compact Favorites header, move alpha-index to horizontal position 2026-01-29 20:30:04 -06:00
vicrodh 6935aeb552 fix(ui): vertically center action buttons in Favorites 2026-01-29 20:18:07 -06:00
vicrodh c0fdfbc6a6 fix(ui): fix double scrollbar in Favorites tracks tab, replace Play All with circle buttons 2026-01-29 20:15:51 -06:00
vicrodh a401327ab3 fix(ui): remove unwanted fixed track-list-header from FavoritesView 2026-01-29 20:10:10 -06:00
vicrodh fae962d59b feat(ui): add ViewTransition to LocalLibraryView and all tabs
- Outer view slides down on initial mount (200ms, 12px)
- Each tab content (albums, artists, tracks) slides up on tab change
- Uses {#key activeTab} to re-trigger transition on tab switch
- Simple transition without spinner fadeout logic
2026-01-29 20:07:39 -06:00
vicrodh f910b222d3 fix(ui): add slide-down transition to spinner on tab change in FavoritesView
When switching tabs, the loading spinner now animates with slide-down
transition (200ms, 12px) using {#key activeTab} to re-trigger on tab change.
This completes the animation flow: spinner slides down -> fadeout -> content slides up
2026-01-29 20:02:08 -06:00
vicrodh df17f859e0 feat(ui): add ViewTransition to PlaylistDetail and PlaylistManager views
- PlaylistDetailView: outer slide-down (200ms), spinner fadeout, content slide-up
- PlaylistManagerView: outer slide-down (200ms), spinner fadeout, content slide-up
- Matches the FavoritesView transition pattern
2026-01-29 19:58:06 -06:00
vicrodh 4ce7694290 fix(ui): add initial slide-down transition to FavoritesView
Wrap entire FavoritesView in ViewTransition with direction="down" so the
initial view (header + spinner) slides down on first load.

Complete flow:
0. Initial view appears with slide-down transition (200ms, 12px)
1. Loading spinner shows while syncing
2. When sync completes, spinner fades out (200ms)
3. Content appears with slide-up transition (200ms, 12px)
2026-01-29 19:54:39 -06:00
vicrodh b5a437d0d0 feat(ui): add ViewTransition to Album and Favorites views
- Add ViewTransition wrapper to AlbumDetailView (200ms, 12px slide up)
- Add ViewTransition to FavoritesView content sections (tracks, albums, artists, playlists)
- Add spinner fadeout animation (200ms) before content transition in FavoritesView
- Both loading spinner and playlists loading spinner now fade out smoothly
2026-01-29 19:50:46 -06:00