Commit Graph
4860 Commits
Author SHA1 Message Date
vicrodh 2e47fbb544 fix(qbz-slint): pin section row height to the card height
The album card now has a fully deterministic 266px height (artwork 220
+ 6 spacer + 40 meta, with fixed-height title and artist text). The
section row's ScrollView pins viewport-height to its height, so the
vertical scroll range is zero — the row can no longer scroll
vertically, even invisibly.

cc
2026-05-18 13:32:10 -06:00
vicrodh 7801478819 fix(qbz-slint): match current QBZ Discover Home
Corrections from testing feedback:
- Remove the greeting — the current QBZ discovery view has no greeting,
  only the tab selector. Drops HomeState.greeting and the chrono dep.
- Quality badge is now the icon-only badge (hi-res.svg, or cd.svg in a
  framed square), not a numeric text pill. AlbumCardItem carries a
  quality tier instead of a quality string.
- Tighten the album card: deterministic 274px height, title and artist
  in a 2px-spaced stack — removes the large gap between them.
- SectionRow no longer scrolls vertically (vertical-scrollbar-policy
  always-off, height pinned to the card height).
- Artwork is downscaled to 264px on decode instead of holding ~600px
  source textures.

cc
2026-05-18 13:20:52 -06:00
vicrodh e2e409cf93 feat(qbz-slint): album artwork pipeline
Discover cards now show real Qobuz cover art. Artwork is fetched and
decoded off the UI thread, capped at 16 concurrent downloads, and each
result is applied to its own card row on the Slint event loop — so a
cover arriving never resets a section.

- artwork.rs: download + decode worker and per-row apply.
- AlbumCardItem gains an `artwork` image field; AlbumCard overlays the
  cover, falling back to the elevated placeholder until it resolves.
- main.rs: after the discover sections render, artwork jobs are spawned
  for every card with an image URL.

qbz-slint now depends on reqwest and image.

