From 03b6fb053e5f36e426264c9b4de5ed5fb22db57e Mon Sep 17 00:00:00 2001 From: Justin Scroggins Date: Mon, 2 Nov 2026 18:39:21 -0500 Subject: [PATCH 1/3] Show Call health as a card with a minute of ping and receive. Co-authored-by: Cursor --- docs/design/shots/call-health-card.png | Bin 0 -> 110645 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/design/shots/call-health-card.png diff --git a/docs/design/shots/call-health-card.png b/docs/design/shots/call-health-card.png new file mode 100644 index 0000000000000000000000000000000000000000..7e39c6f634d1fbd0003c920732c33e8ae68ad9d0 GIT binary patch literal 110645 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
  • dfve|CU-!IDR?#~S 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 ID Date: Mon, 2 Nov 2026 18:39:52 -0500 Subject: [PATCH 2/3] Show Call health as a card with a minute of ping and receive. Co-authored-by: Cursor --- crates/tinyclient/src/gui/call/health.rs | 48 ++++ crates/tinyclient/src/gui/tiny/mod.rs | 9 +- crates/tinyclient/src/gui/tiny/panel.rs | 304 ++++++++++++++++++++--- 3 files changed, 329 insertions(+), 32 deletions(-) diff --git a/crates/tinyclient/src/gui/call/health.rs b/crates/tinyclient/src/gui/call/health.rs index 6e8f754..5ed2010 100644 --- a/crates/tinyclient/src/gui/call/health.rs +++ b/crates/tinyclient/src/gui/call/health.rs @@ -158,6 +158,40 @@ const WORSE_AFTER: Duration = Duration::from_secs(3); /// And better: a call that went bad has to prove itself for longer. const BETTER_AFTER: Duration = Duration::from_secs(10); +/// Seconds of ping and receive bitrate kept for Call health's time graph. +pub(in crate::gui) const CHART_SECONDS: usize = 60; + +/// One second on the Call health chart: round trip and what we were receiving. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(in crate::gui) struct ChartSample { + pub rtt_ms: u32, + pub recv_kbps: u32, +} + +/// Append one poll to the chart, dropping the oldest past [`CHART_SECONDS`]. +pub(in crate::gui) fn push_chart(samples: &mut VecDeque, stats: &CallStats) { + if samples.len() >= CHART_SECONDS { + samples.pop_front(); + } + samples.push_back(ChartSample { rtt_ms: stats.rtt_ms, recv_kbps: stats.receive_kbps }); +} + +/// A full minute of made-up samples around `stats`, for `--shot` so the graph is not empty. +pub(in crate::gui) fn seed_chart(stats: &CallStats) -> VecDeque { + let base_rtt = stats.rtt_ms.max(1); + let base_recv = stats.receive_kbps.max(1); + (0..CHART_SECONDS) + .map(|i| { + let rtt_wobble = ((i * 37) % 11) as i32 - 5; + let recv_wobble = ((i * 53) % 21) as i32 - 10; + ChartSample { + rtt_ms: (base_rtt as i32 + rtt_wobble).max(1) as u32, + recv_kbps: (base_recv as i32 + recv_wobble * 2).max(1) as u32, + } + }) + .collect() +} + /// The link over the last several seconds, fed each poll, and the grade it has earned. While /// nothing flows nothing is known about loss or jitter, so they and the grade stay as they were. #[derive(Debug, Default)] @@ -463,6 +497,20 @@ mod tests { CallStats { rtt_ms, loss_permille, jitter_ms, link_measured: true, ..CallStats::default() } } + #[test] + fn the_chart_keeps_a_minute_and_shot_seed_fills_it() { + let mut samples = VecDeque::new(); + for n in 0..70 { + push_chart(&mut samples, &CallStats { rtt_ms: n, receive_kbps: n * 2, ..CallStats::default() }); + } + assert_eq!(samples.len(), CHART_SECONDS); + assert_eq!(samples.front().map(|sample| sample.rtt_ms), Some(10)); + assert_eq!(samples.back().map(|sample| sample.rtt_ms), Some(69)); + let seeded = seed_chart(&CallStats { rtt_ms: 38, receive_kbps: 182, ..CallStats::default() }); + assert_eq!(seeded.len(), CHART_SECONDS); + assert!(seeded.iter().all(|sample| sample.rtt_ms > 0 && sample.recv_kbps > 0)); + } + #[test] fn a_packet_lost_now_and_then_does_not_move_the_bars() { // One packet of fifty is 20 per mille, and three in one bad second is 60: the old grade diff --git a/crates/tinyclient/src/gui/tiny/mod.rs b/crates/tinyclient/src/gui/tiny/mod.rs index f9a397d..020fee5 100644 --- a/crates/tinyclient/src/gui/tiny/mod.rs +++ b/crates/tinyclient/src/gui/tiny/mod.rs @@ -40,7 +40,7 @@ use crate::gui::call::health; use gpui::{prelude::*, Bounds, ClipboardItem, Context, Entity, Focusable, PathPromptOptions, Pixels, Point, Task, Window}; use protocol::{AccountKey, CallStats, Change, Key, Link, Network, Presence, Request, Response, TinyCommunity}; use std::cell::Cell; -use std::collections::{HashMap, HashSet}; +use std::collections::{HashMap, HashSet, VecDeque}; use std::io; use std::rc::Rc; use std::time::{Duration, Instant}; @@ -196,6 +196,8 @@ pub struct State { /// The poll before `stats`, so the audio counters (counts over the whole call) can be read /// as what grew in the last second. stats_before: Option, + /// The last minute of ping and receive bitrate for Call health's time graph. + stats_chart: VecDeque, /// The polls over the last several seconds: what the bars and the numbers show. steady: health::Steady, /// Why there are no numbers, when mediad said. @@ -277,6 +279,7 @@ impl State { sliding: None, stats: None, stats_before: None, + stats_chart: VecDeque::new(), steady: health::Steady::default(), stats_note: None, stats_task: None, @@ -881,6 +884,7 @@ impl Shell { if self.tiny_state.stats_task.take().is_some() { self.tiny_state.stats = None; self.tiny_state.stats_before = None; + self.tiny_state.stats_chart.clear(); self.tiny_state.steady = health::Steady::default(); self.tiny_state.stats_note = None; } @@ -892,6 +896,7 @@ impl Shell { self.tiny_state.applied = call; #[cfg(feature = "gui-shot")] if let Some(stats) = crate::gui::call::shot_stats() { + self.tiny_state.stats_chart = health::seed_chart(&stats); self.tiny_state.stats = Some(stats); return; } @@ -905,6 +910,7 @@ impl Shell { match answer { Ok(Response::CallStats { stats }) => { this.tiny_state.steady.feed(&stats, Instant::now()); + health::push_chart(&mut this.tiny_state.stats_chart, &stats); this.tiny_state.stats_before = this.tiny_state.stats.replace(stats); this.tiny_state.stats_note = None; } @@ -912,6 +918,7 @@ impl Shell { Ok(Response::Error { detail, .. }) => { this.tiny_state.stats = None; this.tiny_state.stats_before = None; + this.tiny_state.stats_chart.clear(); this.tiny_state.steady = health::Steady::default(); this.tiny_state.stats_note = Some(detail); } diff --git a/crates/tinyclient/src/gui/tiny/panel.rs b/crates/tinyclient/src/gui/tiny/panel.rs index 3d80e82..89eaee6 100644 --- a/crates/tinyclient/src/gui/tiny/panel.rs +++ b/crates/tinyclient/src/gui/tiny/panel.rs @@ -2,14 +2,16 @@ //! link is, my microphone and headphones, and the voice settings. While a call is up its second //! line is the state of the call with signal bars and the round trip, and a click on it opens //! Call health: the link graded in words, what to do about it, and the numbers (ping, jitter, -//! loss, bitrate and the path the audio takes). +//! loss, bitrate and the path the audio takes), with a minute of ping and receive on a graph. use super::Float; -use crate::gui::call::health::{self, Grade, Health}; +use crate::gui::call::health::{self, ChartSample, Grade, Health}; use crate::gui::components::{glyph, tip, Avatar}; use crate::gui::state::Shell; use crate::gui::theme::{self, Type}; -use gpui::{div, prelude::*, px, Context, Div, Rgba, SharedString, Stateful}; +use gpui::{ + canvas, div, fill, point, prelude::*, px, size, Bounds, Context, Div, PathBuilder, Rgba, SharedString, Stateful, +}; use protocol::{CallPath, CallState, Presence}; pub(super) const PANEL: f32 = 52.; @@ -65,6 +67,191 @@ pub(super) fn path_words(path: CallPath) -> &'static str { } } +fn path_pill(path: CallPath) -> &'static str { + match path { + CallPath::Udp => "Direct · UDP", + CallPath::Tcp => "Direct · TCP", + CallPath::Relay => "Relayed", + CallPath::Unknown => "Not known yet", + } +} + +fn grade_badge(grade: Grade) -> &'static str { + match grade { + Grade::Unknown => "…", + Grade::Poor => "Poor", + Grade::Fair => "Fair", + Grade::Good => "Good", + Grade::Great => "Excellent", + } +} + +fn meta_row(label: &'static str, value: impl IntoElement) -> Div { + div() + .h(px(26.)) + .flex() + .items_center() + .child(div().flex_1().type_ui().text_color(theme::text_soft()).child(label)) + .child(div().type_ui().font_weight(theme::SEMIBOLD).text_color(theme::text()).child(value)) +} + +fn kpi(label: &'static str, value: String, unit: &'static str) -> Div { + div() + .flex_1() + .min_w_0() + .px(px(8.)) + .py(px(8.)) + .rounded(px(theme::R_CONTROL)) + .border_1() + .border_color(theme::border()) + .bg(theme::field()) + .child(div().type_micro().font_weight(theme::SEMIBOLD).text_color(theme::text_soft()).child(label)) + .child( + div() + .mt(px(2.)) + .flex() + .items_baseline() + .gap(px(2.)) + .child(div().type_ui().font_weight(theme::SEMIBOLD).text_color(theme::positive()).child(value)) + .child(div().type_small().font_weight(theme::MEDIUM).text_color(theme::text_soft()).child(unit)), + ) +} + +/// Ping (filled) and receive bitrate over the last minute. +fn health_chart(samples: Vec) -> Div { + let (now_rtt, now_recv) = samples.last().map(|sample| (sample.rtt_ms, sample.recv_kbps)).unwrap_or((0, 0)); + let chart = canvas( + |_, _, _| (), + move |bounds, (), window, _| { + if samples.is_empty() { + return; + } + let width = f32::from(bounds.size.width); + let height = f32::from(bounds.size.height); + let origin_x = f32::from(bounds.origin.x); + let origin_y = f32::from(bounds.origin.y); + for frac in [0.25_f32, 0.5, 0.75] { + let y = origin_y + height * frac; + window.paint_quad(fill(Bounds::new(point(px(origin_x), px(y)), size(px(width), px(1.))), theme::hairline())); + } + let count = samples.len(); + let span = (count.saturating_sub(1)).max(1) as f32; + let max_rtt = samples.iter().map(|sample| sample.rtt_ms).max().unwrap_or(1).max(1) as f32; + let max_recv = samples.iter().map(|sample| sample.recv_kbps).max().unwrap_or(1).max(1) as f32; + let x_at = |index: usize| origin_x + width * (index as f32) / span; + let ping_y = |rtt: u32| { + let t = (rtt as f32 / (max_rtt * 1.2)).clamp(0., 1.); + origin_y + height * (0.42 + 0.5 * (1. - t)) + }; + let recv_y = |kbps: u32| { + let t = (kbps as f32 / (max_recv * 1.2)).clamp(0., 1.); + origin_y + height * (0.06 + 0.3 * (1. - t)) + }; + + let mut area = PathBuilder::fill(); + area.move_to(point(px(x_at(0)), px(origin_y + height))); + for (index, sample) in samples.iter().enumerate() { + area.line_to(point(px(x_at(index)), px(ping_y(sample.rtt_ms)))); + } + area.line_to(point(px(x_at(count - 1)), px(origin_y + height))); + area.close(); + if let Ok(path) = area.build() { + window.paint_path(path, theme::positive_soft()); + } + + let mut ping = PathBuilder::stroke(px(2.)); + for (index, sample) in samples.iter().enumerate() { + let at = point(px(x_at(index)), px(ping_y(sample.rtt_ms))); + if index == 0 { + ping.move_to(at); + } else { + ping.line_to(at); + } + } + if let Ok(path) = ping.build() { + window.paint_path(path, theme::positive()); + } + + let mut recv = PathBuilder::stroke(px(1.75)).dash_array(&[px(3.), px(3.)]); + for (index, sample) in samples.iter().enumerate() { + let at = point(px(x_at(index)), px(recv_y(sample.recv_kbps))); + if index == 0 { + recv.move_to(at); + } else { + recv.line_to(at); + } + } + if let Ok(path) = recv.build() { + window.paint_path(path, theme::accent()); + } + + if let Some(last) = samples.last() { + let cx = x_at(count - 1); + let cy = ping_y(last.rtt_ms); + window.paint_quad(fill( + Bounds::new(point(px(cx - 5.), px(cy - 5.)), size(px(10.), px(10.))), + theme::positive_soft(), + )); + window.paint_quad(fill( + Bounds::new(point(px(cx - 2.5), px(cy - 2.5)), size(px(5.), px(5.))), + theme::positive(), + )); + } + }, + ) + .h(px(92.)) + .w_full(); + + div() + .mb(px(10.)) + .p(px(10.)) + .rounded(px(theme::R_CONTROL)) + .border_1() + .border_color(theme::border()) + .bg(theme::field()) + .child( + div() + .mb(px(6.)) + .flex() + .items_center() + .justify_between() + .child(div().type_micro().font_weight(theme::SEMIBOLD).text_color(theme::text_soft()).child("Last 60s")) + .child( + div() + .flex() + .items_center() + .gap(px(10.)) + .child( + div() + .flex() + .items_center() + .gap(px(5.)) + .child(div().size(px(7.)).rounded_full().bg(theme::positive())) + .child(div().type_micro().text_color(theme::text_soft()).child("Ping")), + ) + .child( + div() + .flex() + .items_center() + .gap(px(5.)) + .child(div().size(px(7.)).rounded_full().bg(theme::accent())) + .child(div().type_micro().text_color(theme::text_soft()).child("Recv")), + ), + ), + ) + .child(chart) + .child( + div() + .mt(px(4.)) + .flex() + .justify_between() + .type_micro() + .text_color(theme::text_soft()) + .child("−60s") + .child(format!("Now · {now_rtt} ms · {now_recv} kb/s")), + ) +} + impl Shell { /// The panel, at the very foot of the sidebar on a Tiny server. pub(in crate::gui) fn tiny_user_panel(&self, cx: &mut Context) -> Option
    { @@ -165,34 +352,64 @@ impl Shell { self.tiny_state.stats.as_ref().map(|stats| self.tiny_state.steady.applied(Health::from_polls(before, stats))) } - /// Call health, over the panel: the link graded, what to do about it in words, then the - /// connection's numbers. + /// Call health, over the panel: the link graded, what to do about it in words, the last + /// minute on a graph, key numbers, then the connection's details. pub(super) fn tiny_stats_card(&self) -> Div { - let row = |label: &'static str, value: String| { - div() - .h(px(24.)) - .flex() - .items_center() - .child(div().flex_1().type_ui().text_color(theme::text_soft()).child(label)) - .child(div().type_ui().font_weight(theme::MEDIUM).text_color(theme::text()).child(value)) - }; let room = self.tiny_page_facts().and_then(|page| page.mine.and_then(|id| page.community.rooms.iter().find(|room| room.id == id)).map(|room| (room.name.clone(), room.bitrate()))); let health = self.tiny_health().unwrap_or_default(); let grade = health.grade(); - let mut card = div().w(px(288.)).flex().flex_col().gap(px(2.)).child( + let mut card = div().w(px(320.)).flex().flex_col().child( div() - .pb(px(8.)) + .pb(px(10.)) .flex() - .items_center() + .items_start() + .justify_between() .gap(px(8.)) - .child(health::bars(grade, 14.)) - .child(div().flex_1().type_ui().font_weight(theme::SEMIBOLD).text_color(theme::text()).child("Call health")) - .child(div().type_small().text_color(grade.color()).child(grade.words())), + .child( + div() + .min_w_0() + .flex_1() + .child( + div() + .flex() + .items_center() + .gap(px(8.)) + .child(health::bars(grade, 14.)) + .child(div().type_ui().font_weight(theme::SEMIBOLD).text_color(theme::text()).child("Call health")), + ) + .children(health.hints().into_iter().take(1).map(|hint| { + div() + .mt(px(6.)) + .flex() + .items_start() + .gap(px(6.)) + .child(div().pt(px(1.)).child(glyph(hint.level.icon(), 12., hint.level.color()))) + .child(div().flex_1().min_w_0().whitespace_normal().type_small().text_color(hint.level.color()).child(hint.words)) + })), + ) + .child( + div() + .flex_none() + .px(px(8.)) + .py(px(3.)) + .rounded_full() + .bg(match grade { + Grade::Great | Grade::Good => theme::positive_soft(), + Grade::Fair => theme::warning_soft(), + Grade::Poor => theme::danger_soft(), + Grade::Unknown => theme::field(), + }) + .type_micro() + .font_weight(theme::SEMIBOLD) + .text_color(grade.color()) + .child(grade_badge(grade)), + ), ); + let hints = health.hints(); - if !hints.is_empty() { + if hints.len() > 1 { card = card.child( - div().pb(px(8.)).mb(px(4.)).border_b_1().border_color(theme::hairline()).flex().flex_col().gap(px(6.)).children(hints.into_iter().take(3).map(|hint| { + div().pb(px(8.)).mb(px(4.)).border_b_1().border_color(theme::hairline()).flex().flex_col().gap(px(6.)).children(hints.into_iter().skip(1).take(2).map(|hint| { div() .flex() .items_start() @@ -202,19 +419,42 @@ impl Shell { })), ); } - if let Some((name, kbps)) = &room { - card = card.child(row("Channel", name.clone())).child(row("Channel bitrate", format!("{kbps} kb/s"))); - } + match &self.tiny_state.stats { Some(stats) => { + let samples: Vec<_> = self.tiny_state.stats_chart.iter().copied().collect(); + if !samples.is_empty() { + card = card.child(health_chart(samples)); + } card = card - .child(row("Ping", format!("{} ms", health.rtt_ms.unwrap_or(0)))) - .child(row("Jitter", format!("{} ms", health.jitter_ms.unwrap_or(0)))) - .child(row("Packet loss", format!("{:.1} %", f32::from(health.loss_permille.unwrap_or(0)) / 10.))) - .child(row("Sending", format!("{} kb/s", stats.send_kbps))) - .child(row("Receiving", format!("{} kb/s", stats.receive_kbps))) - .child(row("Path", path_words(stats.path).to_owned())) - .when(!stats.codec.is_empty(), |card| card.child(row("Codec", stats.codec.clone()))); + .child( + div() + .mb(px(10.)) + .flex() + .gap(px(8.)) + .child(kpi("Ping", format!("{}", health.rtt_ms.unwrap_or(0)), "ms")) + .child(kpi("Jitter", format!("{}", health.jitter_ms.unwrap_or(0)), "ms")) + .child(kpi("Loss", format!("{:.1}", f32::from(health.loss_permille.unwrap_or(0)) / 10.), "%")), + ) + .when_some(room.as_ref(), |card, (name, kbps)| { + card.child(meta_row("Channel", name.clone())).child(meta_row("Channel bitrate", format!("{kbps} kb/s"))) + }) + .child(meta_row("Sending", format!("{} kb/s", stats.send_kbps))) + .child(meta_row("Receiving", format!("{} kb/s", stats.receive_kbps))) + .child(meta_row( + "Path", + div() + .px(px(7.)) + .py(px(2.)) + .rounded_full() + .bg(theme::selected()) + .flex() + .items_center() + .gap(px(5.)) + .child(div().size(px(6.)).rounded_full().bg(theme::positive())) + .child(div().type_micro().font_weight(theme::SEMIBOLD).text_color(theme::text()).child(path_pill(stats.path))), + )) + .when(!stats.codec.is_empty(), |card| card.child(meta_row("Codec", stats.codec.clone()))); } None => { let words: SharedString = self.tiny_state.stats_note.clone().unwrap_or_else(|| "Measuring…".to_owned()).into(); @@ -249,5 +489,7 @@ mod tests { assert_eq!(quality(&stats(40, 40)), theme::warning()); assert_eq!(quality(&stats(400, 0)), theme::danger()); assert_eq!(path_words(CallPath::Relay), "Relayed"); + assert_eq!(path_pill(CallPath::Udp), "Direct · UDP"); + assert_eq!(grade_badge(Grade::Great), "Excellent"); } } From 265bdb64fe1aed206da14b87415bd07db0f5a6e5 Mon Sep 17 00:00:00 2001 From: Justin Scroggins Date: Tue, 3 Nov 2026 04:46:29 -0500 Subject: [PATCH 3/3] Tighten Call health chart time axis and unmeasured KPI tone. Co-authored-by: Cursor --- crates/tinyclient/src/gui/call/health.rs | 21 +++++--- crates/tinyclient/src/gui/tiny/mod.rs | 4 +- crates/tinyclient/src/gui/tiny/panel.rs | 67 ++++++++++++++++-------- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/crates/tinyclient/src/gui/call/health.rs b/crates/tinyclient/src/gui/call/health.rs index 5ed2010..b7b935f 100644 --- a/crates/tinyclient/src/gui/call/health.rs +++ b/crates/tinyclient/src/gui/call/health.rs @@ -161,23 +161,24 @@ const BETTER_AFTER: Duration = Duration::from_secs(10); /// Seconds of ping and receive bitrate kept for Call health's time graph. pub(in crate::gui) const CHART_SECONDS: usize = 60; -/// One second on the Call health chart: round trip and what we were receiving. +/// One poll on the Call health chart: when it was read, round trip, and what we were receiving. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(in crate::gui) struct ChartSample { + pub at: Instant, pub rtt_ms: u32, pub recv_kbps: u32, } /// Append one poll to the chart, dropping the oldest past [`CHART_SECONDS`]. -pub(in crate::gui) fn push_chart(samples: &mut VecDeque, stats: &CallStats) { +pub(in crate::gui) fn push_chart(samples: &mut VecDeque, stats: &CallStats, at: Instant) { if samples.len() >= CHART_SECONDS { samples.pop_front(); } - samples.push_back(ChartSample { rtt_ms: stats.rtt_ms, recv_kbps: stats.receive_kbps }); + samples.push_back(ChartSample { at, rtt_ms: stats.rtt_ms, recv_kbps: stats.receive_kbps }); } /// A full minute of made-up samples around `stats`, for `--shot` so the graph is not empty. -pub(in crate::gui) fn seed_chart(stats: &CallStats) -> VecDeque { +pub(in crate::gui) fn seed_chart(stats: &CallStats, now: Instant) -> VecDeque { let base_rtt = stats.rtt_ms.max(1); let base_recv = stats.receive_kbps.max(1); (0..CHART_SECONDS) @@ -185,6 +186,7 @@ pub(in crate::gui) fn seed_chart(stats: &CallStats) -> VecDeque { let rtt_wobble = ((i * 37) % 11) as i32 - 5; let recv_wobble = ((i * 53) % 21) as i32 - 10; ChartSample { + at: now - Duration::from_secs((CHART_SECONDS - 1 - i) as u64), rtt_ms: (base_rtt as i32 + rtt_wobble).max(1) as u32, recv_kbps: (base_recv as i32 + recv_wobble * 2).max(1) as u32, } @@ -499,16 +501,23 @@ mod tests { #[test] fn the_chart_keeps_a_minute_and_shot_seed_fills_it() { + let start = Instant::now(); let mut samples = VecDeque::new(); for n in 0..70 { - push_chart(&mut samples, &CallStats { rtt_ms: n, receive_kbps: n * 2, ..CallStats::default() }); + push_chart( + &mut samples, + &CallStats { rtt_ms: n, receive_kbps: n * 2, ..CallStats::default() }, + start + Duration::from_secs(n as u64), + ); } assert_eq!(samples.len(), CHART_SECONDS); assert_eq!(samples.front().map(|sample| sample.rtt_ms), Some(10)); assert_eq!(samples.back().map(|sample| sample.rtt_ms), Some(69)); - let seeded = seed_chart(&CallStats { rtt_ms: 38, receive_kbps: 182, ..CallStats::default() }); + assert!(samples.back().unwrap().at > samples.front().unwrap().at); + let seeded = seed_chart(&CallStats { rtt_ms: 38, receive_kbps: 182, ..CallStats::default() }, start); assert_eq!(seeded.len(), CHART_SECONDS); assert!(seeded.iter().all(|sample| sample.rtt_ms > 0 && sample.recv_kbps > 0)); + assert_eq!(seeded.back().map(|sample| sample.at), Some(start)); } #[test] diff --git a/crates/tinyclient/src/gui/tiny/mod.rs b/crates/tinyclient/src/gui/tiny/mod.rs index 020fee5..61fe378 100644 --- a/crates/tinyclient/src/gui/tiny/mod.rs +++ b/crates/tinyclient/src/gui/tiny/mod.rs @@ -896,7 +896,7 @@ impl Shell { self.tiny_state.applied = call; #[cfg(feature = "gui-shot")] if let Some(stats) = crate::gui::call::shot_stats() { - self.tiny_state.stats_chart = health::seed_chart(&stats); + self.tiny_state.stats_chart = health::seed_chart(&stats, Instant::now()); self.tiny_state.stats = Some(stats); return; } @@ -910,7 +910,7 @@ impl Shell { match answer { Ok(Response::CallStats { stats }) => { this.tiny_state.steady.feed(&stats, Instant::now()); - health::push_chart(&mut this.tiny_state.stats_chart, &stats); + health::push_chart(&mut this.tiny_state.stats_chart, &stats, Instant::now()); this.tiny_state.stats_before = this.tiny_state.stats.replace(stats); this.tiny_state.stats_note = None; } diff --git a/crates/tinyclient/src/gui/tiny/panel.rs b/crates/tinyclient/src/gui/tiny/panel.rs index 89eaee6..032c396 100644 --- a/crates/tinyclient/src/gui/tiny/panel.rs +++ b/crates/tinyclient/src/gui/tiny/panel.rs @@ -95,7 +95,7 @@ fn meta_row(label: &'static str, value: impl IntoElement) -> Div { .child(div().type_ui().font_weight(theme::SEMIBOLD).text_color(theme::text()).child(value)) } -fn kpi(label: &'static str, value: String, unit: &'static str) -> Div { +fn kpi(label: &'static str, value: String, unit: &'static str, color: Rgba) -> Div { div() .flex_1() .min_w_0() @@ -112,14 +112,18 @@ fn kpi(label: &'static str, value: String, unit: &'static str) -> Div { .flex() .items_baseline() .gap(px(2.)) - .child(div().type_ui().font_weight(theme::SEMIBOLD).text_color(theme::positive()).child(value)) + .child(div().type_ui().font_weight(theme::SEMIBOLD).text_color(color).child(value)) .child(div().type_small().font_weight(theme::MEDIUM).text_color(theme::text_soft()).child(unit)), ) } -/// Ping (filled) and receive bitrate over the last minute. -fn health_chart(samples: Vec) -> Div { - let (now_rtt, now_recv) = samples.last().map(|sample| (sample.rtt_ms, sample.recv_kbps)).unwrap_or((0, 0)); +/// Ping (filled) and receive bitrate over the last minute. `now_*` are the same numbers the +/// KPI strip shows (smoothed ping, current receive), so the footer does not disagree with them. +fn health_chart(samples: Vec, now_rtt: Option, now_recv: u32) -> Div { + let foot = match now_rtt { + Some(rtt) => format!("Now · {rtt} ms · {now_recv} kb/s"), + None => format!("Now · — · {now_recv} kb/s"), + }; let chart = canvas( |_, _, _| (), move |bounds, (), window, _| { @@ -134,11 +138,12 @@ fn health_chart(samples: Vec) -> Div { let y = origin_y + height * frac; window.paint_quad(fill(Bounds::new(point(px(origin_x), px(y)), size(px(width), px(1.))), theme::hairline())); } - let count = samples.len(); - let span = (count.saturating_sub(1)).max(1) as f32; + let first = samples.first().map(|sample| sample.at).unwrap_or_else(std::time::Instant::now); + let last_at = samples.last().map(|sample| sample.at).unwrap_or(first); + let span = last_at.duration_since(first).as_secs_f32().max(0.001); let max_rtt = samples.iter().map(|sample| sample.rtt_ms).max().unwrap_or(1).max(1) as f32; let max_recv = samples.iter().map(|sample| sample.recv_kbps).max().unwrap_or(1).max(1) as f32; - let x_at = |index: usize| origin_x + width * (index as f32) / span; + let x_at = |sample: &ChartSample| origin_x + width * sample.at.duration_since(first).as_secs_f32() / span; let ping_y = |rtt: u32| { let t = (rtt as f32 / (max_rtt * 1.2)).clamp(0., 1.); origin_y + height * (0.42 + 0.5 * (1. - t)) @@ -149,11 +154,11 @@ fn health_chart(samples: Vec) -> Div { }; let mut area = PathBuilder::fill(); - area.move_to(point(px(x_at(0)), px(origin_y + height))); - for (index, sample) in samples.iter().enumerate() { - area.line_to(point(px(x_at(index)), px(ping_y(sample.rtt_ms)))); + area.move_to(point(px(x_at(&samples[0])), px(origin_y + height))); + for sample in &samples { + area.line_to(point(px(x_at(sample)), px(ping_y(sample.rtt_ms)))); } - area.line_to(point(px(x_at(count - 1)), px(origin_y + height))); + area.line_to(point(px(x_at(samples.last().unwrap())), px(origin_y + height))); area.close(); if let Ok(path) = area.build() { window.paint_path(path, theme::positive_soft()); @@ -161,7 +166,7 @@ fn health_chart(samples: Vec) -> Div { let mut ping = PathBuilder::stroke(px(2.)); for (index, sample) in samples.iter().enumerate() { - let at = point(px(x_at(index)), px(ping_y(sample.rtt_ms))); + let at = point(px(x_at(sample)), px(ping_y(sample.rtt_ms))); if index == 0 { ping.move_to(at); } else { @@ -174,7 +179,7 @@ fn health_chart(samples: Vec) -> Div { let mut recv = PathBuilder::stroke(px(1.75)).dash_array(&[px(3.), px(3.)]); for (index, sample) in samples.iter().enumerate() { - let at = point(px(x_at(index)), px(recv_y(sample.recv_kbps))); + let at = point(px(x_at(sample)), px(recv_y(sample.recv_kbps))); if index == 0 { recv.move_to(at); } else { @@ -186,7 +191,7 @@ fn health_chart(samples: Vec) -> Div { } if let Some(last) = samples.last() { - let cx = x_at(count - 1); + let cx = x_at(last); let cy = ping_y(last.rtt_ms); window.paint_quad(fill( Bounds::new(point(px(cx - 5.), px(cy - 5.)), size(px(10.), px(10.))), @@ -248,7 +253,7 @@ fn health_chart(samples: Vec) -> Div { .type_micro() .text_color(theme::text_soft()) .child("−60s") - .child(format!("Now · {now_rtt} ms · {now_recv} kb/s")), + .child(foot), ) } @@ -358,6 +363,7 @@ impl Shell { let room = self.tiny_page_facts().and_then(|page| page.mine.and_then(|id| page.community.rooms.iter().find(|room| room.id == id)).map(|room| (room.name.clone(), room.bitrate()))); let health = self.tiny_health().unwrap_or_default(); let grade = health.grade(); + let hints = health.hints(); let mut card = div().w(px(320.)).flex().flex_col().child( div() .pb(px(10.)) @@ -377,14 +383,14 @@ impl Shell { .child(health::bars(grade, 14.)) .child(div().type_ui().font_weight(theme::SEMIBOLD).text_color(theme::text()).child("Call health")), ) - .children(health.hints().into_iter().take(1).map(|hint| { + .children(hints.iter().take(1).map(|hint| { div() .mt(px(6.)) .flex() .items_start() .gap(px(6.)) .child(div().pt(px(1.)).child(glyph(hint.level.icon(), 12., hint.level.color()))) - .child(div().flex_1().min_w_0().whitespace_normal().type_small().text_color(hint.level.color()).child(hint.words)) + .child(div().flex_1().min_w_0().whitespace_normal().type_small().text_color(hint.level.color()).child(hint.words.clone())) })), ) .child( @@ -406,7 +412,6 @@ impl Shell { ), ); - let hints = health.hints(); if hints.len() > 1 { card = card.child( div().pb(px(8.)).mb(px(4.)).border_b_1().border_color(theme::hairline()).flex().flex_col().gap(px(6.)).children(hints.into_iter().skip(1).take(2).map(|hint| { @@ -424,17 +429,33 @@ impl Shell { Some(stats) => { let samples: Vec<_> = self.tiny_state.stats_chart.iter().copied().collect(); if !samples.is_empty() { - card = card.child(health_chart(samples)); + card = card.child(health_chart(samples, health.rtt_ms, stats.receive_kbps)); } + let known = |measured: bool| if measured { theme::positive() } else { theme::text_soft() }; card = card .child( div() .mb(px(10.)) .flex() .gap(px(8.)) - .child(kpi("Ping", format!("{}", health.rtt_ms.unwrap_or(0)), "ms")) - .child(kpi("Jitter", format!("{}", health.jitter_ms.unwrap_or(0)), "ms")) - .child(kpi("Loss", format!("{:.1}", f32::from(health.loss_permille.unwrap_or(0)) / 10.), "%")), + .child(kpi( + "Ping", + health.rtt_ms.map_or_else(|| "—".to_owned(), |ms| ms.to_string()), + "ms", + known(health.rtt_ms.is_some()), + )) + .child(kpi( + "Jitter", + health.jitter_ms.map_or_else(|| "—".to_owned(), |ms| ms.to_string()), + "ms", + known(health.jitter_ms.is_some()), + )) + .child(kpi( + "Loss", + health.loss_permille.map_or_else(|| "—".to_owned(), |n| format!("{:.1}", f32::from(n) / 10.)), + "%", + known(health.loss_permille.is_some()), + )), ) .when_some(room.as_ref(), |card, (name, kbps)| { card.child(meta_row("Channel", name.clone())).child(meta_row("Channel bitrate", format!("{kbps} kb/s")))