use ratatui::layout::{Constraint, Direction};
use ratatui::style::Color;
use super::types::{PanelStatus, WIDE_LAYOUT_MIN_COLS};
pub fn format_uptime(secs: u64) -> String {
let hours = secs / 3600;
let minutes = (secs % 3600) / 60;
format!("{hours}h {minutes}m")
}
pub fn format_count(n: u64) -> String {
if n >= 10_000 {
let thousands = n as f64 / 1000.0;
format!("{thousands:.1}k")
} else {
group_thousands(n)
}
}
fn group_thousands(n: u64) -> String {
let digits = n.to_string();
let mut out = String::with_capacity(digits.len() + digits.len() / 3);
let bytes = digits.as_bytes();
for (i, b) in bytes.iter().enumerate() {
if i > 0 && (bytes.len() - i).is_multiple_of(3) {
out.push(',');
}
out.push(*b as char);
}
out
}
pub fn panel_layout(width: u16) -> (Direction, [Constraint; 2]) {
if width >= WIDE_LAYOUT_MIN_COLS {
(
Direction::Horizontal,
[Constraint::Percentage(50), Constraint::Percentage(50)],
)
} else {
(
Direction::Vertical,
[Constraint::Percentage(50), Constraint::Percentage(50)],
)
}
}
pub fn help_text() -> String {
[
" Tab switch focus between the search and memory panels",
" r reindex the first index of the focused search panel",
" ? toggle this help overlay",
" Esc close this help overlay",
" q quit",
"",
" Offline panels retry automatically every 5 seconds.",
]
.join("\n")
}
pub fn status_badge<T>(status: &PanelStatus<T>) -> (char, &'static str, Color) {
match status {
PanelStatus::Online(_) => ('●', "ONLINE", Color::Green),
PanelStatus::Connecting => ('◌', "CONNECTING", Color::Yellow),
PanelStatus::Offline { .. } => ('○', "OFFLINE", Color::Red),
}
}
pub fn truncate(s: &str, max: usize) -> String {
if s.chars().count() <= max {
s.to_string()
} else {
let kept: String = s.chars().take(max.saturating_sub(1)).collect();
format!("{kept}…")
}
}