stynx_code_tui/widgets/
status_bar.rs1use ratatui::{
2 buffer::Buffer,
3 layout::Rect,
4 style::{Modifier, Style},
5 text::{Line, Span},
6 widgets::{Paragraph, Widget},
7};
8
9use crate::widgets::spinner::FRAMES;
10use crate::theme;
11
12pub struct StatusBar<'a> {
13 pub model: &'a str,
14 pub mode: &'a str,
15 pub cost: f64,
16 pub git_branch: Option<&'a str>,
17 pub is_streaming: bool,
18 pub spinner_frame: usize,
19}
20
21impl<'a> StatusBar<'a> {
22 pub fn new(model: &'a str, mode: &'a str, cost: f64, git_branch: Option<&'a str>, is_streaming: bool, spinner_frame: usize) -> Self {
23 Self { model, mode, cost, git_branch, is_streaming, spinner_frame }
24 }
25}
26
27impl<'a> Widget for StatusBar<'a> {
28 fn render(self, area: Rect, buf: &mut Buffer) {
29 for x in area.x..area.x + area.width {
30 buf[(x, area.y)].set_style(Style::default().bg(theme::SURFACE()));
31 }
32
33 let sep = Span::styled(" · ", Style::default().fg(theme::HL_HIGH()).bg(theme::SURFACE()));
34
35 let mode_span = if self.is_streaming {
36 let ch = FRAMES[self.spinner_frame % FRAMES.len()];
37 Span::styled(format!("{ch} generating"), Style::default().fg(theme::IRIS()).bg(theme::SURFACE()).add_modifier(Modifier::ITALIC))
38 } else {
39 let (icon, color) = match self.mode {
40 "Auto-accept" => ("⚡ ", theme::GOLD()),
41 "Plan" => ("◆ ", theme::IRIS()),
42 "Bypass" => ("⚠ ", theme::LOVE()),
43 _ => ("● ", theme::FOAM()),
44 };
45 Span::styled(format!("{icon}{}", self.mode), Style::default().fg(color).bg(theme::SURFACE()))
46 };
47
48 let mut spans = vec![
49 Span::styled(" ", Style::default().bg(theme::SURFACE())),
50 Span::styled(self.model, Style::default().fg(theme::FOAM()).bg(theme::SURFACE()).add_modifier(Modifier::BOLD)),
51 sep.clone(),
52 mode_span,
53 sep.clone(),
54 Span::styled(format!("${:.4}", self.cost), Style::default().fg(theme::IRIS()).bg(theme::SURFACE())),
55 ];
56
57 if let Some(branch) = self.git_branch {
58 spans.push(sep);
59 spans.push(Span::styled(
60 format!("\u{E0A0} {branch}"),
61 Style::default().fg(theme::PINE()).bg(theme::SURFACE()),
62 ));
63 }
64
65 Paragraph::new(Line::from(spans)).render(area, buf);
66 }
67}