Commit Graph
1036 Commits
Author SHA1 Message Date
victorrhgap 7c96720dca chore: bump version to 1.2.1
Update all version endpoints, regenerate lockfiles,
add metainfo release entry and release docs.

cc
2026-03-25 19:47:08 -06:00
victorrhgap 3dd09ea522 chore(deps): bump aws-lc-rs 1.16.1 -> 1.16.2, aws-lc-sys 0.38.0 -> 0.39.0
Fixes dependabot alerts #25 and #26 (high severity):
- CRL Distribution Point Scope Check Logic Error
- X.509 Name Constraints Bypass via Wildcard/Unicode CN

cc
2026-03-25 18:13:02 -06:00
victorrhgap a8910a66c7 feat(prefetch): use exponential backoff for cache pre-loading
Replace fixed 500ms delays with download_with_backoff in prefetch
path. Gives the same 1s/2s/4s backoff and 4th retry as playback.

cc
2026-03-25 15:35:58 -06:00
victorrhgap b08e5ecf02 feat(audio): exponential backoff retry with quality fallback
Replace fixed 500ms delays with 1s/2s/4s exponential backoff.
Add 4th retry attempt at fallen-back quality level.
Return QualityExhausted structured error when all attempts fail.
Add force_lowest_quality param to v2_play_track.

cc
2026-03-25 14:22:07 -06:00
victorrhgap 94518e56c2 feat(audio): add v2 commands for quality fallback behavior
v2_get_quality_fallback_behavior and v2_set_quality_fallback_behavior
to read/write the persisted user preference.

cc
2026-03-25 14:06:21 -06:00
victorrhgap 038f846884 feat(audio): add quality_fallback_behavior to audio settings
Persisted in audio_settings.db, protected by ADR-003.
Survives reset_all(), defaults to 'ask'.

