Files
zesdex/src/view/status.rs
T

71 lines
2.6 KiB
Rust
Raw Normal View History

//! Status bar rendering for the TUI.
//!
//! Flow: `draw_status_bar` reads live connection/turn state off
//! `AppStateRest` every frame and paints a single-line bar at the top
//! (or bottom, per layout) of the screen showing agent status, provider,
//! and model.
//!
//! Why: kept as one small, self-contained render function rather than a
//! widget struct, matching the other `view/*` modules' functional style.
use ratatui::layout::Rect;
use ratatui::style::{Style, Modifier};
use ratatui::text::{Line, Span};
use ratatui::widgets::Block;
use ratatui::Frame;
use super::theme::Theme;
/// Render the single-line status bar showing connection state, provider, and model.
///
/// Flow: derive an agent status label/color from turn-in-flight and API
/// connection state → build left ([zesdex] STATUS) and right
/// (provider · model) span groups → render as one styled Line.
///
/// Return: nothing; draws directly into `frame` at `area`.
pub fn draw_status_bar(frame: &mut Frame, area: Rect, state: &crate::app::state::rest::AppStateRest) {
// Connection status — reflects actual agent readiness:
// PROG → turn is in flight
// READY → connected and ready
// NOAPI → disconnected
let spinner_frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
let (agent_status, conn_color) = if state.turn_in_flight() {
let frame = spinner_frames[(state.misc.tick_count as usize / 2) % spinner_frames.len()];
(format!("{} PROG", frame), Theme::MODE_YOLO)
} else if state.misc.api_connected {
("READY".to_string(), Theme::MODE_AUTO)
} else {
("NOAPI".to_string(), Theme::DIM)
};
let status = Span::styled(
format!(" {} ", agent_status),
Style::default()
.fg(if agent_status == "NOAPI" { Theme::DIM } else { Theme::BG })
.bg(conn_color)
.add_modifier(Modifier::BOLD),
);
// Left chunk: [zesdex] STATUS
let mut spans = vec![
Span::styled(" [zesdex] ", Style::default().fg(Theme::TEXT).add_modifier(Modifier::BOLD)),
status,
];
// Right chunk: provider · model
spans.push(Span::styled(
format!(" {} · {} ", state.settings.provider, state.settings.model),
Style::default().fg(Theme::DIM),
));
let line = Line::from(spans);
let block = Block::default()
.style(
Style::default()
.bg(Theme::STATUS_BAR_BG)
.fg(Theme::TEXT),
);
let paragraph = ratatui::widgets::Paragraph::new(line).block(block);
frame.render_widget(paragraph, area);
}