Commit Graph
1163 Commits
Author SHA1 Message Date
vicrodh 2802527912 chore(deps): update jsdom 29.0.2, notify-rust 4.14.0
Also closed PR #298 (md-5 0.11) — breaking API change across 9
call sites for zero functionality gain.

cc
2026-04-09 08:38:19 -06:00
Victor RH b196a299dc Merge pull request #300 from vicrodh/dependabot/cargo/src-tauri/pre-release/tauri-plugin-dialog-2.7.0 2026-04-09 08:20:17 -06:00
Victor RH 1bc3eaf759 Merge pull request #299 from vicrodh/dependabot/cargo/src-tauri/pre-release/rodio-0.22.2 2026-04-09 08:20:13 -06:00
Victor RH 15c926ea6f Merge pull request #295 from vicrodh/dependabot/cargo/src-tauri/pre-release/tauri-plugin-deep-link-2.4.8 2026-04-09 08:20:02 -06:00
vicrodh 8fc6111782 feat(qbzd): mDNS discovery + registration for LAN pairing
Daemon side: registers _qbz._tcp.local mDNS service on startup
so desktop apps can discover it on the LAN. Uses hostname as
service name (configurable via qbzd.toml).

Desktop side: new qbzd_discovery.rs module with Tauri commands:
- v2_qbzd_start_discovery: browse _qbz._tcp services
- v2_qbzd_stop_discovery: stop browsing
- v2_qbzd_get_devices: list discovered daemons

Uses same mdns-sd crate already used for AirPlay discovery.

