add pulsing dot loading state (#4736)
## Description Changes default CLI spinner to pulsing dot https://github.com/user-attachments/assets/b81225d6-6655-4ead-8cb1-d6568a603d5b ## Tests Passes CI --------- Co-authored-by: Fouad Matin <fouad@openai.com>
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
source: tui/src/chatwidget/tests.rs
|
||||
expression: blob1
|
||||
---
|
||||
⠋ Exploring
|
||||
• Exploring
|
||||
└ List ls -la
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
source: tui/src/chatwidget/tests.rs
|
||||
expression: blob3
|
||||
---
|
||||
⠋ Exploring
|
||||
• Exploring
|
||||
└ List ls -la
|
||||
Read foo.txt
|
||||
|
||||
@@ -116,12 +116,10 @@ pub(crate) fn output_lines(
|
||||
}
|
||||
|
||||
pub(crate) fn spinner(start_time: Option<Instant>) -> Span<'static> {
|
||||
const FRAMES: &[char] = &['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
||||
let idx = start_time
|
||||
.map(|st| ((st.elapsed().as_millis() / 100) as usize) % FRAMES.len())
|
||||
.unwrap_or(0);
|
||||
let ch = FRAMES[idx];
|
||||
ch.to_string().into()
|
||||
let blink_on = start_time
|
||||
.map(|st| ((st.elapsed().as_millis() / 600) % 2) == 0)
|
||||
.unwrap_or(false);
|
||||
if blink_on { "•".into() } else { "◦".dim() }
|
||||
}
|
||||
|
||||
impl HistoryCell for ExecCell {
|
||||
|
||||
@@ -3,4 +3,4 @@ source: tui/src/history_cell.rs
|
||||
assertion_line: 1740
|
||||
expression: rendered
|
||||
---
|
||||
⠋ Calling search.find_docs({"query":"ratatui styling","limit":3})
|
||||
• Calling search.find_docs({"query":"ratatui styling","limit":3})
|
||||
|
||||
@@ -134,12 +134,16 @@ impl StatusIndicatorWidget {
|
||||
self.frame_requester.schedule_frame();
|
||||
}
|
||||
|
||||
fn elapsed_seconds_at(&self, now: Instant) -> u64 {
|
||||
fn elapsed_duration_at(&self, now: Instant) -> Duration {
|
||||
let mut elapsed = self.elapsed_running;
|
||||
if !self.is_paused {
|
||||
elapsed += now.saturating_duration_since(self.last_resume_at);
|
||||
}
|
||||
elapsed.as_secs()
|
||||
elapsed
|
||||
}
|
||||
|
||||
fn elapsed_seconds_at(&self, now: Instant) -> u64 {
|
||||
self.elapsed_duration_at(now).as_secs()
|
||||
}
|
||||
|
||||
pub fn elapsed_seconds(&self) -> u64 {
|
||||
@@ -156,11 +160,18 @@ impl WidgetRef for StatusIndicatorWidget {
|
||||
// Schedule next animation frame.
|
||||
self.frame_requester
|
||||
.schedule_frame_in(Duration::from_millis(32));
|
||||
let elapsed = self.elapsed_seconds();
|
||||
let pretty_elapsed = fmt_elapsed_compact(elapsed);
|
||||
let now = Instant::now();
|
||||
let elapsed_duration = self.elapsed_duration_at(now);
|
||||
let pretty_elapsed = fmt_elapsed_compact(elapsed_duration.as_secs());
|
||||
let blink_on = (elapsed_duration.as_millis() / 600).is_multiple_of(2);
|
||||
|
||||
// Plain rendering: no borders or padding so the live cell is visually indistinguishable from terminal scrollback.
|
||||
let mut spans = vec!["• ".dim()];
|
||||
let mut spans = Vec::with_capacity(5);
|
||||
if blink_on {
|
||||
spans.push("• ".into());
|
||||
} else {
|
||||
spans.push("◦ ".dim());
|
||||
}
|
||||
spans.extend(shimmer_spans(&self.header));
|
||||
spans.extend(vec![
|
||||
" ".into(),
|
||||
|
||||
Reference in New Issue
Block a user