Commit Graph
2240 Commits
Author SHA1 Message Date
vicrodh cfa66ef316 fix(share): restore Song.link sharing via Deezer ISRC resolution
Odesli no longer accepts ISRC as a direct query param or Spotify search
URLs. Replace with a two-step approach: resolve ISRC to a real Deezer
track URL via Deezer's free API, then pass that URL to Odesli.

Also fix error display in frontend — RuntimeError objects were shown as
[object Object] instead of extracting the details message.
2026-02-19 18:22:25 -06:00
vicrodh cbc2ff0b26 feat(audio): add PipeWire force bit-perfect mode
Add experimental toggle to force PipeWire clock.force-quantum alongside
clock.force-rate for true bit-perfect playback. Quantum is matched to
sample rate (1024 for <=48kHz, 2048 for <=96kHz, etc). Both values
reset to 0 on stop and pause-suspend to avoid affecting other apps.

Requires DAC Passthrough to be enabled, PipeWire backend only.
2026-02-19 18:01:42 -06:00
vicrodh 98ffd3dff2 chore: bump version to 1.1.15-rc-2 2026-02-19 16:57:19 -06:00
vicrodh 6f612e699f feat(purchases): add playback support to purchases views
Purchased tracks are streamable via normal Qobuz API. Reuse existing
handleDisplayTrackPlay/playAlbumById infrastructure to enable click-to-play
on track rows and a Play button on album detail header. Active track
highlights with accent color and animated playing bars.
2026-02-19 16:57:16 -06:00
vicrodh 9bd8aec91b fix(purchases): add lenient deserialization for non-vital fields
If the Qobuz API returns an unexpected type for optional fields like
purchased_at, label, genre, quality metadata, etc., the field silently
defaults to None instead of crashing the entire purchases fetch.

cc
2026-02-19 16:36:07 -06:00
vicrodh 45ca758f47 fix(purchases): deserialize purchased_at as i64 unix timestamp
The Qobuz API returns purchased_at as a Unix timestamp integer, not a
string. Updated Rust structs, TypeScript types, and frontend date
formatting to handle numeric timestamps correctly.

Fixes #88

cc
2026-02-19 16:29:13 -06:00
vicrodh 183a0ec50d chore(types): add track_number and description to interfaces
Add optional track_number to QobuzTrack and description to QobuzAlbum.

cc
2026-02-19 16:19:02 -06:00
vicrodh 45116707bf fix(player): add null guard for seek target position
TypeScript narrowing for seekTargetPosition after the initial null
check to prevent potential runtime error.

cc
2026-02-19 16:19:01 -06:00
vicrodh e245b702bd fix(ui): improve error message formatting in LoginView
Extract structured error messages from objects instead of raw
String(err) which shows [object Object].

cc
2026-02-19 16:19:00 -06:00
vicrodh e375826fa3 fix(ui): ADR-001 compliance in SpectralRibbon, remove unused AlsaUtilsHelpModal
Rename t variable to interpWeight in SpectralRibbon to avoid shadowing
the i18n store. Delete unused AlsaUtilsHelpModal component.

cc
2026-02-19 16:18:58 -06:00
vicrodh 2508ea9e55 chore(dev): improve dev scripts and runtime cleanup
Add svelte-kit sync + --force to dev script, add clean-runtime script,
bind vite to 127.0.0.1 explicitly.

cc
2026-02-19 16:18:53 -06:00
vicrodh 33aa848dcf fix(flatpak): improve metainfo for Flathub compliance
Shorten summary, add branding colors, add xml:lang to screenshot
captions, remove redundant Features heading.

cc
2026-02-19 16:18:52 -06:00
vicrodh c380434619 fix(ci): skip RC tags in AUR workflow
Only trigger AUR package update on stable version tags, not release
candidates.

cc
2026-02-19 16:18:47 -06:00
vicrodh 3d497a33b0 fix(desktop): add %u to Exec and complete tarball .desktop for URI handling
The Tauri .desktop template was missing %u in the Exec line, preventing
the desktop environment from passing qobuzapp:// URIs as arguments when
launched from the browser. The tarball .desktop was also missing MimeType,
StartupWMClass, and StartupNotify fields.

