Commit Graph
894 Commits
Author SHA1 Message Date
vicrodh 585053bd42 feat(label): redesign label detail view with Android-style sections
Replace the flat album grid LabelView with a rich detail page featuring:
- Header with label image, name, description, and play button
- Popular Tracks section (5/10/all expand, same UX as ArtistDetailView)
- Releases horizontal scroll row with "See all" → LabelReleasesView
- Critics' Picks section from second releases container
- Playlists, Artists, and More Labels sections

Backend: add /label/page and /label/explore API endpoints with V2
commands (v2_get_label_page, v2_get_label_explore). Models use
serde_json::Value for flexible section parsing.

Old LabelView renamed to LabelReleasesView for the "See all" flow.
i18n keys added to all 4 locales (en, es, de, fr).
2026-02-20 02:51:47 -06:00
vicrodh 494ddce28b feat(v2): register purchases-get-ids, purchases-get-by-type, and dynamic-suggest commands
New V2 Tauri commands:
- v2_purchases_get_ids: fetch purchase IDs with optional type filter
- v2_purchases_get_by_type: fetch all albums or tracks with download status
- v2_dynamic_suggest: typed dynamic suggestions from Qobuz API
- v2_dynamic_suggest_raw: raw JSON variant for debugging

Registered all four in the Tauri invoke handler.
2026-02-20 00:15:12 -06:00
vicrodh a7ffe13469 feat(api): add purchases-by-type, purchase-ids, and dynamic-suggest endpoints
New API client methods:
- get_user_purchases_page_typed: fetch purchases filtered by type (album/track)
- get_user_purchases_ids_page_typed: fetch purchase IDs by type
- get_user_purchases_all_typed: paginated fetch for a single purchase type
- get_user_purchases_ids_page: generic purchase IDs page
- get_dynamic_suggest / get_dynamic_suggest_raw: Qobuz dynamic suggestions

New models: DynamicSuggestRequest/Response/Track, DynamicTrackToAnalyse,
PurchaseIdsResponse, lenient serde deserializers for robust API parsing.
2026-02-20 00:15:05 -06:00
vicrodh 3a297c0b2b style: apply cargo fmt across codebase
Automated formatting pass covering 79 Rust source files.
No logic changes -- only line wrapping, import ordering,
and match/closure reformatting.
2026-02-20 00:14:58 -06:00
vicrodh 867b1dfbe0 perf(share): eliminate Odesli API call, construct song.link URLs directly
ISRC/UPC paths now use a single Deezer API request instead of two
sequential requests (Deezer + Odesli). The song.link/album.link URL
is constructed directly from the Deezer ID (e.g. song.link/d/12345).

This cuts latency from ~2-5s (often timing out) to ~200ms.
The Odesli fallback is kept only for get_by_url (no ISRC/UPC).
2026-02-19 18:47:44 -06:00
vicrodh 844bd60319 fix(share): use Deezer ID + platform param for faster Odesli lookups
Instead of passing a full Deezer URL to Odesli (which requires URL
resolution), use platform=deezer&type=song&id=XXX params directly.
This is faster since Odesli skips URL parsing.

Also fix album sharing (get_by_upc) — Odesli no longer accepts ?upc=
directly, same Deezer resolution approach applied.

Bump request timeout from 10s to 20s with 5s connect timeout.
2026-02-19 18:42:14 -06:00
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 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 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 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 1472fb2dcc feat(purchases): implement real V2 purchases API and clean mock remnants
cx
2026-02-17 20:03:41 -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 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 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 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 d4bc1fe677 fix(immersive): improve visualizer panels per feedback
Energy Bands + Oscilloscope:
- Constrain drawing area to 85% of screen height, vertically centered

Oscilloscope:
- Change from bottom-left info to centered artwork layout (like Bars)

Transient Pulse:
- Lower backend threshold 0.15 -> 0.04, cooldown 6 -> 3 frames
- Use raw (un-smoothed) bass-weighted RMS for sharper detection
- Add frontend-side supplementary beat detection from energy data

Album Reactive:
- Fix glow layer centering (was anchored to top-left, now inset: 0)
- Double scale effect (0.04 -> 0.08) and glow spread (40 -> 80)
- Fast attack / medium decay smoothing for visible reactivity
2026-02-17 08:22:56 -06:00
vicrodh 6c4eaef9a5 feat(immersive): add 4 new visualizer tabs
Backend:
- Emit viz:energy with 5-band RMS (sub-bass, bass, mids, presence, air)
- Emit viz:transient with attack detection (threshold + cooldown)

Frontend panels:
- EnergyBandsPanel: concentric glowing rings around centered artwork
- LissajousPanel: stereo X/Y phase plot with trail (watermark layout)
- TransientPulsePanel: expanding rings from center on beat detection
- AlbumReactivePanel: album art with breathing scale/glow from energy

