Commit Graph
131 Commits
Author SHA1 Message Date
vicrodh 65a0d523bb fix(qconnect): track active remote renderer state for skip and seekbar
cx
2026-03-13 11:55:48 -06:00
vicrodh 02155f54fe merge(pre-release): sync qconnect-poc-v3 with latest local integration state
cx
2026-03-12 15:23:32 -06:00
vicrodh df86363aac fix: add retry with fresh URL on CDN premature EOF
Root cause: Qobuz CDN returns "end of file before message length
reached" for specific tracks - sends Content-Length header then
closes connection without body data. Consistently reproducible for
certain tracks while others from the same album work fine.

Add retry logic at all download paths: on failure, request a fresh
stream URL from the API and retry once (CDN may route to different
edge). Streaming probe failures now fall back to standard download
path instead of failing completely. Also stream response body in
chunks for better partial-read diagnostics.
2026-03-11 20:41:58 -06:00
vicrodh a4a6722110 chore: bump version to 1.1.20 2026-03-11 12:53:13 -06:00
vicrodh 0eb0139418 fix: remove sys-lib-libjpeg from mupdf to fix startup on Debian/Fedora (#161, #162)
Ubuntu ships libjpeg8 (libjpeg.so.8) while Debian sid and Fedora ship
libjpeg62-turbo (libjpeg.so.62). Building with sys-lib-libjpeg on Ubuntu
hardcodes a dependency on libjpeg.so.8, breaking startup on other distros.

Let mupdf vendor its own libjpeg (statically linked) instead.
2026-03-11 08:01:25 -06:00
vicrodh 05f1a5ec13 chore: bump version to 1.1.19
- Cargo.toml, tauri.conf.json, package.json, snapcraft.yaml
- Regenerate Cargo.lock and package-lock.json
- Add metainfo release entry for 1.1.19
2026-03-09 00:35:42 -06:00
vicrodh 69aed4e1ad feat(notifications): migrate from notify-rust to ashpd XDG Portal
Replace direct D-Bus notifications (notify-rust) with XDG Desktop
Portal notifications (ashpd) for Flathub compliance. Portal
notifications use the app's .desktop file identity and don't require
--talk-name=org.freedesktop.Notifications permission.

- Replace notify-rust dep with ashpd (linux-only, tokio+notification)
- Use NotificationProxy for portal-based notifications
- Use stable ID "track-now-playing" to replace instead of stacking
- Convert artwork path to file:// URI via ashpd::Uri
- Graceful fallback when portal is unavailable
2026-03-03 22:25:59 -06:00
vicrodh b49d0b3e3b chore(release): bump version to 1.1.19-rc-1
cx
2026-03-01 18:59:24 -06:00
vicrodh faf8844584 chore: upgrade rodio 0.19 to 0.22, remove vendored rodio/cpal
Remove vendored rodio and cpal from src-tauri/vendor/ since rodio 0.22
now includes upstream f32 decoder support (our vendored modification).
Update all Cargo.toml files to use rodio 0.22 from crates.io and remove
the [patch.crates-io] section.
2026-02-28 07:48:03 -06:00
vicrodh bb723c7ca5 feat: switch booklet viewer from pdfjs-dist to MuPDF backend
Replace browser-side pdfjs-dist canvas rendering with server-side
MuPDF rendering for high-quality PDF booklet display. MuPDF renders
pages to PNG at configurable DPI in Rust, producing much sharper
results than the JavaScript canvas approach which had persistent
JPEG 2000 WASM decoder issues.

- Add mupdf crate with sys-lib features (avoid GTK symbol conflicts)
- Create pdf_viewer.rs with v2_booklet_open/render_page/close commands
- Download PDF to temp file, render pages on demand via MuPDF
- Display rendered PNGs as img tags instead of canvas
- DPI scales with zoom and devicePixelRatio for crisp output
- Support rotation via MuPDF transformation matrix
2026-02-28 07:48:03 -06:00
vicrodh 6d2128e90a chore: bump version to 1.1.18 2026-02-26 03:41:45 -06:00
vicrodh 1981771584 chore: bump version to 1.1.17 2026-02-23 17:59:24 -06:00
vicrodh 26db1c1728 chore(release): bump version to 1.1.15 2026-02-23 12:18:08 -06:00
vicrodh a0790f9a1d feat(qconnect-tauri): add runtime service bridging renderer commands to CoreBridge
cx
2026-02-21 12:54:06 -06:00
vicrodh 373220c379 chore(qconnect): register workspace crates and tauri adapter dependency
-cx
2026-02-21 12:17:30 -06:00
vicrodh 98ffd3dff2 chore: bump version to 1.1.15-rc-2 2026-02-19 16:57:19 -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 ba09345aa3 chore(release): prepare 1.1.15-rc-1 and beta checklist
cx
2026-02-17 20:13:30 -06:00
vicrodh 63994c0a20 refactor(cast): extract qbz-cast crate
Extract casting functionality (Chromecast, AirPlay, DLNA) to standalone
qbz-cast crate. This crate is Tauri-agnostic and can be used by TUI/CLI
clients.

- Move device connection, discovery, threading, and media server to crate
- Keep only Tauri commands in src-tauri/src/cast/
- Thin re-exports in src-tauri for backwards compatibility
- Remove duplicate dependencies from src-tauri Cargo.toml
2026-02-15 14:51:06 -06:00
vicrodh d6e4b3349b feat(qbz-library): extract local library management to standalone crate
Create qbz-library crate with:
- LibraryScanner: directory scanning for audio files
- MetadataExtractor: audio metadata extraction via lofty
- LibraryDatabase: SQLite persistence with WAL mode
- CueParser: CUE sheet parsing for single-file albums
- Thumbnails: artwork extraction and thumbnail generation
- Tag sidecar: album metadata override files

src-tauri re-exports from qbz-library for backwards compatibility.
Enables TUI/headless clients to manage local libraries without Tauri.
2026-02-15 12:12:52 -06:00
vicrodh 384459d4d7 feat(qbz-cache): extract audio caching to standalone crate
Create qbz-cache crate with:
- AudioCache: L1 in-memory LRU cache (~300MB)
- PlaybackCache: L2 disk-based cache (~500MB)
- LRU eviction with spillover from L1 to L2

src-tauri now re-exports from qbz-cache for backwards compatibility.
This enables TUI/headless clients to use caching without Tauri.
2026-02-15 11:27:38 -06:00
vicrodh 6310e9b216 chore: add qbz-integrations crate dependency
Wire qbz-integrations to src-tauri Cargo.toml. The crate provides
Tauri-independent implementations of Last.fm, ListenBrainz, and
MusicBrainz integrations.

Next step: Create V2 commands that use the new crate, then gradually
deprecate the existing in-tree implementations.
2026-02-15 11:05:33 -06:00
vicrodh d0e46aca05 feat(qbz-nix): Phase 6.1 - integrate extracted crates
Add dependencies on extracted crates and create TauriAdapter.

Changes:
- Add qbz-models, qbz-audio, qbz-player, qbz-qobuz, qbz-core as deps
- Add async-trait dependency for FrontendAdapter impl
- Create tauri_adapter.rs implementing FrontendAdapter
- TauriAdapter emits CoreEvents to frontend via Tauri event system

This is the first step of integration. The old modules still exist
but the new crates are now available for gradual migration.
2026-02-14 14:32:24 -06:00
vicrodh d3a4e4a688 Bump version to 1.1.14 for release
Changes since 1.1.13:
- Fix MPRIS dbus name to use appid (Flathub compliance)
- Fix SQLite WAL mode for all connections (UI lag fix)
- Add volume +/- step buttons in player bar
- Add playlist search in sidebar with folder auto-expand
- New playlist collage layout (3+1 grid)
2026-02-13 09:07:02 -06:00
vicrodh 008dfbcbb0 Bump version to 1.1.13 for Flathub submission 2026-02-12 15:12:07 -06:00
vicrodh f70000bbcc Bump version to 1.1.12 2026-02-12 14:32:52 -06:00
vicrodh 700183b0bb fix: prevent multiple instances when reopening from desktop icon
Cherry-picked from main (c163435b)

cc
2026-02-12 09:46:03 -06:00
vicrodh d6e9375333 chore: bump version to 1.1.11 2026-02-10 08:00:42 -06:00
vicrodh a7409bfdd4 chore: bump version to 1.1.10 2026-02-10 02:17:48 -06:00
vicrodh 3e4cc6921c Add developer settings backend, log capture system, and --reset-dmabuf CLI flag
Developer settings: SQLite-backed store for force_dmabuf toggle.
Logging: TeeWriter captures env_logger output to ring buffer;
log_startup() captures pre-logger startup messages.
Upload: multipart POST to 0x0.st for log sharing.
CLI: --reset-dmabuf flag resets force_dmabuf and exits for recovery.
2026-02-08 15:00:58 -06:00
vicrodh eaacc9e3a7 feat(audio): add real-time EBU R128 volume normalization (Phase 2)
Replace static ReplayGain-only normalization with real-time loudness
analysis that works with any audio source including Qobuz streams.

New components:
- DynamicAmplify: Source wrapper that reads gain from shared atomic
  with 50ms linear ramp to prevent clicks on gain changes
- AnalyzerTap: Source wrapper that batches samples and sends them
  to the analyzer thread via bounded channel (never blocks audio)
- LoudnessAnalyzer: Background thread computing EBU R128 integrated
  LUFS, first measurement at ~10s, refinement every ~5s
- LoudnessCache: SQLite persistence for computed LUFS values so
  replayed tracks get instant gain application

Pipeline when normalization ON:
  Decode -> Diagnostic -> AnalyzerTap -> DynamicAmplify -> Visualizer

Pipeline when normalization OFF (bit-perfect, unchanged):
  Decode -> Diagnostic -> Visualizer

Re-enable normalization toggle in NowPlayingBar UI.
2026-02-08 08:24:51 -06:00
vicrodh 3f18378c13 bump version to 1.1.9 2026-02-07 01:52:38 -06:00
vicrodh 6d49e2ce5a chore: bump version to 1.1.8 2026-02-04 20:48:22 -06:00
vicrodh 94c867c934 chore: bump version to 1.1.8-rc-6 for workflow testing 2026-02-04 18:46:58 -06:00
vicrodh 2818ac4d29 security: improve credential encryption and CORS configurability
Security improvements based on code review:

1. Credential Encryption (Critical)
   - Replace XOR obfuscation with AES-256-GCM encryption
   - Derive key from machine ID (tied to specific machine)
   - Add migration support for legacy XOR format
   - Automatic re-encryption on first load of legacy credentials

2. HTTPS Default (Medium)
   - Change default `secure` setting to `true` for new installs
   - Existing users keep their current setting

3. Configurable CORS Origins (High)
   - Replace hardcoded domain whitelist with SQLite-backed storage
   - Default origins: vicrodh.github.io, control.qbz.lol
   - Add commands: get/add/remove origins, restore defaults
   - Origins can be customized for third-party clients
   - Server restarts automatically when origins change

New dependencies:
   - aes-gcm: AES-256-GCM authenticated encryption
   - sha2: SHA-256 for key derivation
2026-02-03 12:36:18 -06:00
vicrodh 1039241d28 feat(api): add SSE endpoint for real-time playback updates
Add /api/events endpoint using Server-Sent Events (SSE) as a more
efficient alternative to WebSocket for pushing playback state updates
to PWA clients. SSE provides automatic reconnection and is simpler
to implement on the client side.

- Add tokio-stream dependency with sync feature for BroadcastStream
- Implement sse_handler with 15s keep-alive ping
- Keep /api/ws for backwards compatibility
2026-02-03 10:57:16 -06:00
vicrodh 651d0b0792 chore: bump version to 1.1.8-rc-5 2026-02-03 08:28:34 -06:00
vicrodh 4d2227cb5b fix(remote-control): initialize rustls provider
cx
2026-02-03 04:55:22 -06:00
vicrodh 229d24f891 feat(remote-control): add HTTPS mode and cert flow
cx
2026-02-03 04:48:23 -06:00
vicrodh 363ca4c264 feat(remote-control): add LAN API server, settings UI, and QR pairing\n\n- add axum API server with LAN-only + token auth + CORS allowlist\n- expose playback and search endpoints plus WS updates\n- persist remote control settings (enabled/port/token)\n- add settings UI with QR/token controls and i18n\n\ncx 2026-02-03 03:47:48 -06:00
vicrodh b8cfcfb34a Add audio visualizer backend infrastructure
- Add spectrum-analyzer crate for FFT processing
- Create visualizer module with:
  - RingBuffer: lockless SPSC buffer for audio samples
  - FFT processor: dedicated thread for spectrum analysis
  - TappedSource: rodio Source wrapper for sample capture
  - VisualizerTap: shared state for audio thread integration
- Add Tauri commands: set_visualizer_enabled, is_visualizer_enabled
- Register visualizer in AppState and lib.rs

Backend compiles. Next: integrate with audio thread to capture samples.
2026-02-01 15:07:21 -06:00
vicrodh 1d2e28c1a8 feat(vectors): add sparse vector foundation for playlist suggestions
Phase 1 of playlist-suggestions feature:
- SparseVector: memory-efficient vector with math operations
  - set/get with sorted indices for O(log n) access
  - add, sub, scale, dot product, magnitude
  - normalize, cosine_similarity, top_k_similar
- ArtistVectorStore: SQLite persistence
  - artist_index table: MBID to integer index mapping
  - vector_entries table: sparse representation (one row per non-zero)
  - vector_metadata table: track freshness with TTL
  - find_nearest: cosine similarity search with exclusion
- 17 unit tests all passing
2026-01-27 11:19:55 -06:00
vicrodh b3117cc7c2 Bump version to 1.1.7 2026-01-27 04:58:28 -06:00
vicrodh fbc1938838 feat: compare studio albums only when matching artists
When comparing "X" vs "The X" variants, now fetches actual albums
and counts only studio albums (main discography) instead of total
album count. This filters out:
- Tributes (albums by other artists)
- Compilations (greatest hits, best of)
- Unofficial releases (bootlegs, broadcasts)
- Live albums
- EPs and singles

Uses the same categorization logic as the frontend (qobuzAdapters.ts).
This provides cleaner matching, e.g., "The Beatles" with 200+ studio
albums vs "Beatles" tribute compilation with 2 albums.
2026-01-25 23:08:46 -06:00
vicrodh e5779ce6cf feat(backend): Add playlist folders Phase 1 - database and Tauri commands
- Add uuid crate dependency for folder ID generation
- Add PlaylistFolder struct and database schema
- Add folder_id field to PlaylistSettings
- Add database migration for existing installations
- Add CRUD methods for playlist folders:
  - create_playlist_folder
  - get_all_playlist_folders
  - get_playlist_folder
  - update_playlist_folder
  - delete_playlist_folder
  - reorder_playlist_folders
  - move_playlist_to_folder
  - get_playlists_in_folder
- Register Tauri commands for frontend integration
2026-01-24 23:15:48 -06:00
vicrodh fc03bee9b1 feat(thumbnails): add backend thumbnail generation system 2026-01-23 01:07:16 -06:00
vicrodh 2a8b7c6d55 feat: Qobuz™ compliance, subscription gating, and settings cleanup
cx
2026-01-22 10:33:45 -06:00
vicrodh 6260b2f66c chore: Bump version to 1.1.6 for release 2026-01-20 22:00:40 -06:00
vicrodh 4748cef7df chore: Bump version to 1.1.6-rc and add ARM64 workflow
- Update version to 1.1.6-rc for release candidate testing
- Add Linux ARM64/aarch64 build workflow
- Uses ubuntu-24.04-arm GitHub runner (free for public repos)
- Builds .deb, .rpm, .AppImage, and AUR tarball for ARM64
- Workflow isolated with continue-on-error to not block x86_64 builds
2026-01-20 16:04:35 -06:00
vicrodh c749b7d932 chore: Update tauri-plugin-dialog to 2.6.0
Fixes version mismatch warning between Rust crate (2.5.0) and
NPM package (@tauri-apps/plugin-dialog 2.6.0)
2026-01-20 14:34:18 -06:00