Commit Graph
1561 Commits
Author SHA1 Message Date
vicrodh 42b9e39992 feat(qbz): wire settings export modal to the bundle engine (04 §4.2)
SettingsExportActions.confirm() -> settings::export_settings: read the
include-auth gate, close the modal, then off the event loop build the bundle
via qbz_app::settings::bundle::export(ExportSource::Desktop, ..) (no new
export logic), open a native rfd save dialog seeded with
qbz-settings-YYYYMMDD.qbzb, write it 0600 via write_bundle_file, and toast
the "qbzd settings import <file>" step. Errors surface a toast; cancel is a
no-op.

cc
2026-07-15 07:50:27 -06:00
vicrodh 897ba7128c feat(qbz-ui): settings export modal + Developer row (04 §4.2)
Add the desktop "Export settings…" surface for the qbzd daemon epic (T18):
a Developer-settings row that opens a modal with the single default-off
"Include Qobuz login and integration tokens" gate, its warning line, and a
Cancel/Export footer. Confirm() is a Rust callback (wired next). New
SettingsExportState/SettingsExportActions globals, exported from app.slint
so the Rust layer binds them, and the modal mounted in AppShell. New strings
translated across all 8 locales (en es de fr pt ru ja nl).

cc
2026-07-15 07:50:27 -06:00
vicrodh d658a501ad fix(qbzd): store I/O failures in settings set exit 1 not 2
cc
2026-07-14 22:04:11 -06:00
vicrodh 722a0207ec fix(qbzd): latch network.online from real network-class outcomes
cc
2026-07-14 21:59:50 -06:00
vicrodh 47081b7666 fix(qbzd): drop qconnect control handle before device release in shutdown
cc
2026-07-14 21:54:55 -06:00
vicrodh 39eb12fc45 feat(packaging): ship qbzd binary and user unit in deb/rpm and tarball
cc
2026-07-14 21:02:34 -06:00
vicrodh 80a20f4322 fix(qbzd): land setup on menu when credentials exist, use multiplication sign in size warning
cc
2026-07-14 20:56:22 -06:00
vicrodh a1fbbafc79 feat(qbzd): ratatui setup TUI, six screens with explicit-save semantics
Implements owner requirement 2 (03-setup-tui.md): `qbzd setup`, a six-screen
raspi-config-grade configurator over the daemon's real stores — zero new
persistence. ratatui 0.30 (IV5: unifies on the lock's unicode-width 0.2.2;
0.29 forbidden). A synchronous event loop on a blocking thread; disk/HTTP only
at screen entry, `r`, save and the immediate actions, on workers with a spinner
(no I/O on keystrokes). Non-tty exits 2 with the verbatim copy; alt-screen +
panic-hook restore.

Screens: Account (T5 login engine; inline masked token paste, suspend-and-run
browser login, logout confirm), Audio (the §3.2.3 constraint matrix + 7
cascades verified 1:1 vs the desktop code, device picker re-deriving the
§3.2.2 grouping/BP-badge rules, DSD guard), Playback (ask->fallback rule,
infinite-radio read-only), QConnect (startup/name/volume_mode, live preview),
Network (whole-file qbzd.toml rewrite preserving every key), Import/Export
(pure renderer of the T12 bundle plan; interactive device re-pick; default-off
auth gate). Saves reuse T11 write_one + reload/status classification (§4.3);
dirty marker + Save/Discard/Stay. All user-facing strings centralized.

cc
2026-07-14 20:42:42 -06:00
vicrodh 8021393925 fix(qbzd): mask secret values in import summary and distinguish reload refusal
cc
2026-07-14 19:58:31 -06:00
vicrodh 0b7cd6c5e3 feat(qbz-app): settings bundle engine with importer-side classification
Export/import CLI on qbzd; requirements 4 and 5 complete with zero desktop builds.