cc
2026-03-25 14:03:56 -06:00
victorrhgap 39e5867a7d fix: proxy all images through reqwest to bypass WebKit TLS (#163)
When image cache is disabled or unavailable, images were returned
as original HTTPS URLs for WebKit to load directly. On AppImage
distros where GnuTLS can't find system CA certs, this fails silently.

Now all images go through reqwest (rustls, bundled CA) and are
written to temp files as file:// URLs. WebKit never needs to
resolve HTTPS for images.

cc
2026-03-24 20:35:32 -06:00
Victor RH e6ea2b483c Merge pull request #198 from vicrodh/dependabot/cargo/src-tauri/rustls-webpki-0.103.10 2026-03-24 20:17:12 -06:00
victorrhgap 9f7304b35b Merge branch 'pr-181' into pre-release 2026-03-24 19:28:57 -06:00
victorrhgap 499f188bf8 fix: hybrid Intel+NVIDIA treated as NVIDIA-only for compositing
main.rs GPU conditions checked has_nvidia && !has_amd but not
has_intel, so hybrid laptops (Intel iGPU + NVIDIA dGPU) had
compositing and DMA-BUF disabled unnecessarily.

Also remove duplicate DMABUF/compositing logic from lib.rs that
ran before main.rs and conflicted with its GPU-aware decisions.

cc
2026-03-24 18:03:46 -06:00
victorrhgap be900ab628 feat: add v2_get_runtime_diagnostics command
Single IPC call returns saved audio/graphics/developer settings,
runtime GPU detection state, and active environment variables.

cc
2026-03-24 17:51:57 -06:00
victorrhgap a472930cd0 fix: respect saved graphics settings at startup
apply_linux_webkit_workarounds() was unconditionally disabling
DMABUF renderer and compositing mode, ignoring what the user
configured in Appearance > Composition settings.

Now reads graphics_settings.db and developer_settings.db at startup
(readonly, before Tauri state init) so toggles actually take effect.

- Add new_readonly() to GraphicsSettingsStore and DeveloperSettingsStore
- Hardware Acceleration ON = compositing enabled
- Force DMA-BUF toggle respected for WEBKIT_DISABLE_DMABUF_RENDERER
- Env vars still override saved settings

cc
2026-03-24 16:06:24 -06:00
victorrhgap 1a5104150a perf: batch download status checks on Home view
Replace 8+ sequential per-section IPC calls with a single batch
command. Backend reads all tracks once instead of N times.

- Add v2_check_albums_fully_cached_batch (single DB read, HashMap return)
- Remove per-section await tick() + loadAllAlbumDownloadStatuses() calls
- Single batch call at end of loadHome() after all data resolves
- Keep individual check for on-click refresh (single album)

cc
2026-03-24 15:58:24 -06:00
vicrodh eeb155641c fix: initialize all user stores in offline session activation
activate_offline_session was only initializing library, offline,
offline_cache, audio_settings, and playback_prefs. Missing stores
caused "No active session" errors for:
- download_settings (Show in Local Library toggle)
- session_store (session persistence)
- favorites_cache/prefs (favorites view)
- tray_settings (tray icon settings)

Now mirrors activate_session but skips online-only services
(MusicBrainz, ListenBrainz, Last.fm, API cache, artist vectors).

cc
2026-03-21 14:32:02 -06:00
vicrodh 8316e1f4c9 fix: logout spinner hang and last_user_id preservation
Two bugs:

1. mainContentEl teardown crash on logout — the $effect cleanup used
   non-null assertion (!) on an element that becomes null when the DOM
   is destroyed during logout. Changed to optional chaining (?.).
   This TypeError was blocking the render, causing the spinner to hang
   instead of showing the login form.

2. deactivate_session was clearing last_user_id, which broke offline
   mode after logout. The user's data stays on disk — only factory
   reset should clear the last_user_id marker.

cc
2026-03-21 14:25:28 -06:00
vicrodh fb74f318a1 fix: restore offline mode — use last known user profile
Three bugs prevented offline mode from working after V2 migration:

1. activate_offline_session used user_id=0 (empty profile) instead of
   the last known user_id, so the user's library/settings were invisible

2. setManualOffline was called BEFORE activate_offline_session, but it
   requires the offline store to be initialized (which happens during
   session activation). Reordered: activate session first, then set
   manual offline.

3. LoginView called setManualOffline directly instead of delegating to
   the parent's handleStartOffline which has the correct order.

Also added "noPreviousSession" i18n message for users who never logged
in — they need to create a profile first before offline mode works.

cc
2026-03-21 11:01:25 -06:00
dependabot[bot] 2c0c46d2bc chore(deps): bump rustls-webpki from 0.103.9 to 0.103.10 in /src-tauri
Bumps [rustls-webpki](https://github.com/rustls/webpki) from 0.103.9 to 0.103.10.
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.103.9...v/0.103.10)

---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-version: 0.103.10
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-21 09:41:52 +00:00
vicrodh 0416198557 fix: retry download with effective quality after fallback (#196)
When get_stream_url_with_fallback internally falls back from UltraHiRes
to HiRes (due to restrictions), the retry logic was requesting a fresh
URL at the original UltraHiRes quality — triggering another fallback
cycle and CDN connection issues.

Now tracks the effective quality from stream_url.format_id and retries
at that quality directly. Applied to both streaming and standard
download paths.

cc
2026-03-20 17:41:22 -06:00
vicrodh f1f084c994 fix: use ~/.local/share/icons for Flatpak tray icon temp path
In Flatpak, the default temp dir is inside the sandbox and invisible
to the host's KDE StatusNotifierWatcher. libayatana-appindicator writes
the PNG to temp dir and calls set_icon_theme_path, but KDE can't see
sandbox paths. Use ~/.local/share/icons which is exported to the host
via Flatpak filesystem permissions.

Non-Flatpak installs continue using XDG_RUNTIME_DIR.

cc
2026-03-20 09:35:01 -06:00
Afonso Jorge Ramos 70c27f3772 fix(macos): log when DAC sample rate detection is skipped 2026-03-20 01:16:09 +01:00
Afonso Jorge Ramos ce33270535 refactor: gate KWin functions with cfg(target_os = "linux") 2026-03-20 01:15:52 +01:00
Afonso Jorge Ramos 379ba28cee refactor: simplify should_use_main_window_transparency 2026-03-20 01:15:28 +01:00
Afonso Jorge Ramos ebe555b7ca fix(macos): make notification fire-and-forget 2026-03-20 01:14:08 +01:00
Afonso Jorge Ramos f854e09661 feat(audio): add SystemDefault variant to AudioBackendType 2026-03-20 01:13:29 +01:00
Afonso Jorge Ramos 77888fb310 fix: suppress unused_mut warning for cross-platform builder 2026-03-20 00:49:42 +01:00
Afonso Jorge Ramos 08367fe951 fix: convert 16-bit PNG icons to 8-bit for Tauri compatibility 2026-03-20 00:45:16 +01:00
Afonso Jorge Ramos caffd7b56c feat(macos): enable private API and set minimum system version 2026-03-20 00:45:16 +01:00
Afonso Jorge Ramos 3809a5cc67 feat(macos): add notify-rust dependency for desktop notifications 2026-03-20 00:45:15 +01:00
Afonso Jorge Ramos dbfc5e3f89 feat(macos): gate Linux-only commands and configure macOS window
- Gate XDG/desktop handler commands with macOS fallbacks
- Gate KWin window rule functions and cleanup to Linux
- Gate Linux-only notification helpers and constants
- Force native decorations on macOS (fixes WKWebView event delivery)
- Use overlay title bar style with dark background color
- Add macOS notifications via notify-rust with bundle identifier
2026-03-20 00:45:15 +01:00
Afonso Jorge Ramos 9bcf24131f feat(macos): gate network module and fix remaining souvlaki error formatting
Gate /proc/self/mountinfo parsing to Linux with empty fallback. Use
Debug formatting for remaining souvlaki errors not covered by 6261f312.
2026-03-20 00:45:15 +01:00
vicrodh 95bc788c5a chore: clean up all warnings — zero Rust warnings, zero Svelte warnings
Rust:
- Remove unused get_screen_resolution() function
- Remove unused DEFAULT_QCONNECT_DEVICE_NAME constant

Svelte:
- Add tabindex=-1 to TitleBarNav menu dropdowns (a11y)
- Make volumeRef reactive with $state() in NowPlayingBar
- Remove unused .section-separator CSS from NowPlayingBar
- Remove unused .artist-albums CSS from SearchView and Grid
- Remove unused .artist-list-meta CSS from ArtistList

cc
2026-03-19 17:44:53 -06:00
vicrodh 352d589276 fix: update rcgen 0.12 -> 0.14 API and suppress unused variable warning
rcgen 0.14 breaking changes:
- CertificateParams::new() takes Vec<String> not Vec<SanType>
- Certificate::from_params() replaced by params.self_signed(&key_pair)
- cert.serialize_pem() replaced by cert.pem()
- cert.serialize_private_key_pem() replaced by key_pair.serialize_pem()
- Ia5String no longer public, DNS SANs passed as strings

Also prefixed unused _envelope variable in qconnect_service.rs.

cc
2026-03-19 17:34:12 -06:00
dependabot[bot] 3e6b51c7dd chore(deps): bump qrcode-generator from 4.1.9 to 5.0.0 in /src-tauri
Bumps [qrcode-generator](https://github.com/magiclen/qrcode-generator) from 4.1.9 to 5.0.0.
- [Commits](https://github.com/magiclen/qrcode-generator/compare/v4.1.9...v5.0.0)

---
updated-dependencies:
- dependency-name: qrcode-generator
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 23:22:18 +00:00
Victor RH ef4ee640b1 Merge pull request #191 from vicrodh/dependabot/cargo/src-tauri/pre-release/rcgen-0.14.7
chore(deps): bump rcgen from 0.12.1 to 0.14.7 in /src-tauri
2026-03-19 17:21:05 -06:00
Victor RH 9cf7657be7 Merge pull request #193 from vicrodh/dependabot/cargo/src-tauri/pre-release/ashpd-0.13.8
chore(deps): bump ashpd from 0.13.3 to 0.13.8 in /src-tauri
2026-03-19 17:21:03 -06:00
Victor RH eb82bc8920 Merge pull request #190 from vicrodh/dependabot/cargo/src-tauri/pre-release/tauri-2.10.3
chore(deps): bump tauri from 2.10.2 to 2.10.3 in /src-tauri
2026-03-19 17:21:01 -06:00
dependabot[bot] d04781826c chore(deps): bump ashpd from 0.13.3 to 0.13.8 in /src-tauri
Bumps [ashpd](https://github.com/bilelmoussaoui/ashpd) from 0.13.3 to 0.13.8.
- [Release notes](https://github.com/bilelmoussaoui/ashpd/releases)
- [Commits](https://github.com/bilelmoussaoui/ashpd/commits)

---
updated-dependencies:
- dependency-name: ashpd
  dependency-version: 0.13.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 23:16:32 +00:00
dependabot[bot] 9d29ed757c chore(deps): bump uuid from 1.21.0 to 1.22.0 in /src-tauri
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.21.0 to 1.22.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.21.0...v1.22.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 23:16:18 +00:00
dependabot[bot] 92058de4a2 chore(deps): bump rcgen from 0.12.1 to 0.14.7 in /src-tauri
Bumps [rcgen](https://github.com/rustls/rcgen) from 0.12.1 to 0.14.7.
- [Release notes](https://github.com/rustls/rcgen/releases)
- [Commits](https://github.com/rustls/rcgen/compare/v0.12.1...v0.14.7)

---
updated-dependencies:
- dependency-name: rcgen
  dependency-version: 0.14.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 23:16:06 +00:00
dependabot[bot] 97ac638ae3 chore(deps): bump tauri from 2.10.2 to 2.10.3 in /src-tauri
Bumps [tauri](https://github.com/tauri-apps/tauri) from 2.10.2 to 2.10.3.
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/tauri-v2.10.2...tauri-v2.10.3)

---
updated-dependencies:
- dependency-name: tauri
  dependency-version: 2.10.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 23:15:47 +00:00
vicrodh af23efb3c1 chore: bump version to 1.2.0
Updated:
- src-tauri/Cargo.toml
- src-tauri/tauri.conf.json
- package.json + package-lock.json
- snapcraft.yaml (root + packaging/)
- flake.nix
- Cargo.lock
- metainfo.xml (new release entry)
- README: Snap MPRIS limitation note with forum link

cc
2026-03-19 17:12:31 -06:00
vicrodh 768b9c118c fix(qconnect): re-request session state after renderer join
QBZ wasn't appearing as a renderer on first connect because the
frontend snapshot was emitted before the deferred renderer join
completed. After joining as renderer, wait 500ms and re-request
session state so the server sends an updated renderer list that
includes QBZ.

cc
2026-03-19 16:07:28 -06:00
vicrodh 780f75158a fix: skip credential tests in Nix build sandbox (#154)
Nix sets HOME=/homeless-shelter during builds, which makes
dirs::config_dir() return a technically writable but unusable path.
The keyring/D-Bus is also unavailable in the sandbox.

Added detection for HOME containing "homeless-shelter" or
"/nix/store", and NIX_BUILD_TOP env var, to skip credential
roundtrip tests in Nix builds.

cc
2026-03-19 14:52:24 -06:00
vicrodh 6261f312be fix: use {:?} for souvlaki MediaControlError formatting
MediaControlError doesn't impl Display on all platforms. Using {}
would fail to compile on non-Linux targets. Use {:?} (Debug) instead.

Cherry-picked from PR #181 by @afonsojramos.

cc
2026-03-19 14:42:12 -06:00
vicrodh 1f1e729db8 fix: HiFi Wizard now detects real DAC sample rates from /proc/asound
v2_query_dac_capabilities was returning hardcoded sample rates
(44.1-192kHz including 176.4kHz) instead of querying the actual
hardware. This caused incorrect configuration for DACs that don't
support all rates (e.g. DacMagic Plus doesn't support 176.4kHz).

Now queries /proc/asound/cardN/stream0 via PipeWire sink mapping
or ALSA device ID to get the real discrete rates from the USB
descriptor. Falls back to defaults only if detection fails.

cc
2026-03-19 12:41:24 -06:00
vicrodh 1ad16338fa feat: add Qobuz playlist follow/unfollow (#172)
Discovered undocumented Qobuz API endpoints from bundle analysis:
- POST /playlist/subscribe { playlist_id }
- POST /playlist/unsubscribe { playlist_id }

This is the native "follow playlist" feature that syncs across all
Qobuz clients, separate from QBZ's existing "Copy to Library" (local
copy) and "Favorite" (local flag) features.

Added:
- subscribe_playlist/unsubscribe_playlist in both qbz-qobuz and legacy client
- v2_qobuz_subscribe_playlist / v2_qobuz_unsubscribe_playlist commands
- Bookmark toggle button in PlaylistDetailView (next to Copy button)
- i18n keys in all 5 locales

cc
2026-03-19 11:36:56 -06:00
vicrodh 509426ebcf fix: restore booklet viewer with mupdf 0.6 (#170)
mupdf 0.5 had struct size mismatches on Arch Linux (mupdf-sys bindings
incompatible with system MuPDF headers). Upgrading to mupdf 0.6 fixes
the bindings.

- Removed the booklet feature gate — mupdf is now a direct dependency
  again, matching the v1.1.19 configuration
- Removed stub implementation (always compile real MuPDF backend)
- sys-lib-libjpeg remains excluded (cross-distro libjpeg incompatibility)

cc
2026-03-19 09:28:07 -06:00
vicrodh c2e9a4f0ba fix: replace broken screen resolution clamping with sane fallback
xdpyinfo returns combined multi-monitor resolution (e.g. 6000x1600 for
dual monitors), causing false positives like clamping 1926x1590 to
5700x1520. The 95% multiplier made things worse — the fallback size was
larger than any single monitor.

Replace with simple corruption guard: only clamp values above 8K
(obviously corrupt DB entries), fallback to 1920x1080. The window
manager already handles fitting windows to the actual display.

cc
2026-03-19 08:44:29 -06:00
vicrodh 2439b5f4d8 fix: remove KDE KWin SSD hack entirely (#170)
The KWin window rule approach (kwinrulesrc + qdbus reconfigure) was
never actually active because GDK_BACKEND is unset on most KDE Wayland
sessions. In v1.1.18 this meant decorations(use_system_titlebar) was
used directly — GTK CSD appeared (ugly but functional, no CPU issues).

The hack itself, when triggered, caused double titlebar and a CPU busy
loop that blocked networking. Remove all KDE-specific detection and
KWin rule setup. Window now simply uses decorations(use_system_titlebar)
on all platforms, matching the effective behavior of v1.1.18.

The one-time cleanup of stale kwinrulesrc entries is preserved so users
who had the rule from v1.1.14-v1.1.19 get it cleaned up automatically.

cc
2026-03-19 08:29:49 -06:00
vicrodh 8a8c709c1b feat: lock volume at 100% when ALSA Direct hw: is active
With ALSA Direct hw: there is no software mixer — volume must be
controlled at the DAC/hardware level. Software volume attenuation
would reduce bit depth and defeat the purpose of bit-perfect playback.

Backend: v2_set_volume forces volume to 1.0 when backend=Alsa+plugin=Hw
Frontend: volume slider disabled (grayed out at 100%), mute/step buttons
hidden, handleVolumeChange and handleToggleMute return early.
Settings callbacks notify +page.svelte when backend/plugin changes to
update the lock state in real-time.

i18n: volumeLockedHw tooltip added to all 5 locales.

cc
2026-03-19 00:10:59 -06:00