Commit Graph
1805 Commits
Author SHA1 Message Date
vicrodh 017a081f7f feat(immersive): auto-degrade background on sustained low FPS
Add performance watchdog to ImmersiveRenderer that monitors FPS after
a 3-second warmup period. If FPS stays below 15 for 5 consecutive
seconds, automatically degrades background mode (Full -> Lite -> Off),
persists the setting, and shows a toast notification.

ImmersiveBackground listens for the degradation event and switches
renderer in-place without requiring a full remount.
2026-03-08 21:49:35 -06:00
vicrodh 776987856a fix: tray icon path for Flatpak and titlebar double-click maximize
- Fix Flatpak tray icon path (com.blitzfc.qbz, not com.blitzkriegfc.qbz)
- Fix titlebar double-click: prevent JS handler from firing on native
  drag regions, which caused double toggleMaximize (maximize then
  immediate restore)
- Improve tray click handlers to properly detect minimized state
2026-03-08 21:43:30 -06:00
vicrodh 572d23b935 feat: replace ListenBrainz co-listening with MusicBrainz tag-based discovery
ListenBrainz similar-artists returned mainstream crossover artists (SOAD,
Led Zeppelin for Metallica) instead of genre-accurate results. Now uses
MusicBrainz tag search to find artists sharing the seed's primary genre tag
(e.g. "thrash metal" returns Megadeth, Slayer, Kreator, etc).

- Add search_artists_by_tag to MusicBrainz client
- Deterministic shuffle using seed MBID hash for variety across artists
- Secondary tag fallback when primary yields fewer than 5 results
- Rename label to "You May Also Like", limit results to 6
- Add Last.fm get_similar_artists method (unused, for future use)
- Add tags field to ArtistFullResponse model
- Tighten local history exclusion to play_count > 2
2026-03-08 21:30:01 -06:00
vicrodh a029f30fa5 feat: show similarity percentage in discovery artists sidebar
Display similarity score next to each discovery artist name. Update
DiscoveryArtist interface with similarityPercent field. Add i18n keys
for youMayAlsoLike section and sidebar layout improvements.
2026-03-08 15:47:33 -06:00
vicrodh a2eabf08f1 fix: freeze equalizer animation when player is paused
Separate isActiveTrack (current track) from isPlaying (actively playing)
so the equalizer bars freeze via animation-play-state when paused instead
of always animating. Show Play icon on hover when paused, Pause when playing.
Also fix AlbumDetailView which was missing the isPlaybackActive check.
2026-03-08 13:24:12 -06:00
vicrodh 8c626c0e6a fix: poll output device name so it updates during playback
The device name was only read on mount and on hover, so it stayed
as "No device" until the user hovered the badges area. Now the
1-second poll also reads get_audio_output_status (cheap in-memory
read) alongside hardware status, keeping the device name current.
2026-03-08 13:10:53 -06:00
vicrodh bdc24c5a2e fix: show configured device name when player has no active stream
Fall back to settings.output_device when the player hasn't reported
a device yet (before first playback). Previously showed "No device"
even though a device was configured in audio settings. Also change
the final fallback from "No device" to "System Default" since no
configured device means the system default is being used.
2026-03-08 13:04:51 -06:00
vicrodh f95620ba12 fix: apply home settings changes immediately without reload
Add loadHome({ showSkeletons: false }) to the settings subscription
callback so visibility toggles, reordering, and limit changes are
reflected in real-time instead of requiring a page reload.
2026-03-08 12:28:38 -06:00
vicrodh 070589427b feat: apply image cache to all artist image components
Use cachedSrc action for artist images in SearchView, HomeView,
ArtistDetailView, VirtualizedFavoritesArtistGrid, and
VirtualizedFavoritesArtistList. Use size-aware image selection
(small instead of large) for grid/card contexts. Add opacity
transition for smooth placeholder-to-image loading.
2026-03-08 12:20:26 -06:00
vicrodh 8379227a0e fix: hide image during cache resolution to show placeholder
Image is hidden (opacity 0) until the cached URL resolves, preventing
broken image icons. The disc placeholder shows through while loading.
Adds a subtle 150ms fade-in transition when the image appears.
2026-03-08 10:57:23 -06:00
vicrodh 6b87554dbb feat: frontend image cache with size-aware loading and settings UI
- getQobuzImageForSize(): picks small (230px) for grids, large for hero
- cachedSrc Svelte action: resolves images through backend disk cache
- imageCacheService: in-memory URL map with dedup for pending requests
- AlbumCard uses cachedSrc action for artwork rendering
- Settings UI: Toggle for cache on/off, numeric input for max size (MB),
  stats display, clear button — uses existing Toggle and input styles