cc
2026-07-14 19:44:01 -06:00
vicrodh a864aa8d55 feat(qbzd): settings reload endpoint and settings/qconnect/config CLI verbs
Route table complete: 17 P0 routes, CI-counted.

cc
2026-07-14 19:02:10 -06:00
vicrodh 6fa0428127 fix(qbzd): pin player volume to 100 percent at connect in locked volume mode
cc
2026-07-14 18:27:43 -06:00
vicrodh adccb98e76 feat(qbzd): report tick, daemon device identity, volume modes and queue persistence
cc
2026-07-14 18:14:52 -06:00
vicrodh 196f167873 feat(qbzd): copy QConnect glue with TODO(converge) markers and daemon trait impls
Real-volume join report and reconnect credential re-resolution are daemon-copy
fixes; desktop call sites untouched (OD2).

cc
2026-07-14 17:47:33 -06:00
vicrodh 05e2216acc fix(qbzd): strict queue payload parsing, history in queue response, honest race comment
cc
2026-07-14 17:19:44 -06:00
vicrodh 92c49e648b feat(qbzd): queue routes and CLI verbs with server-side track materialization
cc
2026-07-14 17:05:15 -06:00
vicrodh 393a6e01a7 fix(qbzd): serialize volume canonically in JSON responses
cc
2026-07-14 16:49:20 -06:00
vicrodh e700084f0b feat(qbzd): playback routes and transport CLI verbs with full advance ritual
cc
2026-07-14 16:35:21 -06:00
vicrodh dd63b18ae9 fix(qbzd): treat empty [server] token as unset
cc
2026-07-14 16:10:34 -06:00
vicrodh 286cb51957 feat(qbzd): tiny_http control plane, Origin shield + opt-in token, ping/info/status and CLI diagnostics
cc
2026-07-14 15:59:17 -06:00
vicrodh 9597573a61 fix(qbzd): bind login nonce into the redirect path instead of relying on state echo
cc
2026-07-14 15:26:56 -06:00
vicrodh 66c9acfa86 feat(qbzd): login via one-shot nonce-bound listener, paste and token paths
Port the desktop system-browser OAuth (crates/qbz/src/auth.rs) into the daemon
CLI with three daemon-specific changes: the one-shot listener binds an ephemeral
port (never the control-API port, D6), a CSPRNG state nonce binds the callback,
and the command only validates + persists the token into the daemon root then
best-effort nudges a running daemon. Adds validate_token / login_browser /
login_paste / login_with_token_arg / nudge_reload plus logout; no email+password
surface anywhere. cli/copy.rs carries the verbatim 02 §2.2 timeout, success and
logout strings.

cc
2026-07-14 15:13:07 -06:00
vicrodh 8534a02f0d test(qbz-app): pin duration==0 end-detection edge in playback driver
cc
2026-07-14 14:22:02 -06:00
vicrodh 297bbad326 feat(qbz-app): headless playback driver with pure plan_tick and thin IO shell
cc
2026-07-14 14:09:22 -06:00
vicrodh 4d0f52138a feat(qbzd): headless runtime bring-up with daemon-root stores and credential restore
Adds additive _at credential fns (crypto/format untouched), DaemonAdapter
broadcast bus, numbered boot per 01 §8.1 incl. the #521 shutdown pair.

cc
2026-07-14 13:40:49 -06:00
vicrodh 18a10d14d9 fix(qbzd): warn on config-dir create/chmod failure instead of silent discard
cc
2026-07-14 13:18:30 -06:00
vicrodh d911f43856 feat(qbzd): qbzd.toml with unknown-key warning, flock instance lock, daemon_prefs store
cc
2026-07-14 13:10:08 -06:00
vicrodh 02c2dba68d feat(qbzd): scaffold slint-free qbzd crate with clap verb tree and CI gate
IV6 build peak: 795 MB max RSS (summed across the cargo-capped build's
process tree via /proc VmRSS polling; /usr/bin/time -v is not installed
on this box). aws-lc-rs in graph: 0 (single rustls provider: ring
v0.17.14 throughout).