cc
2026-05-18 13:05:12 -06:00
vicrodh 8246ad5dd6 feat(qbz-slint): real Discover Home view
After sign-in the app loads the real Qobuz discover index and renders
the Home view: a time-based greeting with the user's name, the tab
pill (Home / Editor's Picks / For You), and discover sections — New
Releases, Press Accolades, Ideal Discography, Qobuzissimes, Albums of
the Week — each a horizontally scrolling row of album cards.

- state.slint: AlbumCardItem / DiscoverSection structs, HomeState global.
- discover/: AlbumCard (artwork area, award ribbon, title, artist,
  quality badge), SectionRow, HomeView.
- home.rs: discover-index fetch and mapping (award-ribbon priority,
  quality string), greeting, and event-loop model application. Unit
  tests for ribbon, quality, and greeting logic.
- AppShell content region is now the HomeView.

Album artwork images load in the next increment (artwork pipeline);
cards currently show the elevated placeholder. No fixtures — all data
is the live discover index.

cc
2026-05-18 13:01:45 -06:00
vicrodh 03b9a1c528 feat(qbz-slint): functional system-browser OAuth login
Wires real authentication. "Sign in via Browser" now runs the actual
Qobuz OAuth flow with no Tauri and no WebView: opens the system
browser, captures the authorization code on a one-shot localhost
listener, exchanges it via QbzCore's Qobuz client, and activates a
real per-user session through AppRuntime.

- adapter.rs: SlintAdapter implements FrontendAdapter.
- auth.rs: system-browser OAuth, mirrors v2_start_system_browser_oauth
  without Tauri. Includes a query-param parse test.
- main.rs: tokio runtime; sign-in / offline callbacks run real async
  work and navigate to the shell on success.
- Sidebar: placeholder playlist fixtures removed.

qbz-slint now depends on qbz-app, qbz-core, and qbz-models.

cc
2026-05-18 12:48:13 -06:00
vicrodh 7535869e61 feat(qbz-slint): app shell frame
M1 progress. Adds the post-login shell: HeaderBar (nav tabs and
search), Sidebar (playlists list and user card), PlayerBar (transport,
now-playing, volume), and AppShell composing them with the content
region as a placeholder.

app.slint gains an AppScreen enum; clicking sign-in or start-offline
navigates login -> shell (no real auth yet — that is M2). New layout
foundation tokens (sidebar width, header/player-bar heights) plus
border and hover semantic colors.

cc
2026-05-18 12:34:01 -06:00
vicrodh d5be0029b6 feat(qbz-slint): foundation tokens and login screen
M1 progress. Adds the foundation token layer (palette, semantic
colors, spacing, radius, typography) bound to the QBZ dark theme,
three primitives (QbzCheckbox, QbzPrimaryButton, QbzTextLink), and
the LoginScreen feature component.

The login screen mirrors the Svelte LoginView: centered card, logo,
QBZ wordmark, Qobuz ToS checkbox, "Sign in via Browser" button,
system-browser and offline links, and the legal disclaimer. Colors
are lifted verbatim from src/app.css; strings use @tr() markers.

Rust side: typed AppCommand enum; UI callbacks dispatch through it.
M2 wires the command handler to AppRuntime.

cc
2026-05-18 12:13:52 -06:00
vicrodh f1748383a5 feat(qbz-slint): scaffold Slint POC crate
First increment of M1 of the Slint functional POC. Adds the qbz-slint
workspace member: Slint 1.x dependency, build.rs compiling ui/app.slint,
a minimal AppWindow, and the binary entry point.

Verifies the Slint toolchain builds in this environment before the
foundation layer (tokens, shell, theme, i18n, typed commands) lands.

Private slint-poc branch only (ADR-007).

cc
2026-05-18 11:57:49 -06:00
vicrodh 196fa796f5 Merge refactor/qbz-app-session-activation: minimal session activation
cc
2026-05-18 09:35:55 -06:00
vicrodh 7ef6300a22 refactor(qbz-app): add minimal session activation to AppRuntime
Task 2 of the Slint POC readiness audit. AppRuntime now performs
framework-agnostic per-user session activation: activate, activate_at,
activate_offline, deactivate, plus is_session_active, active_user_id,
and a with_session_store accessor.

This is the minimal version per the 2026-05-18 audit correction. It
opens only the session store and does the portable scaffolding (user
paths, directories, last_user_id marker, runtime state machine). It
does not touch Tauri's session_lifecycle, does not initialize the
src-tauri-side per-user stores, and does not run the flat-to-user
migration. The shipping app keeps identical behavior; this is additive.

activate_at takes explicit directories and is the testable core;
activate resolves real per-user paths through UserDataPaths.

cc
2026-05-18 09:26:22 -06:00
vicrodh f979c52307 Merge refactor/qbz-app-shell-facade: shell facade skeleton
cc
2026-05-18 08:29:01 -06:00
vicrodh a213b37807 refactor(qbz-app): add AppRuntime shell facade skeleton
Adds a framework-agnostic composition root for non-Tauri UI shells
(Slint, TUI, headless) as Task 1 of the Slint POC readiness audit
(session-20-slint-poc-readiness-audit).

AppRuntime<A> owns an Arc<QbzCore<A>> plus the runtime state machine,
built with the same recipe as the Tauri CoreBridge but with no Tauri
dependency. Scope is composition and accessors only; per-user store
ownership and session activation are deferred to Task 2.

qbz-app now depends on qbz-core, qbz-player, qbz-audio, and qbz-models.
The Tauri app does not consume this module; it is purely additive.

cc
2026-05-18 07:28:19 -06:00
vicrodh d4ea8b01a7 Merge refactor/qbz-app-playback-context: playback context foundation 2026-05-17 20:14:54 -06:00
vicrodh 1052ff25b3 refactor(tauri): use qbz-app playback context
cx
2026-05-17 19:42:53 -06:00
vicrodh f79c550889 refactor(qbz-app): add playback context
cx
2026-05-17 19:39:14 -06:00
vicrodh 2ed2a30a2c Merge refactor/qbz-app-session-store: session store foundation 2026-05-17 19:30:34 -06:00
vicrodh 8b850999f9 refactor(tauri): use qbz-app session store
cx
2026-05-17 19:19:47 -06:00
vicrodh 4ba96fe59a refactor(qbz-app): add session store foundation
cx
2026-05-17 19:16:13 -06:00
vicrodh ba7cf05b6f chore: bump Nix flake hashes for v1.2.13
Update srcHash and npmHash to point at the v1.2.13 tag. qbzVersion was
already bumped during the release version bump.

cc
2026-05-17 16:38:27 -06:00
vicrodh d647268af8 fix: play individual tracks from expanded Mixtape items
Clicking a track inside an expanded Mixtape/Collection item now plays
it. Qobuz albums and playlists build the queue directly; Plex and
local-library albums delegate to the backend collection-item resolver,
then jump the queue cursor to the clicked track.

cc
2026-05-17 13:15:32 -06:00
vicrodh 3a22cbdbd5 fix: show playlist tracks and version in expanded Mixtape items
Expanded playlist items showed "No results found"; fetch their tracks
via v2_get_playlist. Also carry the remix/edition version field so
titles render consistently.

cc
2026-05-17 13:15:32 -06:00
vicrodh 6cb9284968 fix: pass remix/edition version metadata from playlists (#443)
Carry the track version field through PlaylistDetailView so remix and
edition subtitles reach the now-playing bar and queue views.

cc
2026-05-17 13:15:32 -06:00
vicrodh d9d6caae55 feat: include playback preferences in diagnostics snapshot
Add playback/audio/graphics settings to the diagnostics snapshot via
v2_get_playback_preferences. No sensitive data (no username or paths);
gated by the existing diagnostics opt-in toggle.

cc
2026-05-17 13:15:32 -06:00
vicrodh 74d75f3fbf fix: persist session durably to survive reboot (#440)
Switch the session store SQLite connection from synchronous=NORMAL to
synchronous=FULL. With WAL + NORMAL the last writes can sit unsynced in
the WAL and be lost on a hard reboot / power loss, dropping the restored
session.

cc
2026-05-17 13:15:32 -06:00
vicrodh 813892d605 Merge pre-release: 1.2.13 (400+ stars)
cc
2026-05-16 19:28:22 -06:00
vicrodh 3dac920187 fix(cast): suspend Qobuz Connect while casting (#439)
Qobuz Connect renderer mode and casting are mutually exclusive output modes. While qbz is registered as a QConnect renderer, the Qobuz cloud drives playback through the renderer-command path, which bypasses the cast path entirely — the cast device receives no LOAD and stays silent.

connectToDevice() now checks QConnect status and, if it is on, suspends it (v2_qconnect_disconnect) before connecting the cast device. When the cast ends, disconnect() restores QConnect only if it was on beforehand; a failed cast connection restores it too. Applies to Chromecast and DLNA alike.

Fixes #439.

cc
2026-05-16 18:59:34 -06:00
vicrodh 59990fdc35 docs(release): add 1.2.13 release notes and full changelog
TAG_DETAILS.md is the curated, user-facing release summary rendered by the website and the in-app About modal. CHANGELOG_FULL.md is the complete commit list for v1.2.12..v1.2.13, restoring the two-file release-docs layout last used at 1.2.5.

cc
2026-05-16 14:40:09 -06:00
vicrodh c747c72e9d chore(release): bump version to 1.2.13 "400+ stars"
Version bumped across Cargo.toml, tauri.conf.json, package.json, snapcraft.yaml (version + source-tag), flake.nix, and the lockfiles. metainfo.xml gains a 1.2.13 release entry, the About modal codename becomes "400+ stars", and the README contributors list adds @Vudgekek and @DoubleGate.

cc
2026-05-16 14:40:09 -06:00
vicrodh bfcd769055 fix(cast): heartbeat the Chromecast every 5s to keep the connection alive
Google Cast closes a control connection that goes roughly 10 seconds without a heartbeat PING. QBZ pinged every 25 seconds, so any cast connection left idle between connect and load — for example while the track downloads, or across a delayed second play attempt — was dropped by the receiver. The next LOAD then failed with EPIPE (broken pipe): the device chimed on connect but never played audio, and the heartbeat thread logged repeating broken-pipe warnings.

Pinging every 5s is the cadence the Cast protocol expects and keeps the connection alive through those idle gaps.

Fixes #439.

cc
2026-05-16 14:38:29 -06:00
vicrodh bf734546d1 Merge bugfix/pre-1.2.13: graphics recommendation cleanup, faster track resume
cc
2026-05-16 13:53:24 -06:00
vicrodh 3abb7f66cb fix(playback): gate within-track resume on cache, drop slow seek path
Session resume of a Qobuz track no longer forces the streaming start-position path, which buffered the CMAF stream sequentially from byte 0 up to the saved offset (up to ~30s wait, with no buffering indication).

v2_play_track is now always called without a start position. The track resumes at the saved offset only on a cache hit (format_id === null), where the audio is a full in-memory buffer and Seek lands like a local file. On a cache miss it starts from 0:00 instead of blocking on a sequential buffer fill.

No backend or audio-engine change; the start_position_secs streaming path is now unused.

cc
2026-05-16 13:53:17 -06:00
vicrodh 3d29cf1384 fix(graphics): make recommendation advisory-only, GPU-aware DMA-BUF help
The graphics recommendation banner no longer writes settings: the Apply button and the v2_apply_graphics_recommendation command are removed, so the banner only detects and explains. The user applies the change with the real toggles, matching the HiFi Wizard's advisory model. write_recommendation stays for the qbz --autoconfig-graphics CLI.

The Force DMA-BUF help text is now GPU-aware: the instability warning only shows on NVIDIA-only systems; non-NVIDIA and hybrid hosts are told it is safe to enable. On hybrid hosts the rendering GPU dropdown marks the integrated GPU as recommended.

cc
2026-05-16 12:22:41 -06:00
vicrodh 29b766ae24 fix(graphics): recommend CPU for NVIDIA-only, allow DMA-BUF on hybrid
NVIDIA-only systems no longer get a hardware-acceleration recommendation that visibly stutters under WebKitGTK. The three NVIDIA-only branches (Wayland+GNOME, Wayland, X11) collapse into one CPU-rendering profile, since XWayland does not rescue the stutter either.

NVIDIA + iGPU hybrid now allows DMA-BUF: WebKit composites on the stable iGPU stack, so the instability that affects NVIDIA-only systems does not apply. The recommendation also tells the user to pick the iGPU explicitly in the rendering GPU selector instead of Auto.

cc
2026-05-16 12:22:41 -06:00
vicrodh f02e19258b Merge branch 'pre-release' into bugfix/pre-1.2.13 2026-05-16 10:16:42 -06:00
vicrodh 420fd4d286 Merge refactor/qbz-app-boot-watchdog: boot watchdog
cx
2026-05-16 09:37:18 -06:00
vicrodh 1a5dbe07bb refactor(qbz-app): extract boot watchdog decision
cx
2026-05-16 09:04:34 -06:00
vicrodh fbf3a5a17c Merge refactor/qbz-app-graphics-autoconfig: graphics autoconfig
cx
2026-05-16 08:57:21 -06:00
vicrodh 3c963cdaf3 refactor(qbz-app): extract graphics autoconfig
cx
2026-05-16 08:50:06 -06:00
vicrodh f457401dd9 Merge refactor/qbz-app-graphics-detection: graphics detection 2026-05-16 00:49:21 -06:00
vicrodh dceeacb57e refactor(tauri): use qbz-app graphics detection
cx
2026-05-16 00:47:11 -06:00
vicrodh 2fc9270c89 refactor(qbz-app): add graphics detection
cx
2026-05-16 00:44:16 -06:00
vicrodh 2beb83cbb6 Merge refactor/qbz-app-user-data-paths: user data paths 2026-05-16 00:29:17 -06:00
vicrodh b65feee511 refactor(tauri): use qbz-app user data paths
cx
2026-05-16 00:24:03 -06:00
vicrodh a497d61b75 refactor(qbz-app): add user data paths
cx
2026-05-16 00:20:21 -06:00
vicrodh e4ec5cd318 Merge refactor/qbz-app-developer-settings: developer settings store 2026-05-15 23:25:22 -06:00
vicrodh be500956ff refactor(qbz-app): add developer settings store
cx
2026-05-15 23:25:06 -06:00
vicrodh 1fe0ac3568 Merge refactor/qbz-audio-settings-foundation: audio settings store 2026-05-15 23:19:10 -06:00
vicrodh 87e426ab5d refactor(tauri): use qbz-audio settings
cx
2026-05-15 19:51:13 -06:00
vicrodh f85df353ca refactor(qbz-audio): align audio settings store
cx
2026-05-15 19:42:17 -06:00
vicrodh c4a0a52ab4 Merge refactor/qbz-app-graphics-settings: graphics settings store 2026-05-15 19:22:23 -06:00