overlay + library: the preloader working on glass, album names that land on the right self-titled record, and covers warmed before you scroll to them

This commit is contained in:
KeelrLeek committed 2026-08-25 08:05:07 -05:00
1 parent ad2c912b71
commit 6a7a5c49c0
7 files changed
+534 -39

No files matched your search

+60
View File
@@ -6,6 +6,7 @@
//! Process figures aggregate the WHOLE process tree: the WebView2 children
//! do the actual rendering, so app.exe alone would tell a comforting lie.
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::time::Instant;
@@ -27,6 +28,48 @@ struct Inner {
/// StreamProgress — the overlay must read download truth at the source,
/// not the UI store's window-activity-gated mirror.
current_stream: Option<(u64, Arc<StreamProgress>)>,
/// On-deck pre-buffer transfers by transfer id, mirrored from the
/// download event stream (those updates are otherwise swallowed — no
/// player, no Downloads view). The Instant is set when the transfer
/// reaches a terminal state, so finished rows linger long enough to be
/// seen and then fall off.
preloads: HashMap<u64, (PreloadDl, Option<Instant>)>,
}
/// One on-deck transfer as the overlay sees it.
#[derive(Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct PreloadDl {
pub username: String,
/// Full remote path — the frontend matches queue rows by this.
pub path: String,
pub state: String,
/// Remote queue position, when the peer reported one.
pub place: Option<u32>,
pub received: u64,
pub total: u64,
pub speed_bps: u64,
}
/// Called from the download event stream for every preload update.
pub fn note_preload(app: &tauri::AppHandle, id: u64, dl: PreloadDl, terminal: bool) {
if let Some(state) = app.try_state::<DiagState>() {
let finished = if terminal { Some(Instant::now()) } else { None };
state
.0
.lock()
.expect("diag lock")
.preloads
.insert(id, (dl, finished));
}
}
/// Called when a play path takes the transfer over: it is the CURRENT
/// track's stream from here on (note_stream reports it), not an on-deck row.
pub fn retire_preload(app: &tauri::AppHandle, id: u64) {
if let Some(state) = app.try_state::<DiagState>() {
state.0.lock().expect("diag lock").preloads.remove(&id);
}
}
/// Called by the play paths: this track streams from a peer.
@@ -51,6 +94,7 @@ pub fn init(app: &tauri::AppHandle) {
gpu: GpuCounter::open(),
started: Instant::now(),
current_stream: None,
preloads: HashMap::new(),
})));
}
@@ -98,6 +142,9 @@ pub struct DebugStats {
pub preview_volume: Option<f32>,
/// The active preview clip's loudness-normalization gain in dB.
pub preview_norm_db: Option<f32>,
/// On-deck pre-buffer transfers, in arrival order (finished rows linger
/// ~15s so a completion is visible before it drops off).
pub preload_dl: Vec<PreloadDl>,
}
#[tauri::command]
@@ -167,6 +214,18 @@ pub fn debug_stats(app: tauri::AppHandle, state: State<'_, DiagState>) -> DebugS
let tree_u32: Vec<u32> = tree.iter().map(|p| p.as_u32()).collect();
let gpu_sample = inner.gpu.as_mut().and_then(|g| g.sample(&tree_u32));
// On-deck transfers: drop terminal rows after they've been visible a
// while, then report the rest in arrival (transfer-id) order.
inner
.preloads
.retain(|_, v| v.1.is_none_or(|t| t.elapsed().as_secs() < 15));
let mut preload_ids: Vec<u64> = inner.preloads.keys().copied().collect();
preload_ids.sort_unstable();
let preload_dl: Vec<PreloadDl> = preload_ids
.iter()
.filter_map(|id| inner.preloads.get(id).map(|(dl, _)| dl.clone()))
.collect();
DebugStats {
cpu_process,
cpu_system: inner.sys.global_cpu_usage(),
@@ -201,6 +260,7 @@ pub fn debug_stats(app: tauri::AppHandle, state: State<'_, DiagState>) -> DebugS
main_fade_gain: app
.try_state::<crate::playback::PlayerState>()
.map(|p| p.player.fade_gain()),
preload_dl,
}
}