use ratatui::{
Frame,
prelude::Rect,
style::{Modifier, Style},
text::{Line, Span},
widgets::Paragraph,
};
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
use crate::i18n;
use crate::state::AppState;
use crate::theme::{KeyChord, theme};
#[allow(clippy::missing_const_for_fn)]
pub fn render_status(f: &mut Frame, app: &mut AppState, area: Rect) {
let th = theme();
let key_label_opt = app
.keymap
.search_normal_open_status
.first()
.map(KeyChord::label);
let show_key = matches!(app.focus, crate::state::Focus::Search)
&& app.search_normal_mode
&& key_label_opt.is_some();
let status_text = if show_key {
i18n::t_fmt(
app,
"app.results.status_with_key",
&[
&app.arch_status_text,
&key_label_opt.expect("key_label_opt should be Some when show_key is true"),
],
)
} else {
format!(
"{} {}",
i18n::t(app, "app.results.status_label"),
app.arch_status_text
)
};
let sx = area.x.saturating_add(2); let sy = area.y.saturating_add(area.height.saturating_sub(1));
let maxw = area.width.saturating_sub(4); let mut content = status_text;
if u16::try_from(content.width()).unwrap_or(u16::MAX) > maxw {
let mut truncated = String::new();
let mut width_so_far = 0u16;
for ch in content.chars() {
let ch_width = u16::try_from(ch.width().unwrap_or(0)).unwrap_or(u16::MAX);
if width_so_far + ch_width > maxw {
break;
}
truncated.push(ch);
width_so_far += ch_width;
}
content = truncated;
}
let mut dot = "";
let mut dot_color = th.overlay1;
match app.arch_status_color {
crate::state::ArchStatusColor::Operational => {
dot = "●";
dot_color = th.green;
}
crate::state::ArchStatusColor::IncidentToday => {
dot = "●";
dot_color = th.yellow;
}
crate::state::ArchStatusColor::IncidentSevereToday => {
dot = "●";
dot_color = th.red;
}
crate::state::ArchStatusColor::None => {
if app
.arch_status_text
.to_lowercase()
.contains("arch systems nominal")
{
dot = "●";
dot_color = th.green;
}
}
}
let style_text = Style::default()
.fg(th.mauve)
.bg(th.base)
.add_modifier(Modifier::BOLD | Modifier::UNDERLINED);
let line = Paragraph::new(Line::from(vec![
Span::styled(
dot.to_string(),
Style::default()
.fg(dot_color)
.bg(th.base)
.add_modifier(Modifier::BOLD),
),
Span::raw(" "),
Span::styled(content.clone(), style_text),
]));
let dot_width = u16::try_from(dot.width()).unwrap_or(u16::MAX);
let content_width = u16::try_from(content.width()).unwrap_or(u16::MAX);
let cw = (content_width + dot_width + 1).min(maxw); let pad_left = maxw.saturating_sub(cw) / 2;
let start_x = sx.saturating_add(pad_left);
let click_start_x = start_x.saturating_add(dot_width + 1);
app.arch_status_rect = Some((
click_start_x,
sy,
content_width.min(maxw.saturating_sub(dot_width + 1)),
1,
));
let rect = ratatui::prelude::Rect {
x: start_x,
y: sy,
width: cw,
height: 1,
};
f.render_widget(line, rect);
}