cc
2026-07-14 12:53:09 -06:00
vicrodh 90d9d1c66a fix(themes): Catppuccin Latte is a light theme, not dark
PR #612 added the three Catppuccin flavors but grouped all of them under ThemeCategory::Dark. Latte is the LIGHT flavor (its palette already builds light via bg_is_light); move it to the Light category arm so the theme picker groups it correctly. Frappé/Macchiato stay Dark.

cc
2026-07-14 11:19:32 -06:00
Victor RH 771f1a29fb Merge pull request #612 from TerminalTilt/add-catppuccin-themes
feat(themes): add Catppuccin Latte, Frappé, and Macchiato
2026-07-14 11:18:42 -06:00
Afonso Jorge Ramos 96672a459d fix(log): stop logging Last.fm auth token prefixes
Request-token material must never appear in support log bundles.
2026-07-14 13:33:04 +02:00
vicrodh 6ff4c3449c fix(discover): expose Most Played globals to Rust + plays in all AlbumCardItem inits
Two build breaks from the View-all work: (1) MostPlayedAlbumsState/Actions were export global in state.slint but not re-exported from the app.slint entry, so slint codegen never emitted their Rust bindings — added them to the app.slint export list (verified: the generated app.rs now defines both). (2) adding plays to AlbumCardItem forced every Rust struct literal to set it — added plays: 0 to the six construction sites (album_map/artist/external_reco/foryou/home/search); most_played_item overrides it after card_to_item. slintcheck's .slint validation can't catch the export-list gap (it only bites when the qbz crate consumes the generated types), hence the miss.

cc
2026-07-14 02:30:49 -06:00
TerminalTilt 5aae3e0b59 feat(themes): add Catppuccin Latte, Frappé, and Macchiato
Adds the remaining three Catppuccin flavor palettes to complete the set:
- Latte (light)
- Frappé (dark)
- Macchiato (dark)

All colors transcribed from the official Catppuccin palette.
Themes follow the existing StdSpec builder pattern and are fully
integrated into the theme registry and UI.
2026-07-14 03:36:13 -04:00
vicrodh 9e7d574be0 feat(discover): Most Played Albums View-all page with search + play count
Full-page listing opened from the rail's View all (both tabs now wire show-view-all -> HomeActions.open-most-played-albums). New MostPlayedAlbumsView (mirrors RecentAlbumsView) with a search box; AlbumCardItem gains a plays field shown ONLY here (a gated line in AlbumCard). Rust: navigate_most_played_albums loads all_albums(), caches the ranked rows, renders the grid + fires artwork (MostPlayedAlbumsPage target, Qobuz vs Plex/local split); the search box re-filters the cached rows by title/artist and re-renders (mirrors the Qobuz-playlists filter). NavEntry::MostPlayedAlbums + AppShell mount + ContentView variant. Count label in 8 locales. slintcheck green; qbz-crate Rust pending a full build (30GB wall).

cc
2026-07-14 01:21:36 -06:00
vicrodh 1a7853d9c6 feat(discover): Most Played Albums carousel in Home + For You
Wires the rail (top-20 by play count) into both tabs, mirroring the favoriteAlbums pattern: HomeState/ForYouState.most-played-albums DiscoverSection; foryou::most_played_album_cards maps the ranked rows onto AlbumCard; home.rs builds it inline (local, no fetch) and For You rides the favorites branch; HomeMostPlayedAlbum/ForYouMostPlayedAlbum artwork targets + apply arms; render arms in HomeView/ForYouView (self-hide while empty); title in 8 locales. slintcheck green. View-all page (search + play count) is the next increment.

