Rebuild both Settings panels to match the Tauri app — every option present, on the correct tab, and fully functional (persisted and applied to the live player). Audio: streaming quality, limit-quality-to-device, maximum sample rate, backend, output device, ALSA plugin, hardware volume, exclusive mode, reserve DAC, DAC passthrough, force bit-perfect, allow quality fallback, sync-on-startup, lock output device, and a reset button. Conditional rows (ALSA plugin, hardware volume, max sample rate, force bit-perfect, lock output device) are gated on Rust-computed flags. Playback: continue-after-track, show context icon, gapless, restore session, resume position, stream uncached, initial buffer size (slider), streaming only, quality-retry behavior. Note gapless and the streaming options live on the Playback tab though the qbz-audio struct stores them. - ui_prefs.rs: JSON store for the frontend-only streaming-quality pref - QbzSlider primitive for the integer buffer-size control - volume normalization row removed (Tauri hides it) Caveat: toggling reserve-DAC persists and is read live, but re-arming the device reservation guard mid-session needs a player-side API that does not exist yet; it takes effect on next launch. cc
176 lines
6.3 KiB
Plaintext
176 lines
6.3 KiB
Plaintext
// Shared UI state — structs and globals the Rust controllers populate.
|
|
//
|
|
// The Rust side builds these models on a worker thread, then sets them
|
|
// on the global from the Slint event loop (see src/home.rs, src/main.rs).
|
|
|
|
export struct AlbumCardItem {
|
|
id: string,
|
|
title: string,
|
|
artist: string,
|
|
genre: string, // shown in the hover overlay
|
|
year: string, // shown in the hover overlay
|
|
quality-tier: string, // "hires" | "cd" | "" — drives the badge icon
|
|
quality-label: string, // "Hi-Res: 24-bit / 96 kHz" — badge hover tooltip
|
|
ribbon: string,
|
|
ribbon-kind: string, // "press" | "qobuzissime" | "albumOfTheWeek" | ""
|
|
artwork-url: string,
|
|
artwork: image, // empty until the artwork pipeline resolves it
|
|
}
|
|
|
|
export struct DiscoverSection {
|
|
title: string,
|
|
albums: [AlbumCardItem],
|
|
}
|
|
|
|
// Compact "slim" card item — a small thumbnail with a title/subtitle,
|
|
// optionally rank-numbered (Popular albums, Recently Played).
|
|
export struct SlimItem {
|
|
id: string,
|
|
title: string,
|
|
subtitle: string,
|
|
rank: string, // "" = no rank
|
|
artwork-url: string,
|
|
artwork: image,
|
|
}
|
|
|
|
// Discover / Home screen state.
|
|
export global HomeState {
|
|
in property <[DiscoverSection]> sections: [];
|
|
in property <[SlimItem]> popular: [];
|
|
in property <[SlimItem]> recent: [];
|
|
in property <[AlbumCardItem]> recent-albums: [];
|
|
in property <bool> loading: false;
|
|
}
|
|
|
|
export struct AlbumTrackItem {
|
|
id: string,
|
|
number: string,
|
|
title: string,
|
|
artist: string,
|
|
duration: string,
|
|
quality-tier: string,
|
|
explicit: bool,
|
|
}
|
|
|
|
// Album detail screen state.
|
|
export global AlbumState {
|
|
in property <string> id;
|
|
in property <string> title;
|
|
in property <string> artist;
|
|
in property <string> artist-id;
|
|
in property <string> info-line;
|
|
in property <string> quality-tier;
|
|
// "24-bit / 96 kHz" — quality-badge detail line.
|
|
in property <string> quality-detail;
|
|
// Editorial description / review (HTML stripped). May be empty.
|
|
in property <string> description;
|
|
// Truncated description for the header; full text lives in the modal.
|
|
in property <string> description-short;
|
|
in property <image> artwork;
|
|
// Artwork-derived tint for the header gradient.
|
|
in property <color> header-color: #181820;
|
|
in property <string> label;
|
|
in property <[string]> awards: [];
|
|
in property <[AlbumTrackItem]> tracks: [];
|
|
in property <bool> loading: false;
|
|
}
|
|
|
|
// Album-view actions wired to Rust callbacks.
|
|
export global AlbumActions {
|
|
// Filter the visible track list by a query (client-side).
|
|
callback search(string);
|
|
}
|
|
|
|
// Which content view the shell shows.
|
|
export enum ContentView { home, album, artist, settings }
|
|
|
|
// Settings screen state. Audio and Playback preferences are loaded from
|
|
// the persistence stores by the Rust settings controller and pushed here;
|
|
// changes flow back through the settings-bool / settings-select /
|
|
// settings-slider callbacks.
|
|
export global SettingsState {
|
|
// Sub-section: 0 = Audio, 1 = Playback.
|
|
in-out property <int> section: 0;
|
|
in property <bool> loading: true;
|
|
|
|
// --- AUDIO -------------------------------------------------------------
|
|
|
|
// Audio — dropdowns. Each list is paired with a selected index; the
|
|
// Rust controller owns the index -> value mapping.
|
|
in-out property <[string]> streaming-qualities: [];
|
|
in-out property <int> streaming-quality-index: 0;
|
|
in-out property <[string]> sample-rates: [];
|
|
in-out property <int> sample-rate-index: 0;
|
|
in-out property <[string]> backends: [];
|
|
in-out property <int> backend-index: 0;
|
|
in-out property <[string]> devices: [];
|
|
in-out property <int> device-index: 0;
|
|
in-out property <[string]> alsa-plugins: [];
|
|
in-out property <int> alsa-plugin-index: 0;
|
|
|
|
// Audio — toggles.
|
|
in-out property <bool> limit-quality-to-device: false;
|
|
in-out property <bool> alsa-hardware-volume: false;
|
|
in-out property <bool> exclusive-mode: false;
|
|
in-out property <bool> reserve-dac: false;
|
|
in-out property <bool> dac-passthrough: false;
|
|
in-out property <bool> pw-force-bitperfect: false;
|
|
in-out property <bool> allow-quality-fallback: false;
|
|
in-out property <bool> sync-audio-on-startup: false;
|
|
in-out property <bool> skip-sink-switch: false;
|
|
|
|
// Audio — Rust-computed conditional flags driving `if`-gated rows.
|
|
in-out property <bool> backend-is-alsa: false;
|
|
in-out property <bool> backend-is-pipewire: false;
|
|
in-out property <bool> alsa-plugin-is-hw: false;
|
|
|
|
// --- PLAYBACK ----------------------------------------------------------
|
|
|
|
// Playback — toggles. `continue-playback` maps to the autoplay mode
|
|
// (on = ContinueWithinSource, off = PlayTrackOnly).
|
|
in-out property <bool> continue-playback: true;
|
|
in-out property <bool> show-context-icon: true;
|
|
in-out property <bool> persist-session: false;
|
|
in-out property <bool> resume-position: false;
|
|
in-out property <bool> gapless: true;
|
|
in-out property <bool> stream-uncached: false;
|
|
in-out property <bool> streaming-only: false;
|
|
|
|
// Playback — Initial Buffer Size slider (seconds, 1-10).
|
|
in-out property <int> buffer-seconds: 3;
|
|
|
|
// Playback — "When quality retries fail" dropdown.
|
|
in-out property <[string]> retry-behaviors: [];
|
|
in-out property <int> retry-behavior-index: 0;
|
|
}
|
|
|
|
export global NavState {
|
|
in-out property <ContentView> view: ContentView.home;
|
|
// Browser-like history flags, driven by the Rust nav module.
|
|
in property <bool> can-back: false;
|
|
in property <bool> can-forward: false;
|
|
// Navigation requests routed to Rust so history is recorded.
|
|
callback request-back();
|
|
callback request-forward();
|
|
callback request-settings();
|
|
}
|
|
|
|
// Artist detail screen state.
|
|
export global ArtistState {
|
|
in property <string> name;
|
|
in property <string> bio;
|
|
in property <image> artwork;
|
|
// Artwork-derived tint for the header gradient.
|
|
in property <color> header-color: #181820;
|
|
in property <[AlbumTrackItem]> top-tracks: [];
|
|
// Releases grouped into titled sections (Albums, EPs & Singles, ...).
|
|
in property <[DiscoverSection]> release-sections: [];
|
|
in property <bool> loading: false;
|
|
}
|
|
|
|
// Authenticated user, for the header user element.
|
|
export global SessionState {
|
|
in property <string> user-name: "";
|
|
in property <string> subscription: "";
|
|
}
|