Skip to content

Commit 323a184

Browse files
committed
showing a min 1 bar red if there is any packet loss above 0%
1 parent ce2add4 commit 323a184

1 file changed

Lines changed: 59 additions & 23 deletions

File tree

src/tui/dashboard.rs

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -364,22 +364,6 @@ pub fn draw_dashboard(area: Rect, f: &mut Frame, state: &UiState) {
364364
let lost = udp_sent.saturating_sub(safe_received);
365365
let pending = safe_total.saturating_sub(udp_sent);
366366

367-
let bar_width = udp_inner.width.saturating_sub(70) as usize;
368-
let bar_width = bar_width.max(10);
369-
370-
// Ensure any loss shows at least one red segment
371-
let lost_units = if lost > 0 {
372-
((lost as f64 / safe_total as f64) * bar_width as f64).ceil().max(1.0) as usize
373-
} else {
374-
0
375-
};
376-
let recv_units = ((safe_received as f64 / safe_total as f64) * bar_width as f64).floor() as usize;
377-
let pending_units = bar_width.saturating_sub(recv_units + lost_units);
378-
379-
let bar_recv = "█".repeat(recv_units);
380-
let bar_lost = "█".repeat(lost_units);
381-
let bar_pending = "░".repeat(pending_units);
382-
383367
let rtt_str = udp_latest_rtt
384368
.map(|v| format!("{:.0}ms", v))
385369
.unwrap_or_else(|| "-".to_string());
@@ -398,6 +382,58 @@ pub fn draw_dashboard(area: Rect, f: &mut Frame, state: &UiState) {
398382
})
399383
.unwrap_or(("", String::new(), String::new(), String::new()));
400384

385+
// Calculate text width before the bar
386+
let mut pre_bar_width: usize = 0;
387+
pre_bar_width += udp_status.len() + 1; // status + space
388+
if !quality_label.is_empty() {
389+
pre_bar_width += quality_label.len();
390+
if !mos_str.is_empty() {
391+
pre_bar_width += 2 + mos_str.len() + 2; // " (" + mos + ") "
392+
} else {
393+
pre_bar_width += 1; // space
394+
}
395+
}
396+
let loss_str = format!("loss {:.1}%", udp_loss_pct);
397+
let rtt_display = format!("rtt {}", rtt_str);
398+
pre_bar_width += loss_str.len() + 1 + rtt_display.len(); // loss + space + rtt
399+
if !jitter_str.is_empty() {
400+
pre_bar_width += 1 + jitter_str.len();
401+
}
402+
if !reorder_str.is_empty() && state.phase != crate::model::Phase::PacketLoss {
403+
pre_bar_width += 1 + reorder_str.len();
404+
}
405+
pre_bar_width += 2; // " " before bar
406+
407+
// Calculate text width after the bar
408+
let ok_str = format!("ok {}", safe_received);
409+
let lost_str = format!("lost {}", lost);
410+
let mut post_bar_width: usize = 2 + ok_str.len() + 1 + lost_str.len(); // " " + ok + " " + lost
411+
if pending > 0 {
412+
post_bar_width += format!(" pending {}", pending).len();
413+
}
414+
415+
// Calculate bar width from remaining space
416+
let total_text_width = pre_bar_width + post_bar_width;
417+
let available_width = udp_inner.width as usize;
418+
let bar_width = if available_width > total_text_width + 5 {
419+
available_width - total_text_width
420+
} else {
421+
10 // minimum bar width
422+
};
423+
424+
// Ensure any loss shows at least one red segment
425+
let lost_units = if lost > 0 {
426+
((lost as f64 / safe_total as f64) * bar_width as f64).ceil().max(1.0) as usize
427+
} else {
428+
0
429+
};
430+
let recv_units = ((safe_received as f64 / safe_total as f64) * bar_width as f64).floor() as usize;
431+
let pending_units = bar_width.saturating_sub(recv_units + lost_units);
432+
433+
let bar_recv = "█".repeat(recv_units);
434+
let bar_lost = "█".repeat(lost_units);
435+
let bar_pending = "░".repeat(pending_units);
436+
401437
let mut spans = vec![
402438
Span::styled(udp_status, Style::default().fg(Color::Yellow)),
403439
Span::raw(" "),
@@ -409,7 +445,7 @@ pub fn draw_dashboard(area: Rect, f: &mut Frame, state: &UiState) {
409445
spans.push(Span::styled(quality_label, Style::default().fg(label_color)));
410446
if !mos_str.is_empty() {
411447
spans.push(Span::raw(" ("));
412-
spans.push(Span::styled(mos_str, Style::default().fg(label_color)));
448+
spans.push(Span::styled(&mos_str, Style::default().fg(label_color)));
413449
spans.push(Span::raw(") "));
414450
} else {
415451
spans.push(Span::raw(" "));
@@ -418,21 +454,21 @@ pub fn draw_dashboard(area: Rect, f: &mut Frame, state: &UiState) {
418454

419455
spans.extend(vec![
420456
Span::styled(
421-
format!("loss {:.1}%", udp_loss_pct),
457+
loss_str,
422458
Style::default().fg(if udp_loss_pct == 0.0 { Color::Green } else if udp_loss_pct < 2.5 { Color::Yellow } else { Color::Red }),
423459
),
424460
Span::raw(" "),
425-
Span::styled(format!("rtt {}", rtt_str), Style::default().fg(Color::Gray)),
461+
Span::styled(rtt_display, Style::default().fg(Color::Gray)),
426462
]);
427463

428464
// Add jitter and reorder when available
429465
if !jitter_str.is_empty() {
430466
spans.push(Span::raw(" "));
431-
spans.push(Span::styled(jitter_str, Style::default().fg(Color::Gray)));
467+
spans.push(Span::styled(&jitter_str, Style::default().fg(Color::Gray)));
432468
}
433469
if !reorder_str.is_empty() && state.phase != crate::model::Phase::PacketLoss {
434470
spans.push(Span::raw(" "));
435-
spans.push(Span::styled(reorder_str, Style::default().fg(Color::Gray)));
471+
spans.push(Span::styled(&reorder_str, Style::default().fg(Color::Gray)));
436472
}
437473

438474
spans.extend(vec![
@@ -441,9 +477,9 @@ pub fn draw_dashboard(area: Rect, f: &mut Frame, state: &UiState) {
441477
Span::styled(bar_lost, Style::default().fg(Color::Red)),
442478
Span::styled(bar_pending, Style::default().fg(Color::DarkGray)),
443479
Span::raw(" "),
444-
Span::styled(format!("ok {}", safe_received), Style::default().fg(Color::Green)),
480+
Span::styled(ok_str, Style::default().fg(Color::Green)),
445481
Span::raw(" "),
446-
Span::styled(format!("lost {}", lost), Style::default().fg(Color::Red)),
482+
Span::styled(lost_str, Style::default().fg(Color::Red)),
447483
]);
448484

449485
if pending > 0 {

0 commit comments

Comments
 (0)