cc
2026-07-14 01:06:54 -06:00
vicrodh abb529e22b feat(discover): Most Played Albums — play-count store, hook, section id
Data foundation for the new Most Played Albums rail. New qbz-app store album_play_history (SQLite, mirrors play_history): one album_play_event row per track-start + an album_meta side table; top_albums(n)/all_albums() rank by COUNT(*) GROUP BY album_id, tie-broken by most-recent play. Hooked in playback::record_recent next to the recently/artist stores, same album identity. Registers the mostPlayedAlbums section id in discover_prefs (Home + For You, default off). The Qobuz API exposes no most-played endpoint (verified vs the inferred OpenAPI), so the ranking is local. 15 unit tests green (store 5 + prefs 10).

cc
2026-07-13 23:30:28 -06:00
vicrodh bf29892aa4 fix(dsd): DsdErrorReport holds SharedState, not Arc<SharedState>
The merged #599 typed DsdErrorReport.state as Arc<SharedState>, but the audio thread passes thread_state — a SharedState, which is itself a #[derive(Clone)] handle of Arc<Atomic..> fields (a clone already shares the state). The extra Arc broke the qbz-player build in the combined pre-release (E0308 at the four DoP / native-DSD wrap sites), failing the test-crates CI. Switches the field + new() to SharedState and drops the now-redundant Arc::new in the two DSD tests. Verified with scripts/cargo-test.sh (workspace, no UI): all crates green.

cc
2026-07-13 21:15:22 -06:00
vicrodh 8c50c16faa fix(offline): clarify that Clear cache keeps downloaded albums
After #606 the offline Clear-cache purges only the transient cache dirs (tracks/tracks-cmaf/artwork), never the organized downloaded albums — those are removed per-item from the offline manager. The old copy ('Remove every downloaded track. This cannot be undone.') was misleading. Relabels the row 'Clear cache', rewrites the description to say downloads are kept and point to the manager, and softens the toasts to 'Cache cleared' / 'Couldn't clear the cache'. 8 locales.

cc
2026-07-13 21:01:48 -06:00
vicrodh ba7be747a7 fix(immersive): persist volume on drag-end
The immersive VolumeBar only called set-volume (live) and never persist-volume, so a volume set in the immersive view was lost on restart/track-change. Adds a released(float) callback emitted on pointer-up, wired to NowPlayingState.persist-volume — parity with the NPB sliders. Pure .slint; persist-volume already exists in Rust.

cc
2026-07-13 21:01:48 -06:00
vicrodh 41f8578b78 feat(home): sort control for the Library Albums rail
Adds a compact dropdown in the Library Albums (favoriteAlbums) row header, left of the page chevrons: Recently added (default), First added (reverse), Random (shuffle). Reorders the cached base list in Rust with no re-fetch and re-fires artwork by the new index. Also corrects the stale HomeView comment that claimed the recently-played refresh lives in the toolbar (it is a row-header button). 8 locales updated.

cc
2026-07-13 21:01:48 -06:00
vicrodh dfc74fb6d4 Merge branch 'pr/606' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:27:23 -06:00
vicrodh 12dcedbc0f Merge branch 'pr/611' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:14:09 -06:00
vicrodh 30c57c9f54 Merge branch 'pr/608' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:13:57 -06:00
vicrodh 97ab577778 Merge branch 'pr/598' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:13:57 -06:00
vicrodh 3f974752ae Merge branch 'pr/595' into integration/pr-review-smoke-2026-07-13
# Conflicts:
#	crates/qbz-player/src/player/mod.rs
2026-07-13 14:13:47 -06:00
vicrodh 83c47933cb Merge branch 'pr/594' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:12:49 -06:00
vicrodh 7b0b2ed7da Merge branch 'pr/599' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:12:39 -06:00
vicrodh c2e23dfa95 Merge branch 'pr/593' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:12:39 -06:00
vicrodh 116fe38476 Merge branch 'pr/607' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:08:28 -06:00
vicrodh d4522c3585 Merge branch 'pr/604' into integration/pr-review-smoke-2026-07-13 2026-07-13 14:08:28 -06:00