All panels extract colors from album art, throttle at 30fps, and follow
the existing visualizer lifecycle (enable/disable backend on mount).

Focus tabs now: Coverflow, Static, Bars, Scope, Energy, X/Y, Pulse,
Reactive, Lyrics, Queue (keys 1-0).
2026-02-17 07:53:49 -06:00
vicrodh 3b94acd95e feat(visualizer): emit stereo waveform data for oscilloscope
Add viz:waveform event emission alongside existing viz:data FFT output.
De-interleaves L/R channels from the raw sample buffer and downsamples
to 256 points per channel (512 floats = 2048 bytes). Pre-allocates the
waveform buffer outside the hot loop to avoid per-frame allocations.
2026-02-17 03:40:13 -06:00
vicrodh f583092a76 chore(packaging): add qobuzapp scheme to desktop files
All 6 .desktop files now declare x-scheme-handler/qobuzapp in their
MimeType line, enabling OS-level link capture for qobuzapp:// URLs.
2026-02-17 00:25:09 -06:00
vicrodh d286aec9ef feat(core): forward scheme links from single-instance and launch args
Single-instance plugin now inspects args for qobuzapp:// or
play.qobuz.com URLs and emits link:resolved event. Launch args
are also checked on first startup with a 1.5s delay for frontend
readiness.
2026-02-17 00:24:49 -06:00
vicrodh 261d420540 feat(v2): add qobuzapp handler registration commands
v2_check_qobuzapp_handler, v2_register_qobuzapp_handler,
v2_deregister_qobuzapp_handler — use xdg-mime for scheme handler
registration and mimeapps.list editing for deregistration.
2026-02-17 00:24:02 -06:00
vicrodh 9006e64fa2 feat(v2): add v2_resolve_qobuz_link command
Thin Tauri command that calls qbz_qobuz::resolve_link(). Pure parsing,
no State params, no auth required. Registered in invoke_handler.
2026-02-17 00:23:16 -06:00
vicrodh 0c66a14249 fix(player): stabilize seek interaction and remove misleading secondary bar refs #75
cx
2026-02-16 22:48:39 -06:00
vicrodh 39bbbdc230 fix(playback): reduce mpris desync and stale playback event lag refs #85
cx
2026-02-16 21:36:07 -06:00
vicrodh c3696f02d4 fix(playback): harden auto-advance for long-track edge cases
cx
2026-02-16 20:08:34 -06:00
vicrodh 99877fa740 fix(v2): align immersive track info/radio and i18n history keys
cx
2026-02-16 19:27:47 -06:00
vicrodh 37db48ea3d fix(v2): complete command migration sweep and musician/blacklist flows
- migrate remaining frontend invokes to V2 names
- add missing V2 command registrations and implementations
- enforce commands_v2 backend purity (no legacy delegation)
- restore blacklist/relationships/musician flows in V2
- align playlist/local-library/settings invoke paths with V2

cx
2026-02-16 18:40:07 -06:00
vicrodh 45b98c40d4 fix(v2): harden session restore and favorites query params
cx
2026-02-16 17:16:41 -06:00
vicrodh 6f7b8e0aff Revert "fix(v2): harden session restore and favorites query params"
This reverts commit c20bb034ae.
2026-02-16 17:16:29 -06:00
vicrodh c20bb034ae fix(v2): harden session restore and favorites query params
cx
2026-02-16 17:15:58 -06:00
vicrodh 1037b59cfa refactor(v2): hard-delete unused legacy command files
cx
2026-02-16 17:11:24 -06:00
vicrodh ffd5c992b0 refactor(v2): shrink legacy command module to internal minimum
cx
2026-02-16 17:09:29 -06:00
vicrodh 43ebf19ae1 chore(v2): hard-cut legacy invoke handler surface
cx
2026-02-16 17:04:08 -06:00
vicrodh a58116212c fix(v2): stabilize plex playback control and shuffle reorder semantics
cx
2026-02-16 15:23:46 -06:00
vicrodh e51f367b31 fix(v2): restore Plex command surface for LocalLibrary
cx
2026-02-16 12:53:20 -06:00
vicrodh 8ac5ba92fd refactor(v2): enforce backend purity and stabilize playback runtime
cx
2026-02-16 07:45:43 -06:00
vicrodh d64e0f38d7 chore(v2): apply phase-2 legacy cut-off for auth playback queue and context surface
cx
2026-02-16 04:14:13 -06:00
vicrodh 9e126a0c59 chore(v2): apply legacy invoke cut-off markers in handler with rollback notes
cx
2026-02-16 04:08:22 -06:00
vicrodh ee5998533d refactor(v2): route library flows through shared impls and remove command-to-command calls
cx
2026-02-16 04:05:16 -06:00
vicrodh d2a13ba95e refactor(v2): internalize notification offline playlist reset and reco training flows
cx
2026-02-16 04:02:52 -06:00