cc
2026-04-09 04:30:08 -06:00
dependabot[bot] e6bacb7507 chore(deps): bump tauri-plugin-dialog from 2.6.0 to 2.7.0 in /src-tauri
Bumps [tauri-plugin-dialog](https://github.com/tauri-apps/plugins-workspace) from 2.6.0 to 2.7.0.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/log-v2.6.0...log-v2.7.0)

---
updated-dependencies:
- dependency-name: tauri-plugin-dialog
  dependency-version: 2.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-09 05:37:52 +00:00
dependabot[bot] 608f9508ef chore(deps): bump rodio from 0.22.1 to 0.22.2 in /src-tauri
Bumps [rodio](https://github.com/RustAudio/rodio) from 0.22.1 to 0.22.2.
- [Changelog](https://github.com/RustAudio/rodio/blob/master/CHANGELOG.md)
- [Commits](https://github.com/RustAudio/rodio/compare/v0.22.1...v0.22.2)

---
updated-dependencies:
- dependency-name: rodio
  dependency-version: 0.22.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-09 05:37:36 +00:00
dependabot[bot] b2527d829b chore(deps): bump tauri-plugin-deep-link in /src-tauri
Bumps [tauri-plugin-deep-link](https://github.com/tauri-apps/plugins-workspace) from 2.4.7 to 2.4.8.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/deep-link-v2.4.7...deep-link-v2.4.8)

---
updated-dependencies:
- dependency-name: tauri-plugin-deep-link
  dependency-version: 2.4.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-09 05:36:58 +00:00
vicrodh 242b27bb1b refactor: clean up commands_v2/mod.rs
cc
2026-04-08 19:10:23 -06:00
vicrodh 77f12075da refactor: extract commands_v2/diagnostics.rs
cc
2026-04-08 18:07:54 -06:00
vicrodh 8fa11a4317 refactor: extract commands_v2/discovery.rs
cc
2026-04-08 18:05:50 -06:00
vicrodh b0ae328964 refactor: extract commands_v2/image_cache.rs
cc
2026-04-08 18:02:05 -06:00
vicrodh 709c399e31 refactor: extract commands_v2/session.rs
cc
2026-04-08 17:59:33 -06:00
vicrodh 6f1a1c8a22 refactor: extract commands_v2/settings.rs
cc
2026-04-08 17:55:33 -06:00
vicrodh 93154690e3 refactor: extract commands_v2/auth.rs
cc
2026-04-08 17:49:16 -06:00
vicrodh 45ab6c34b6 refactor: extract commands_v2/catalog.rs
cc
2026-04-08 17:46:59 -06:00
vicrodh 5f4cc58d99 refactor: extract commands_v2/playlists.rs
cc
2026-04-08 15:26:06 -06:00
vicrodh c746303f2b refactor: extract commands_v2/audio.rs
cc
2026-04-08 15:23:48 -06:00
vicrodh 98f17019d4 refactor: extract commands_v2/favorites.rs
cc
2026-04-08 15:18:37 -06:00
vicrodh 0303e40f32 refactor: extract commands_v2/search.rs
cc
2026-04-08 15:16:04 -06:00
vicrodh 6c6199a76d refactor: extract commands_v2/queue.rs
cc
2026-04-08 15:11:43 -06:00
vicrodh 02bae5b601 refactor: extract commands_v2/runtime.rs
cc
2026-04-08 15:01:25 -06:00
vicrodh 555139a6e2 refactor: extract commands_v2/playback.rs
cc
2026-04-08 14:44:55 -06:00
vicrodh f4c874fdac refactor: extract commands_v2/link_resolver.rs
cc
2026-04-08 14:30:05 -06:00
vicrodh d667c3e13c refactor: extract commands_v2/integrations.rs
cc
2026-04-08 13:47:46 -06:00
vicrodh 82e1b337a1 refactor: extract commands_v2/helpers.rs
cc
2026-04-08 13:34:51 -06:00
vicrodh d8dbcf7bd7 refactor: extract commands_v2/library.rs
cc
2026-04-08 13:15:43 -06:00
vicrodh ccce564586 refactor: extract commands_v2/legacy_compat.rs
cc
2026-04-08 12:57:08 -06:00
vicrodh 6cc75d091a refactor: convert commands_v2.rs to module directory
Rename commands_v2.rs to commands_v2/mod.rs as the first step
of splitting the 14,635-line file into domain-specific modules.
No functional changes.

cc
2026-04-08 12:34:37 -06:00
vicrodh c56bd12e46 refactor(gapless): flatten local library check from 4 nested ifs
Chain Option combinators to reduce nesting. The await boundary
requires one outer if-let, but the rest flattens into a single
and_then/map/filter pipeline.

cc
2026-04-08 12:20:07 -06:00
vicrodh 7191309f62 Merge remote-tracking branch 'origin/pre-release' into pre-release 2026-04-08 12:14:25 -06:00
vicrodh 94949a7f5d fix(qconnect): persist custom device name across restarts
The custom QConnect device name was stored in-memory only,
resetting to "Qbz - hostname" on every app launch.

Now persists to qconnect_settings.db in the global data dir
(~/.local/share/qbz/). Loaded on startup, saved on change.
Fail-open: any db error silently falls back to default.

Fixes #284

cc
2026-04-08 10:40:37 -06:00
vicrodh a30cfa7c71 Merge branch 'bugfix/internal/1.2.5-alsa-lifecycle' into pre-release 2026-04-08 10:29:37 -06:00
vicrodh b6035cb3ad perf(prefetch): increase cache depth to 5 tracks, 2 concurrent
- V2_PREFETCH_COUNT: 2 -> 5 (cache ~2 min ahead)
- V2_MAX_CONCURRENT_PREFETCH: 1 -> 2 (overlap downloads)
- V2_PREFETCH_LOOKAHEAD: 10 -> 15 (find more Qobuz tracks)

Combined with parallel CMAF segments from previous commit,
this keeps the cache well ahead of playback. The sliding
window re-triggers on every track play, so the 5-track
buffer advances continuously through the queue.

cc
2026-04-08 10:27:19 -06:00
AdamArstall 56ec473e14 Merge remote-tracking branch 'upstream/pre-release' into bugfix/external/local-library-gapless 2026-04-08 17:21:24 +01:00
vicrodh 438cc18851 perf(cmaf): parallel segment downloads for prefetch cache
Download CMAF segments concurrently (3 slots) instead of
sequentially for prefetch/cache operations. Each slot has a
500ms cooldown after download to stay under CDN rate limits.

This only affects cache prefetch (try_cmaf_full_download),
not real-time streaming which remains sequential for smooth
playback. Segments are reassembled in order after download.

Typical improvement: 10-segment track goes from ~10 serial
HTTP requests to ~4 batches of 3 concurrent downloads.

cc
2026-04-08 09:58:20 -06:00
vicrodh 6efdca0ea8 feat(oauth): add cancel commands for both OAuth flows
Add OAuthCancelState with shared Notify for system browser flow.
v2_start_system_browser_oauth uses tokio::select! to race between
code received, 120s timeout, and user cancel signal.

New commands:
- v2_cancel_system_browser_oauth: triggers cancel notify
- v2_cancel_oauth_login: closes all OAuth WebView windows

Timeout reduced from 300s to 120s for system browser flow.

cc
2026-04-08 08:49:51 -06:00
vicrodh 814bf8b968 fix(oauth): detect WebView window close to unblock login wait
When the user closes the OAuth WebView window manually, the
Destroyed event now triggers notify to unblock the 5-minute
timeout immediately, returning oauth_cancelled instead of
hanging until timeout.

cc
2026-04-08 08:37:02 -06:00
vicrodh dbc97d6bd1 feat(search): add request signing to all search endpoints
Add request_ts + request_sig (MD5 signature) to catalog/search,
album/search, track/search, artist/search, and playlist/search
endpoints matching the mobile app authentication pattern.

Migrate v2_search_all from legacy AppState to CoreBridge, removing
the last direct API call that bypassed the V2 crate architecture.

cc
2026-04-08 08:34:32 -06:00
vicrodh 7faa4e467a fix(audio): default alsa_plugin to Hw when switching to ALSA backend
When selecting ALSA Direct as backend, alsa_plugin was never persisted
to the DB if the user didn't explicitly change it. The UI showed
"hw (Direct Hardware)" as a visual default but the DB stayed NULL,
causing isAlsaDirect to evaluate false and showing a gray DAC badge
instead of the blue HW badge.

cc
2026-04-07 17:20:17 -06:00
vicrodh d1278e12ad chore: bump version to 1.2.4 - Hardening playback
cc
2026-04-07 09:48:04 -06:00
vicrodh 74e3ba9519 chore(logging): reduce noise in default log level
- Device enumeration (48 CPAL devices): info → debug
- Playlist fetch completion: info → debug
- Playlist command invocation: info → debug
- zbus socket_reader/tracing: filtered to warn level

These remain visible with RUST_LOG=debug or verbose log capture.

cc
2026-04-07 08:39:18 -06:00
vicrodh a279e04881 feat(credentials): use XDG portal secret for key derivation
Add per-app secret from org.freedesktop.portal.Secret as entropy
in the AES-256-GCM key derivation. DE-agnostic (works with GNOME,
KDE, etc.) and Flatpak-safe (portals auto-accessible in sandbox).

Falls back to machine_id + salt when portal is unavailable (headless,
old DEs, non-Linux). Cached for session lifetime via OnceLock.

Users will need to re-login once on upgrade (key derivation changed).

cc
2026-04-07 08:22:28 -06:00
vicrodh 6da5092605 fix(credentials): encrypt OAuth token in keyring
Token was stored as plaintext in the system keyring, visible via
secret-tool. Now AES-256-GCM encrypted before storing — keyring
entry shows ciphertext, not the raw token.

Handles migration from both plaintext keyring entries and encrypted
files from previous versions.

cc
2026-04-07 07:38:57 -06:00
vicrodh 04eab0d880 fix(credentials): keyring-only storage, no redundant file
OAuth token was saved to BOTH keyring and encrypted file, making the
keyring pointless. Now:
- Save: keyring first. Only writes file if keyring unavailable.
- Load: keyring first. If found in file, migrates to keyring and
  deletes the file.
- Result: when keyring works, no token file exists on disk.

cc
2026-04-07 07:19:44 -06:00
vicrodh 4505312280 fix(security): remove hardcoded crypto seed from cmaf crate
Move the CMAF app seed from a hardcoded constant in qbz-cmaf to a
parameter passed by callers. The seed now lives in qbz-qobuz::auth
where other app-level constants are defined. This resolves CodeQL
alerts for hard-coded cryptographic values.

Also truncate session_id in logs to avoid cleartext logging of
sensitive session identifiers.

cc
2026-04-07 07:04:33 -06:00
vicrodh 5f154aaf98 fix(logout): clear stored credentials on logout
Logout was not clearing OAuth tokens or credentials from keyring
and encrypted files. Users had to manually delete files to fully
sign out. Now clears both keyring and file storage.

cc
2026-04-07 06:52:32 -06:00
vicrodh 192f681d25 fix: bump Cargo.toml version to 1.2.3
Cargo.toml was left at 1.2.2 because the version bump sed command
only matched JSON format ("version": "1.2.2") not TOML format
(version = "1.2.2"). This caused CARGO_PKG_VERSION to report 1.2.2
at runtime, triggering the update-available modal on every launch.

cc
2026-04-07 06:41:19 -06:00
vicrodh 2a6bb658b1 fix(credentials): improve keyring failure logging visibility
Keyring save/load failures were logged at debug level, making them
invisible in normal logs. Users on KDE Plasma 6 reported the keyring
feature not working (#276) but couldn't see why.

Promoted keyring failures to warn level with actionable messages
(e.g., KDE users need org.freedesktop.secrets enabled in KWallet).

cc
2026-04-07 06:29:28 -06:00
vicrodh 11bffe7071 fix(cmaf): fetch all audio segments (off-by-one in segment loop)
Loop used 1..n_segments (exclusive) but n_segments is the count of
audio segments, not the last index. Segments are numbered 1 through
n_segments, so the loop must be 1..=n_segments (inclusive).

This caused the last ~9 seconds of every CMAF-streamed track to be
missing. Confirmed with diagnostic logging: table_total_samples
exceeded actual decoded frames by exactly one segment's worth.

cc
2026-04-07 06:17:37 -06:00