Closes #44

cc
2026-02-19 16:17:25 -06:00
vicrodh 13d9ec3724 refactor(ui): convert queue panel from overlay to inline sidebar
Queue now pushes main content instead of overlaying it, fixing the
search header z-index conflict. Lyrics sidebar height fixed to 100%
to fill parent container correctly. Queue and lyrics are now mutually
exclusive - opening one closes the other.
2026-02-19 08:55:09 -06:00
vicrodh 5b76530a4d docs: add glibc 2.38+ requirement for DEB/RPM packages
Ubuntu 24.04 build target (required for Snap Store) means native
packages need glibc 2.38+. Older distros should use Flatpak, Snap,
or AppImage instead.
2026-02-18 16:52:30 -06:00
vicrodh a6cfa36a8d fix(packaging): compile binary as qbz instead of qbz-nix
Add [[bin]] section to Cargo.toml so cargo produces target/release/qbz
directly. Update all packaging references (workflows, PKGBUILD, Flatpak
manifest, AUR desktop file) to use the new binary name. This fixes DEB
and RPM packages installing the binary as /usr/bin/qbz-nix instead of
/usr/bin/qbz.
2026-02-18 16:45:10 -06:00
vicrodh 0055aef515 fix(plex): backfill album_key for existing cached tracks on migration
Existing plex_cache_tracks rows had NULL album_key after the column
migration, causing plex_cache_get_album_tracks WHERE clause to return
zero results until a full re-sync. Now computes and fills album_key
for all NULL rows on DB open.
2026-02-18 15:16:21 -06:00
vicrodh d26af4b7dd feat(plex): add disc/track number support and album track search
- Parse track_number (index) and disc_number (parentIndex) from Plex XML
- Add track_number, disc_number, album_key columns to plex_cache_tracks
- Fix plex_cache_get_album_tracks: add WHERE album_key clause (was
  returning all tracks) and sort by disc/track number instead of title
- Update all SELECT/INSERT queries to include new columns
- Add inline track search to album detail view with search icon toggle
- Update PlexCachedTrack frontend interface and mapPlexTrack mapping
- Add i18n keys for search placeholder in all 4 locales
2026-02-18 15:14:31 -06:00
vicrodh 11b3486c63 fix(v2): close frontend/backend command audit gaps
- add/register missing v2 commands surfaced by audit
- migrate frontend invokes to v2 equivalents
- eliminate legacy invoke callsites in audit report
- harden invoke audit parser for generic/multiline invoke usage