- Removed unused Artwork Thumbnails section (never showed data)
- i18n: added image cache keys to all 4 locales (en/es/de/fr)
2026-03-08 10:52:35 -06:00
vicrodh 7cec1101d1 fix: make currentNavItemId reactive with $state()
Without $state(), Svelte 5 doesn't track changes to currentNavItemId,
so the scroll reset $effect never re-fires on same-view item changes.
2026-03-08 10:17:45 -06:00
vicrodh 3c783973b1 fix: reset scroll to top on forward navigation between same-view items
When navigating from album(1) to album(2), the view type stays 'album'
so the scroll reset effect didn't trigger. Now tracks currentNavItemId
changes too, and explicitly scrolls to top for forward navigation while
preserving scroll restore on back/forward.
2026-03-08 10:12:02 -06:00
vicrodh 150d80dfac feat: granular navigation history with per-item scroll position
Navigation history now tracks itemId per entry (album, artist, playlist,
label, musician, purchase-album) so back/forward restores the exact page.
Scroll positions are saved per view+itemId key and restored on back/forward.
2026-03-08 10:05:45 -06:00
vicrodh c4b25b2b94 fix: remove unused .experimental-inline CSS selector 2026-03-08 09:49:08 -06:00
vicrodh df37b2c15d fix: only re-categorize download group items, not other/compilation (#149)
The "other" group contains podcast episodes with release_type "album"
that should stay in Others, not be moved to Albums. Only "download"
group items should be re-categorized since download is a distribution
channel, not a content classification.
2026-03-07 23:07:10 -06:00
vicrodh 6bcfaa8f90 fix: label releases search bar grows from right, fixed nav height, homologate back button 2026-03-07 23:03:42 -06:00
vicrodh 5ae5543cda fix: remove position recall from session restore, always start from beginning
Position restore was unreliable (always showed 0:01). Session restore
now loads the track ready to play from start without seeking.
2026-03-07 23:03:28 -06:00
vicrodh 6baae44327 fix: map epSingle type and re-categorize items from download/other groups (#149)
The Qobuz artist/page API returns release groups with type "epSingle"
(not "ep" or "single"), and groups like "download" and "other" contain
mixed items (singles, albums) that should be re-categorized by each
item's individual release_type field.
2026-03-07 23:03:20 -06:00
vicrodh 765287817b fix: backfill EPs & Singles when artist/page omits them (#149)
The Qobuz artist/page endpoint sometimes excludes the EP/single
release group from its response. When this happens, fetch them
explicitly via get_releases_grid as a non-blocking backfill.
2026-03-07 22:20:49 -06:00
vicrodh cffbce9faa fix: faster session restore and remember playback position
Move session restore to run immediately after playback preferences
load, before network-heavy initializations (favorites, offline
status, recommendation scores). This eliminates the multi-second
"No track playing" gap on slow storage.

Also restore the saved playback position visually and on first play
(seek to saved position, no auto-play).
2026-03-07 22:01:18 -06:00
vicrodh 9c841365f8 Revert "feat(theme): add System (Dark / Light) theme and rename System to Match Colors"
This reverts commit 82e358208a.
2026-03-06 12:46:32 -06:00
vicrodh 82e358208a feat(theme): add System (Dark / Light) theme and rename System to Match Colors
Add a new "System (Dark / Light)" theme option that toggles between
Dark and Light themes based on OS prefers-color-scheme, with a live
matchMedia listener for instant switching. Rename old "System" (auto
palette generation) to "Match Colors" for clarity.

Applies to main window, miniplayer, and bootstrap.

Closes #148
2026-03-06 11:27:14 -06:00
vicrodh 786ce883ac fix(library): extract track/disc number from file tags during backfill import
insert_qobuz_cached_track_direct was hardcoding track_number to 0,
causing all imported tracks to show wrong numbers. Now accepts
track_number and disc_number params, and both callers (backfill
downloads and offline cache sync) extract metadata from the audio
file via MetadataExtractor before inserting.

Also fix LocalLibraryView to use || instead of ?? for track_number
fallback, so 0 correctly falls back to index-based numbering.

Closes #147
2026-03-06 11:08:32 -06:00
vicrodh 36d5ff65b7 fix(search): add right-click context menu to search result tracks
Wire up oncontextmenu handlers to track rows in SearchView so
TrackMenu opens on right-click, matching behavior of other views.
2026-03-06 09:02:15 -06:00
vicrodh 5b9f5a75c2 feat(ui): add explicit content badge across entire app
Display parental_warning badge (E icon) next to track titles in all
views: TrackRow, QueuePanel, NowPlayingBar, ImmersivePlayer with all
13 visualizer panels, MiniPlayer surfaces, and AlbumDetailView.

Propagate parental_warning field through the full data chain from
Rust backend (qbz-models, queue, commands_v2, session_store, API
server) to frontend stores, adapters, and UI components. Badge uses
CSS mask technique with explicit.svg for theme compatibility.
2026-03-06 08:48:51 -06:00
vicrodh 6685566091 feat(label): add group-by-artist toggle and performance improvements
Add artist grouping option for Label Releases view and remove
expensive loadAllAlbums() call. Use v2_get_label_page for richer
label image data. Add groupByArtist i18n keys to all 4 locales.
2026-03-06 08:48:36 -06:00
vicrodh 4e6a52e453 feat(label): redesign Label Releases view with logo, sorting, and filters
- Replace generic icon with circular label logo (matches LabelView)
- Fix double close button in search: single X that clears and closes
- Add sort options: newest, oldest, title A-Z/Z-A, artist A-Z
- Add Hi-Res filter toggle
- Load all albums automatically when sorting/filtering
- i18n: add labelReleases keys to all 4 locales
- Search bar now replaces title area instead of floating separately

API analysis: Qobuz label endpoints have no server-side sort/filter
params, so all sorting and filtering is done client-side after
paginated fetch.
2026-03-05 14:33:42 -06:00
vicrodh 97f42f4fea fix(settings): remove gapless restrictions for DAC Passthrough and ALSA Direct
Gapless now works on all backends, so the UI constraints that disabled
it for DAC Passthrough and ALSA Direct are removed. Only streaming-only
mode still disables gapless (no cache available). Removed experimental
badge. Cleaned up unused i18n keys.
2026-03-05 12:20:15 -06:00
vicrodh ec6c4c56ac fix(lastfm): use user-scoped storage for session restore on startup
bootstrap.ts used raw localStorage.getItem() while settings saved with
user-scoped setUserItem(), causing session key mismatch. Closes #143
2026-03-05 11:14:42 -06:00
vicrodh fa747ecf8b feat(library): add qobuz_purchase source badge with gold Qobuz icon
Distinguishes purchased downloads from offline cache and regular
library items with a gold-tinted Qobuz logo badge on album cards.
2026-03-05 11:13:52 -06:00
vicrodh 43df8a40e4 fix(purchases): restructure download paths to Artist/Album [FORMAT][Quality]/track
Embeds quality in album folder name instead of subfolder, so each
quality variant appears as a separate album in the local library.
Adds download error toast and fixes format labels to bracket notation.
Closes #116
2026-03-05 11:12:39 -06:00
vicrodh 3c50c1c14e feat(immersive): replace Tunnel visualizer icon with cube SVG 2026-03-05 11:12:04 -06:00
vicrodh 955f5edd05 fix(svelte): resolve all remaining a11y and real warnings
Key discovery: Svelte 5 requires commas between svelte-ignore codes,
not spaces. Fixed separator in all multi-code ignore comments.

Additional fixes across 36 files:
- TrackMenu/AlbumMenu: add role="menu" and ignore comments to menus
- LocalLibraryTagEditorModal: link labels to inputs with for/id
- TrackReplacementModal/DACSetupWizard: fix dialog a11y
- BookletViewer: fix reactivity ($state for bookletLoaded)
- StackIcon/SearchPlaylistCard/QobuzPlaylistCard/FavoritePlaylistCard:
  fix state_referenced_locally with $derived()
- CoverflowPanel/HomeSettingsModal/FavoritesEditModal: fix reactivity
- ImmersiveHeader/FolderEditModal: replace deprecated svelte:component
- Toggle: add aria-label prop
- Various modals: add tabindex="-1" and role to dialogs
- Dropdown/DeviceDropdown: add proper listbox roles

Build output: 0 Svelte warnings (down from ~200)
2026-03-04 20:20:40 -06:00
vicrodh d50b2cf03a fix(svelte): resolve warnings in 26 components
Phase 1 (real warnings):
- SearchView: add $state() to searchInput and scrollContainer
- DiscoverBrowseView: use $derived() for genreContext
- FavoritesView: replace deprecated svelte:component
- CastPicker: replace deprecated svelte:component (2 instances)
- NowPlayingBar: remove unused .section-separator CSS
- SettingsView: remove unused nested .experimental-badge CSS
- PlaylistDetailView: remove unused .playlist-api-image CSS
- PurchaseAlbumDetailView: remove unused .download-done CSS
- DiscoverPlaylistsBrowseView: fix nested buttons (outer to div)
- AlbumCreditsModal: fix nested button (inner to div)

Phase 2 (a11y warnings):
- Add tabindex="-1" to dialog/menu elements (7 files)
- Add svelte-ignore for autofocus (3 files)
- Add onkeydown handlers to role="button" elements (5 files)
- Add role/svelte-ignore to onclick divs (6 files)
- Add role="menu" to dropdown menus (4 files)
- Add svelte-ignore for drag handlers (3 files)
- Fix label a11y: add aria-label, convert decorative labels to spans
2026-03-04 19:55:32 -06:00
vicrodh 18b7bcaf31 ui: increase custom titlebar height by 4px (36 -> 40)
Search input in titlebar also grows 4px (24 -> 28) for better
readability. Layout calculations updated in page, sidebar, and store.
2026-03-04 09:02:06 -06:00
vicrodh b15a375e23 feat(immersive): add 3-mode background system (Full/Lite/Off)
Replace binary blur toggle with a 3-option dropdown. Full mode uses
the existing WebGL2 shader, Lite mode renders a pre-blurred static
image animated with CSS transforms (compositor-driven, immune to
Wayland frame callback stutter), and Off mode shows a solid color.

Includes config migration from disableBlurBackground to backgroundMode,
updated composition profiles, and i18n for all 4 locales.

Closes #127
2026-03-02 13:18:55 -06:00
vicrodh 00675de6b8 feat(snap): add snap sandbox detection and welcome modal wiring
Detect when QBZ runs inside a Snap sandbox (via SNAP env var) and show
a one-time welcome modal with required plug connection commands. Adds a
Snap Sandbox section in Settings with copyable commands, mirroring the
existing Flatpak pattern.

Backend: snap.rs module, DB table snap_welcome_shown, V2 commands.
Frontend: updatesService, +page.svelte modal queue, SettingsView section.
2026-03-02 11:10:50 -06:00
vicrodh 8529477778 feat(immersive): polish tunnel depth and artwork-driven line palette
cx
2026-03-02 01:06:55 -06:00
vicrodh 5930f599d6 feat(immersive): refine tunnel curve occlusion behavior
cx
2026-03-02 00:55:38 -06:00
vicrodh 5492e8115e feat(immersive): refine neon and tunnel panel visuals
cx
2026-03-02 00:50:45 -06:00
vicrodh 47f80149d5 feat(playlists): add custom artwork and folder sidebar visibility controls
cx
2026-03-01 22:09:43 -06:00
vicrodh 55a1ef25e6 fix(ui): polish mini/immersive layout and queue favorite behavior
cx
2026-03-01 18:56:23 -06:00
vicrodh d72eac3c1e fix: search album/artist grid collapses to single column on keystroke
When typing in the search bar, new results cause the virtual scroll
container to remount. The ResizeObserver was stale (watching the old
destroyed element) and containerWidth reset to 0, causing gridCols
to default to 1. Two fixes: cache the last known column count so
width=0 uses the previous layout, and reconnect the ResizeObserver
whenever the container element changes.
2026-03-01 16:38:38 -06:00
vicrodh 63521e920b fix: Escape on empty search input blurs focus
First Escape clears the search text, second Escape when input is
already empty removes focus from the input. Applied to both the
sidebar and titlebar search inputs for keyboard-driven navigation.
2026-03-01 16:33:33 -06:00
vicrodh eabeb3959f fix: move multi-select button to header in WeeklySuggestView
The CheckSquare button was next to the search bar instead of in the
header actions alongside Play/Shuffle/Save, inconsistent with DailyQ,
FavQ and TopQ views. Moved it to the header and removed orphaned CSS.
2026-03-01 16:22:26 -06:00
vicrodh 7753d2520e fix: multi-select add to playlist sends all tracks in one call
The broken views called onTrackAddToPlaylist in a loop (once per
selected track), causing each call to overwrite the previous track
IDs in the playlist modal. Only the last track survived. Now all 6
views collect IDs first and call onBulkAddToPlaylist once with the
full array.

Views fixed: ArtistDetailView, AlbumDetailView, LabelView,
FavoritesView, WeeklySuggestView, PlaylistDetailView.
2026-03-01 16:19:12 -06:00
vicrodh f9e9d58e81 fix: add-to-library uses album folder instead of root destination
When downloading a purchased album to ~/Music, the "Add to Local
Library" button was adding ~/Music (the entire music directory) instead
of the specific album folder like ~/Music/Artist/Album/.

After the first track downloads, extract the album-level folder from
the returned file path and update the stored destination. This ensures
only the downloaded album gets added to the library. Fixes #117.
2026-03-01 15:47:01 -06:00
vicrodh c2f2888312 feat: add cancel button for purchase album downloads
Allow users to cancel an in-progress album download. The current track
finishes but no further tracks are started. A cancel button appears in
the progress bar during download, and a cancelled state shows how many
tracks completed. Closes #133.
2026-03-01 14:14:47 -06:00
vicrodh 8fef723ced fix: eliminate dead space in Customize Shortcuts modal
Switch from CSS grid to CSS multi-column layout so categories pack
tightly top-to-bottom instead of creating large empty rows when
columns have uneven heights.
2026-03-01 14:09:17 -06:00