diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/client.rs | 108 |
1 files changed, 100 insertions, 8 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs index 7933eaf..61a091d 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs | |||
| @@ -2451,11 +2451,84 @@ pub async fn send_events( | |||
| 2451 | } | 2451 | } |
| 2452 | } | 2452 | } |
| 2453 | 2453 | ||
| 2454 | let m = if silent { | 2454 | let verbose = is_verbose(); |
| 2455 | let is_test = std::env::var("NGITTEST").is_ok(); | ||
| 2456 | let use_concise = !verbose && !is_test && !silent && animate; | ||
| 2457 | |||
| 2458 | // Set up the two-MultiProgress pattern (same as fetch_all): | ||
| 2459 | // 1. A spinner MultiProgress shown immediately (concise mode only) | ||
| 2460 | // 2. A detail MultiProgress that starts hidden and becomes visible after a | ||
| 2461 | // delay | ||
| 2462 | let spinner_multi = if use_concise { | ||
| 2463 | let sm = MultiProgress::new(); | ||
| 2464 | let spinner = sm.add( | ||
| 2465 | ProgressBar::new_spinner() | ||
| 2466 | .with_style( | ||
| 2467 | ProgressStyle::with_template("{spinner} {msg}") | ||
| 2468 | .unwrap() | ||
| 2469 | .tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈"), | ||
| 2470 | ) | ||
| 2471 | .with_message("Publishing to nostr relays..."), | ||
| 2472 | ); | ||
| 2473 | spinner.enable_steady_tick(Duration::from_millis(100)); | ||
| 2474 | Some((sm, spinner)) | ||
| 2475 | } else { | ||
| 2476 | None | ||
| 2477 | }; | ||
| 2478 | |||
| 2479 | let m = if silent || is_test || use_concise { | ||
| 2455 | MultiProgress::with_draw_target(ProgressDrawTarget::hidden()) | 2480 | MultiProgress::with_draw_target(ProgressDrawTarget::hidden()) |
| 2456 | } else { | 2481 | } else { |
| 2457 | MultiProgress::new() | 2482 | MultiProgress::new() |
| 2458 | }; | 2483 | }; |
| 2484 | |||
| 2485 | // Pre-add a heading bar at position 0 so it has a reserved slot | ||
| 2486 | // before any relay bars are added. | ||
| 2487 | let heading_bar = if use_concise { | ||
| 2488 | let bar = | ||
| 2489 | m.add(ProgressBar::new(0).with_style(ProgressStyle::with_template("{msg}").unwrap())); | ||
| 2490 | Some(bar) | ||
| 2491 | } else { | ||
| 2492 | None | ||
| 2493 | }; | ||
| 2494 | |||
| 2495 | let reveal_state: Option<Arc<BarRevealState>> = if use_concise { | ||
| 2496 | Some(Arc::new(BarRevealState { | ||
| 2497 | revealed: AtomicBool::new(false), | ||
| 2498 | deferred: Mutex::new(Vec::new()), | ||
| 2499 | })) | ||
| 2500 | } else { | ||
| 2501 | None | ||
| 2502 | }; | ||
| 2503 | |||
| 2504 | // Spawn a background timer that transitions from spinner to detail view | ||
| 2505 | let detail_multi_for_timer = m.clone(); | ||
| 2506 | let spinner_for_timer = spinner_multi.as_ref().map(|(_, s)| s.clone()); | ||
| 2507 | let reveal_state_for_timer = reveal_state.clone(); | ||
| 2508 | let heading_bar_for_timer = heading_bar.clone(); | ||
| 2509 | let timer_handle = if use_concise { | ||
| 2510 | let handle = tokio::spawn(async move { | ||
| 2511 | tokio::time::sleep(Duration::from_millis(SPINNER_EXPAND_DELAY_MS)).await; | ||
| 2512 | if let Some(spinner) = spinner_for_timer { | ||
| 2513 | spinner.finish_and_clear(); | ||
| 2514 | } | ||
| 2515 | detail_multi_for_timer.set_draw_target(ProgressDrawTarget::stderr()); | ||
| 2516 | if let Some(heading) = heading_bar_for_timer { | ||
| 2517 | heading.finish_with_message("publishing to nostr relays..."); | ||
| 2518 | } | ||
| 2519 | if let Some(state) = reveal_state_for_timer { | ||
| 2520 | let mut deferred = state.deferred.lock().unwrap(); | ||
| 2521 | state.revealed.store(true, Ordering::Release); | ||
| 2522 | for df in deferred.drain(..) { | ||
| 2523 | df.bar.finish_with_message(df.message); | ||
| 2524 | } | ||
| 2525 | } | ||
| 2526 | }); | ||
| 2527 | Some(handle) | ||
| 2528 | } else { | ||
| 2529 | None | ||
| 2530 | }; | ||
| 2531 | |||
| 2459 | let pb_style = ProgressStyle::with_template(if animate { | 2532 | let pb_style = ProgressStyle::with_template(if animate { |
| 2460 | " {spinner} {prefix} {bar} {pos}/{len} {msg}" | 2533 | " {spinner} {prefix} {bar} {pos}/{len} {msg}" |
| 2461 | } else { | 2534 | } else { |
| @@ -2484,7 +2557,17 @@ pub async fn send_events( | |||
| 2484 | })?; | 2557 | })?; |
| 2485 | 2558 | ||
| 2486 | #[allow(clippy::borrow_deref_ref)] | 2559 | #[allow(clippy::borrow_deref_ref)] |
| 2487 | join_all(relays.iter().map(|&relay| async { | 2560 | join_all(relays.iter().map(|&relay| { |
| 2561 | let reveal_state_clone = reveal_state.clone(); | ||
| 2562 | let my_write_relays = my_write_relays.clone(); | ||
| 2563 | let repo_read_relays = repo_read_relays.clone(); | ||
| 2564 | let fallback = fallback.clone(); | ||
| 2565 | let m = m.clone(); | ||
| 2566 | let events = events.clone(); | ||
| 2567 | let pb_style = pb_style.clone(); | ||
| 2568 | let pb_after_style_failed = pb_after_style_failed.clone(); | ||
| 2569 | let pb_after_style_succeeded = pb_after_style_succeeded.clone(); | ||
| 2570 | async move { | ||
| 2488 | let relay_clean = remove_trailing_slash(relay); | 2571 | let relay_clean = remove_trailing_slash(relay); |
| 2489 | let details = format!( | 2572 | let details = format!( |
| 2490 | "{}{}{} {}", | 2573 | "{}{}{} {}", |
| @@ -2532,8 +2615,7 @@ pub async fn send_events( | |||
| 2532 | Ok(_) => pb.inc(1), | 2615 | Ok(_) => pb.inc(1), |
| 2533 | Err(e) => { | 2616 | Err(e) => { |
| 2534 | pb.set_style(pb_after_style_failed.clone()); | 2617 | pb.set_style(pb_after_style_failed.clone()); |
| 2535 | pb.finish_with_message( | 2618 | let msg = console::style(format!( |
| 2536 | console::style(format!( | ||
| 2537 | "error: {}", | 2619 | "error: {}", |
| 2538 | e.to_string() | 2620 | e.to_string() |
| 2539 | .replace("relay pool error:", "") | 2621 | .replace("relay pool error:", "") |
| @@ -2541,8 +2623,8 @@ pub async fn send_events( | |||
| 2541 | )) | 2623 | )) |
| 2542 | .for_stderr() | 2624 | .for_stderr() |
| 2543 | .red() | 2625 | .red() |
| 2544 | .to_string(), | 2626 | .to_string(); |
| 2545 | ); | 2627 | finish_bar(&pb, msg, &reveal_state_clone); |
| 2546 | failed = true; | 2628 | failed = true; |
| 2547 | break; | 2629 | break; |
| 2548 | } | 2630 | } |
| @@ -2550,10 +2632,20 @@ pub async fn send_events( | |||
| 2550 | } | 2632 | } |
| 2551 | if !failed { | 2633 | if !failed { |
| 2552 | pb.set_style(pb_after_style_succeeded.clone()); | 2634 | pb.set_style(pb_after_style_succeeded.clone()); |
| 2553 | pb.finish_with_message(""); | 2635 | finish_bar(&pb, String::new(), &reveal_state_clone); |
| 2554 | } | 2636 | } |
| 2555 | })) | 2637 | }})) |
| 2556 | .await; | 2638 | .await; |
| 2639 | |||
| 2640 | // Cancel the background timer if it hasn't fired yet, and clean up | ||
| 2641 | // the spinner. If the timer already fired, the abort is a no-op. | ||
| 2642 | if let Some(handle) = timer_handle { | ||
| 2643 | handle.abort(); | ||
| 2644 | } | ||
| 2645 | if let Some((_, spinner)) = &spinner_multi { | ||
| 2646 | spinner.finish_and_clear(); | ||
| 2647 | } | ||
| 2648 | |||
| 2557 | Ok(()) | 2649 | Ok(()) |
| 2558 | } | 2650 | } |
| 2559 | 2651 | ||