cx
2026-02-18 12:59:28 -06:00
vicrodh ba09345aa3 chore(release): prepare 1.1.15-rc-1 and beta checklist
cx
2026-02-17 20:13:30 -06:00
vicrodh 3e2b493e28 merge(feature): integrate purchased downloads into pre-release
cx
2026-02-17 20:11:21 -06:00
vicrodh 1472fb2dcc feat(purchases): implement real V2 purchases API and clean mock remnants
cx
2026-02-17 20:03:41 -06:00
vicrodh 861a9e0311 revert(purchases): remove mock FastAPI server from repository
cx
2026-02-17 19:36:22 -06:00
vicrodh 415a9d93f3 fix: hide cover art on unavailable albums so overlay text is readable 2026-02-17 18:58:08 -06:00
vicrodh 42915197e3 feat: add downloaded purchases registry in SQLite backend with V2 commands
- downloaded_purchases table in library DB (permanent, per-user)
- V2 commands: mark_downloaded, remove_downloaded, get_downloaded_track_ids
- Frontend enriches purchase data with download status from backend
- Grid overlay for unavailable albums centered on artwork
- Quality filter expanded: All / Hi-Res / CD / Lossy (radio group)
- Album download status derived from track-level registry
2026-02-17 18:57:24 -06:00
vicrodh eb6830430e feat: move unavailable banner to artwork overlay, add hide-downloaded filter with persistence 2026-02-17 18:44:56 -06:00
vicrodh 3cabd95ff4 refactor: use portal file picker instead of mock text input for download folder 2026-02-17 18:36:34 -06:00
vicrodh c14754d4ef refactor: reuse existing UI patterns in purchases views
- Toolbar: FavoritesView pattern (control-btn, dropdown-menu, dropdown-item)
- Albums: grid/list toggle, group by (Off/A-Z/Artist), sort with direction
- Filter panel: LocalLibraryView pattern (checkbox for hide unavailable, Hi-Res)
- Tracks: group by (Off/Artist/Album/Name A-Z)
- Format selector: standard Dropdown component instead of custom pill
- Download All: global action-btn-circle instead of custom button
- Quality in track rows: plain text (12/192) instead of QualityBadge images
- QualityBadge compact only in album header and list mode
- Add filter.availability and filter.hideUnavailable i18n keys (4 locales)
2026-02-17 18:31:21 -06:00
vicrodh c7752cc1c1 style: polish purchases views to match app design language
Rewrite PurchasesView and PurchaseAlbumDetailView to match existing
views (FavoritesView, AlbumDetailView). Consistent header, sticky nav,
expandable search, scrollbar, table headers, track rows, and spacing.
2026-02-17 18:06:49 -06:00
vicrodh 58101a27f5 fix: add generic type parameters to invoke calls in purchases service 2026-02-17 17:56:03 -06:00
vicrodh 0599493a5a feat: add purchases i18n keys to all 4 locales
Keys added to en.json, es.json, de.json, fr.json:
- nav.purchases
- settings.appearance.showPurchases/showPurchasesDesc
- purchases.* section with tabs, search, filters, sorts,
  download actions, progress, formats, and empty states
2026-02-17 17:54:37 -06:00
vicrodh d57a27ad45 feat: wire purchases views into navigation, sidebar, and settings
- Add 'purchases' and 'purchase-album' to ViewType
- Add conditional ShoppingBag nav item in Sidebar (between Favorites and Playlists)
- Wire PurchasesView and PurchaseAlbumDetailView in +page.svelte
- Add Show Purchases toggle in Settings > Appearance
- Toggle persisted via purchasesStore, hidden by default
2026-02-17 17:52:05 -06:00
vicrodh 86593749ec feat: add PurchasesView and PurchaseAlbumDetailView components
PurchasesView: albums grid and tracks list with search, filter
(all/hires), sort (date/artist/album/quality), and download buttons.

PurchaseAlbumDetailView: album header, format picker, folder picker
(mock mode text input), per-track download buttons, progress bar,
multi-disc grouping, and post-download Add to Library button.
2026-02-17 17:49:26 -06:00
vicrodh eecaa624a8 feat: add purchase types, service layer, and store
- PurchaseResponse, PurchasedAlbum, PurchasedTrack, progress types
- Service layer with mock/real toggle via VITE_MOCK_PURCHASES env var
- purchasesStore for show/hide toggle persistence via userStorage
2026-02-17 17:46:12 -06:00
vicrodh 1d39d37a29 feat: add FastAPI mock server for purchase downloads
Lightweight mock API serving Qobuz-shaped purchase data with CORS
enabled for localhost:1420. Includes 8 albums (varied genres, one
multi-disc, one with downloadable:false), 5 individual tracks,
format options, search, and simulated download progress via SSE.
2026-02-17 17:45:24 -06:00
vicrodh ceaf299558 feat(immersive): add spectral ribbon and fix home blacklist filtering
- add Spectral Ribbon analyzer/render path and immersive panel
- tune ribbon density/interpolation and bars edge-bin rendering
- apply artist blacklist filtering to discover index home containers
- include supporting i18n/settings/player wiring changes

