Clamp the progress gauge ratio
The player position can overrun a stale or wrong duration (streams, hand-written track files), and ratatui's LineGauge asserts its ratio into 0..=1 — the TUI died with "ratio should be between 0 and 1" mid-playback. Clamp instead, with render regression tests for both the overrun and the zero-duration case. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
955c7ea5b4
commit
8bb653ab3e
|
|
@ -142,10 +142,16 @@ impl NowPlaying {
|
|||
.constraints([Constraint::Min(10), Constraint::Max(completion_size)])
|
||||
.split(now_playing_layout[1]);
|
||||
|
||||
// Clamped: the player's position can overrun a stale or wrong
|
||||
// duration (streams, hand-written track files), and
|
||||
// `LineGauge` panics on ratios outside 0..=1.
|
||||
let ratio = if duration.is_zero() {
|
||||
0.0
|
||||
} else {
|
||||
position.as_secs_f64().div(duration.as_secs_f64())
|
||||
position
|
||||
.as_secs_f64()
|
||||
.div(duration.as_secs_f64())
|
||||
.clamp(0.0, 1.0)
|
||||
};
|
||||
|
||||
let progress = LineGauge::default()
|
||||
|
|
@ -180,3 +186,48 @@ impl NowPlaying {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ratatui::{backend::TestBackend, Terminal};
|
||||
|
||||
/// A now-playing pane mid-track, built directly (no `update_track`,
|
||||
/// which fires a desktop notification).
|
||||
fn now_playing(position_ms: u32, duration_ms: u32) -> NowPlaying {
|
||||
NowPlaying {
|
||||
play_state: PlayState::Playing,
|
||||
duration: Some(Duration::from_millis(duration_ms.into())),
|
||||
modifiers: QueueModifiers::default(),
|
||||
position: Some(Duration::from_millis(position_ms.into())),
|
||||
track: Some(Track {
|
||||
path: "/fs/radio.cbd-track.toml".to_string(),
|
||||
artist: "artist".to_string(),
|
||||
title: "title".to_string(),
|
||||
duration: None,
|
||||
album: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn render(pane: &NowPlaying) {
|
||||
let backend = TestBackend::new(60, 12);
|
||||
let mut terminal = Terminal::new(backend).expect("test terminal");
|
||||
terminal
|
||||
.draw(|f| pane.render(f, f.area()))
|
||||
.expect("draw must not panic");
|
||||
}
|
||||
|
||||
/// The position can overrun a stale or wrong duration (streams,
|
||||
/// hand-written track files); the gauge must clamp instead of hitting
|
||||
/// ratatui's `ratio should be between 0 and 1` panic.
|
||||
#[test]
|
||||
fn progress_gauge_survives_position_past_duration() {
|
||||
render(&now_playing(90_000, 60_000));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn progress_gauge_survives_a_zero_duration() {
|
||||
render(&now_playing(5_000, 0));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue