use crate::theme::Theme; use agent_core::SessionStats; use permissions::Mode; use ratatui::{ layout::Rect, text::{Line, Span}, widgets::Paragraph, Frame, }; pub struct StatusBar { model: String, mode: Mode, stats: SessionStats, last_tool: Option, theme: Theme, } impl StatusBar { pub fn new(model: String, mode: Mode, theme: Theme) -> Self { Self { model, mode, stats: SessionStats::new(), last_tool: None, theme, } } pub fn update_stats(&mut self, stats: SessionStats) { self.stats = stats; } pub fn set_last_tool(&mut self, tool: String) { self.last_tool = Some(tool); } pub fn render(&self, frame: &mut Frame, area: Rect) { let elapsed = self.stats.start_time.elapsed().unwrap_or_default(); let elapsed_str = SessionStats::format_duration(elapsed); let (mode_str, mode_icon) = match self.mode { Mode::Plan => ("Plan", "🔍"), Mode::AcceptEdits => ("AcceptEdits", "✏️"), Mode::Code => ("Code", "⚡"), }; let last_tool_str = self .last_tool .as_ref() .map(|t| format!("● {}", t)) .unwrap_or_else(|| "○ idle".to_string()); // Build status line with colorful sections let separator_style = self.theme.status_bar; let mut spans = vec![ Span::styled(" ", separator_style), Span::styled(mode_icon, self.theme.status_bar), Span::styled(" ", separator_style), Span::styled(mode_str, self.theme.status_bar), Span::styled(" │ ", separator_style), Span::styled("⚙", self.theme.status_bar), Span::styled(" ", separator_style), Span::styled(&self.model, self.theme.status_bar), Span::styled(" │ ", separator_style), Span::styled( format!("{} msgs", self.stats.total_messages), self.theme.status_bar, ), Span::styled(" │ ", separator_style), Span::styled( format!("{} tools", self.stats.total_tool_calls), self.theme.status_bar, ), Span::styled(" │ ", separator_style), Span::styled( format!("~{} tok", self.stats.estimated_tokens), self.theme.status_bar, ), Span::styled(" │ ", separator_style), Span::styled("⏱", self.theme.status_bar), Span::styled(" ", separator_style), Span::styled(elapsed_str, self.theme.status_bar), Span::styled(" │ ", separator_style), Span::styled(last_tool_str, self.theme.status_bar), ]; // Add help text on the right let help_text = " ? /help "; // Calculate current length let current_len: usize = spans.iter() .map(|s| unicode_width::UnicodeWidthStr::width(s.content.as_ref())) .sum(); // Add padding let padding = area .width .saturating_sub((current_len + help_text.len()) as u16); spans.push(Span::styled(" ".repeat(padding as usize), separator_style)); spans.push(Span::styled(help_text, self.theme.status_bar)); let line = Line::from(spans); let paragraph = Paragraph::new(line); frame.render_widget(paragraph, area); } }