cx
2026-02-17 17:28:32 -06:00
vicrodh e00d58949a fix: remove downloadStateVersion from each-block keys to stop flicker
The global downloadStateVersion counter was embedded in {#each} key
expressions, causing Svelte to destroy and recreate all DOM nodes
whenever the counter incremented during downloads. Track IDs alone
are stable and unique keys; download status reactivity is already
handled by props passed to TrackRow.

Also skip redundant notifyListeners() calls in setOfflineCacheState
when status and progress haven't actually changed, preventing
unnecessary downloadStateVersion++ cascades.
2026-02-17 11:38:36 -06:00
vicrodh 7b8e2d56ac feat(local-library): add Plex source filter and one-shot session sync
Add dedicated Plex source filter in albums view, header sync button when Plex is configured, and one-time auto-sync per session when Plex cache is empty.

cx
2026-02-17 11:38:24 -06:00
vicrodh 7e0c54c9f8 fix(playlists): restore suggestions and duplicate-check commands in v2
cx
2026-02-17 11:22:27 -06:00
vicrodh 76cf401a3a perf: separate library DB connection for download post-processing
Add a second LibraryDatabase connection to OfflineCacheState dedicated
to download post-processing writes. SQLite WAL mode natively handles
concurrent reads (UI via main connection) and writes (downloads via
this separate connection), eliminating app-level mutex contention that
caused progressive UI lag during bulk downloads.

Init after library.init_at() in both activate_session and
activate_offline_session. Teardown before main offline_cache teardown.
2026-02-17 11:02:02 -06:00
vicrodh 644571f82a perf: add batch offline cache command to replace sequential IPC loops
Add v2_cache_tracks_batch_for_offline command that inserts all tracks
in a single SQLite transaction and spawns download tasks in one IPC
call. Extract spawn_track_cache_download helper shared by both single
and batch commands.

Replace sequential for-of loops with batch calls in PlaylistDetailView
and +page.svelte (downloadAlbumById, handleDownloadAlbum,
handleReDownloadAlbum, reDownloadAlbumById). Single-track handlers
remain unchanged.

Reduces 75 IPC round-trips to 1 for bulk downloads.
2026-02-17 10:59:02 -06:00
vicrodh 343bfff357 perf: add 200ms time throttle to download progress events
Add a minimum 200ms interval between progress emissions per track,
on top of the existing 2% change filter. Always emits at 100%.
Limits events to max 5/sec/track, reducing IPC pressure during
concurrent downloads.
2026-02-17 10:55:09 -06:00
vicrodh 086f7f62e4 perf: rAF debounce for offline cache listener notifications
Coalesce all offline cache state notifications within a single
animation frame (~16ms) into one notification cycle. This caps
UI re-renders from hundreds/sec down to max 60/sec during bulk
downloads, preventing progressive UI lag from event storms.
2026-02-17 10:54:10 -06:00
vicrodh bc8300ea62 fix: add WAL mode to api_cache and favorites_preferences SQLite connections
These two databases were missing PRAGMA journal_mode=WAL and
PRAGMA synchronous=NORMAL, which could cause UI lag from lock
contention during concurrent reads/writes.
2026-02-17 10:22:33 -06:00
vicrodh cfd033e2bd fix(artist): lower jump-nav z-index from 40000 to 50 2026-02-17 09:55:49 -06:00
vicrodh 4c765617d5 fix(immersive): increase gap between reactive artwork and track info 2026-02-17 09:52:19 -06:00
vicrodh 86e3424c79 fix(immersive): track info inline with player, artwork right of text
Shrink player bar min-width 700→670px. Move track info block to
bottom: 24px (same level as player). Album art now sits to the right
of the text block (title/album/artist/badge). The info block is part
of the panel so it stays visible when player controls auto-hide.
2026-02-17 09:36:48 -06:00
vicrodh 39b2ccaa8b fix(immersive): 4-row track info + album art thumbnail on all viz panels
All 4 canvas panels (Oscilloscope, Energy, Pulse, X/Y) now share:
- Bottom-left: 72px album art thumbnail with rounded corners
- Bottom-right: 4 rows (title, album, artist, compact badge), right-aligned,
  max-width 400px for longer text
- Energy: removed 85% height constraint, rings use full canvas
2026-02-17 09:23:17 -06:00
vicrodh 4f7bc88155 fix(immersive): oscilloscope track info as 4 separate rows with wider max-width 2026-02-17 09:17:19 -06:00