stynx_code_tui/widgets/
tool_progress.rs1use ratatui::{
2 buffer::Buffer,
3 layout::Rect,
4 style::Style,
5 text::{Line, Span},
6 widgets::{Paragraph, Widget},
7};
8
9use crate::state::{DisplayToolUse, ToolUseStatus};
10use crate::theme;
11
12const FRAMES: [char; 10] = [
13 '\u{280B}', '\u{2819}', '\u{2839}', '\u{2838}',
14 '\u{283C}', '\u{2834}', '\u{2826}', '\u{2827}',
15 '\u{2807}', '\u{280F}',
16];
17
18pub struct ToolProgress<'a> {
19 pub tool_use: &'a DisplayToolUse,
20 pub spinner_frame: usize,
21}
22
23impl<'a> ToolProgress<'a> {
24 pub fn new(tool_use: &'a DisplayToolUse, spinner_frame: usize) -> Self {
25 Self { tool_use, spinner_frame }
26 }
27}
28
29impl<'a> Widget for ToolProgress<'a> {
30 fn render(self, area: Rect, buf: &mut Buffer) {
31 let (indicator, color) = match self.tool_use.status {
32 ToolUseStatus::Running => (FRAMES[self.spinner_frame % FRAMES.len()], theme::GOLD()),
33 ToolUseStatus::Completed => ('✓', theme::FOAM()),
34 ToolUseStatus::Error => ('✗', theme::LOVE()),
35 };
36
37 let line = Line::from(vec![
38 Span::styled(format!("{indicator} "), Style::default().fg(color)),
39 Span::styled(&self.tool_use.name, Style::default().fg(theme::FOAM())),
40 Span::raw(" "),
41 Span::styled(&self.tool_use.output_preview, Style::default().fg(theme::MUTED())),
42 ]);
43
44 Paragraph::new(line).render(area, buf);
45 }
46}