Skip to main content

stynx_code_tui/widgets/
tool_progress.rs

1use 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}