feat(slint): minimal playback wiring + Queue, plus detail/Settings fixes

Playback (minimal, album-focused):
- playback.rs controller: play an album (set queue + start audio),
  play a single track, enqueue, play a queue index, transport
  (play/pause, next, previous, seek, volume)
- the audible step uses Player::play_track (fetch -> download -> play);
  the protected audio backend is untouched
- a 450ms poll loop pushes position/progress/times/playing onto
  NowPlayingState and auto-advances at end of track
- NowPlayingState / QueueState globals; NowPlayingBar bound to real
  state (song card, seek bar, transport, volume); QueueSidebar lists
  the queue and rows play on click
- a played track is recorded into the recently-played store

Detail views:
- album description and artist biography stay with the metadata,
  filling the width to the right of the artwork (not below the header)
- header nav tabs gained a dropdown caret and 2px side padding

Settings > Playback defaults are now opt-out: show context icon,
restore session, resume position and stream-uncached default on;
streaming-only stays opt-in; initial buffer defaults to 2s.

Known gaps: queue/now-playing artwork not yet threaded (Image is not
Send); autoplay-mode preference not consulted by auto-advance; buffer
progress line stays at 0.

cc
This commit is contained in:
vicrodh committed 2026-05-18 22:16:13 -06:00
1 parent 33df7bce76
commit 7e6e548598
12 files changed
+1012 -72

No files matched your search

+6 -6
View File
@@ -91,8 +91,8 @@ impl Default for AudioSettings {
backend_type: Some(AudioBackendType::default()),
alsa_plugin: Some(AlsaPlugin::Hw), // Default to hw (bit-perfect)
alsa_hardware_volume: false, // Disabled by default (maximum compatibility)
stream_first_track: false, // Disabled by default — user opts in
stream_buffer_seconds: 3, // 3 seconds initial buffer
stream_first_track: true, // On by default (opt-out)
stream_buffer_seconds: 2, // 2 seconds initial buffer
streaming_only: false, // Disabled by default (cache tracks for instant replay)
limit_quality_to_device: false, // Disabled in 1.1.9 — detection logic unreliable (#45)
device_max_sample_rate: None, // Set when device is selected
@@ -136,8 +136,8 @@ impl AudioSettingsStore {
backend_type TEXT,
alsa_plugin TEXT,
alsa_hardware_volume INTEGER NOT NULL DEFAULT 0,
stream_first_track INTEGER NOT NULL DEFAULT 0,
stream_buffer_seconds INTEGER NOT NULL DEFAULT 3
stream_first_track INTEGER NOT NULL DEFAULT 1,
stream_buffer_seconds INTEGER NOT NULL DEFAULT 2
);
INSERT OR IGNORE INTO audio_settings (id, exclusive_mode, dac_passthrough)
VALUES (1, 0, 0);",
@@ -155,11 +155,11 @@ impl AudioSettingsStore {
[],
);
let _ = conn.execute(
"ALTER TABLE audio_settings ADD COLUMN stream_first_track INTEGER DEFAULT 0",
"ALTER TABLE audio_settings ADD COLUMN stream_first_track INTEGER DEFAULT 1",
[],
);
let _ = conn.execute(
"ALTER TABLE audio_settings ADD COLUMN stream_buffer_seconds INTEGER DEFAULT 3",
"ALTER TABLE audio_settings ADD COLUMN stream_buffer_seconds INTEGER DEFAULT 2",
[],
);
let _ = conn.execute(