diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-13 17:31:14 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-13 17:31:14 +0000 |
| commit | 9b9d2a2fa2a34ca46f17b821550fc8c972671bd7 (patch) | |
| tree | 4a41b8dc1aabab95b08dd958deaa0f85bb90ae90 /src/lib/client.rs | |
| parent | e97f272db32df2a384465f48ddc3c5be1f59654c (diff) | |
fix: use force_draw to redraw bars after reveal
tick() is a no-op when enable_steady_tick() is active. Use
force_draw() on a bar to trigger a full MultiState redraw
including bars that finished while the draw target was hidden.
Diffstat (limited to 'src/lib/client.rs')
| -rw-r--r-- | src/lib/client.rs | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs index 0427501..9fd668c 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs | |||
| @@ -16,7 +16,7 @@ use std::{ | |||
| 16 | fs::create_dir_all, | 16 | fs::create_dir_all, |
| 17 | path::Path, | 17 | path::Path, |
| 18 | sync::{ | 18 | sync::{ |
| 19 | Arc, RwLock, | 19 | Arc, Mutex, RwLock, |
| 20 | atomic::{AtomicU64, Ordering}, | 20 | atomic::{AtomicU64, Ordering}, |
| 21 | }, | 21 | }, |
| 22 | time::Duration, | 22 | time::Duration, |
| @@ -407,9 +407,14 @@ impl Connect for Client { | |||
| 407 | MultiProgress::with_draw_target(ProgressDrawTarget::hidden()) | 407 | MultiProgress::with_draw_target(ProgressDrawTarget::hidden()) |
| 408 | }; | 408 | }; |
| 409 | 409 | ||
| 410 | // Collect all progress bars so the timer can force a redraw after | ||
| 411 | // switching the draw target (finished bars won't redraw on their own) | ||
| 412 | let all_bars: Arc<Mutex<Vec<ProgressBar>>> = Arc::new(Mutex::new(Vec::new())); | ||
| 413 | |||
| 410 | // Spawn a background timer that transitions from spinner to detail view | 414 | // Spawn a background timer that transitions from spinner to detail view |
| 411 | let detail_multi_for_timer = progress_reporter.clone(); | 415 | let detail_multi_for_timer = progress_reporter.clone(); |
| 412 | let spinner_for_timer = spinner_multi.as_ref().map(|(_, s)| s.clone()); | 416 | let spinner_for_timer = spinner_multi.as_ref().map(|(_, s)| s.clone()); |
| 417 | let all_bars_for_timer = all_bars.clone(); | ||
| 413 | let timer_handle = if !verbose && !is_test { | 418 | let timer_handle = if !verbose && !is_test { |
| 414 | let handle = tokio::spawn(async move { | 419 | let handle = tokio::spawn(async move { |
| 415 | tokio::time::sleep(Duration::from_millis(SPINNER_EXPAND_DELAY_MS)).await; | 420 | tokio::time::sleep(Duration::from_millis(SPINNER_EXPAND_DELAY_MS)).await; |
| @@ -428,6 +433,15 @@ impl Connect for Client { | |||
| 428 | heading.finish_with_message("fetching updates..."); | 433 | heading.finish_with_message("fetching updates..."); |
| 429 | detail_multi_for_timer | 434 | detail_multi_for_timer |
| 430 | .set_draw_target(ProgressDrawTarget::stderr()); | 435 | .set_draw_target(ProgressDrawTarget::stderr()); |
| 436 | // Force a full redraw of the multi progress (including bars | ||
| 437 | // that finished while the draw target was hidden). | ||
| 438 | // We must use force_draw() rather than tick() because tick() | ||
| 439 | // is a no-op on bars that have enable_steady_tick() active. | ||
| 440 | // A single force_draw() on any bar is sufficient since it | ||
| 441 | // triggers MultiState::draw() which renders all bars. | ||
| 442 | if let Some(bar) = all_bars_for_timer.lock().unwrap().first() { | ||
| 443 | bar.force_draw(); | ||
| 444 | } | ||
| 431 | }); | 445 | }); |
| 432 | Some(handle) | 446 | Some(handle) |
| 433 | } else { | 447 | } else { |
| @@ -502,6 +516,7 @@ impl Connect for Client { | |||
| 502 | let current_timeout_clone = current_timeout_for_loop.clone(); | 516 | let current_timeout_clone = current_timeout_for_loop.clone(); |
| 503 | let progress_reporter_clone = progress_reporter.clone(); | 517 | let progress_reporter_clone = progress_reporter.clone(); |
| 504 | let total_relays_clone = total_relays; | 518 | let total_relays_clone = total_relays; |
| 519 | let all_bars_clone = all_bars.clone(); | ||
| 505 | async move { | 520 | async move { |
| 506 | let relay_column_width = request.relay_column_width; | 521 | let relay_column_width = request.relay_column_width; |
| 507 | 522 | ||
| @@ -526,6 +541,7 @@ impl Connect for Client { | |||
| 526 | .with_style(pb_style(current_timeout_clone.clone())?), | 541 | .with_style(pb_style(current_timeout_clone.clone())?), |
| 527 | ); | 542 | ); |
| 528 | pb.enable_steady_tick(Duration::from_millis(300)); | 543 | pb.enable_steady_tick(Duration::from_millis(300)); |
| 544 | all_bars_clone.lock().unwrap().push(pb.clone()); | ||
| 529 | let pb = Some(pb); | 545 | let pb = Some(pb); |
| 530 | 546 | ||
| 531 | fn update_progress_bar_with_error( | 547 | fn update_progress_bar_with_error( |