use chrono::{DateTime, Utc};
use ratatui::style::Color;
use std::collections::HashMap;
use crate::providers;
pub struct Theme {
pub primary: Color,
pub secondary: Color,
pub accent: Color,
pub background: Color,
#[allow(dead_code)]
pub surface: Color,
pub text: Color,
pub text_dim: Color,
pub success: Color,
pub warning: Color,
pub error: Color,
pub border: Color,
pub border_focused: Color,
pub highlight: Color,
pub provider_colors: HashMap<&'static str, Color>,
}
impl Default for Theme {
fn default() -> Self {
let palette = [
Color::Rgb(150, 80, 0),
Color::Green,
Color::Magenta,
Color::Blue,
Color::Cyan,
Color::Rgb(0, 128, 255),
Color::Rgb(255, 165, 0),
Color::Rgb(128, 0, 128),
Color::Rgb(0, 150, 136),
Color::Rgb(233, 30, 99),
];
let mut provider_colors = HashMap::new();
for (i, id) in providers::all_provider_ids().iter().enumerate() {
provider_colors.insert(*id, palette[i % palette.len()]);
}
Self {
primary: Color::Blue,
secondary: Color::Blue,
accent: Color::Magenta,
background: Color::White,
surface: Color::White,
text: Color::Black,
text_dim: Color::Black,
success: Color::Green,
warning: Color::Rgb(184, 92, 0),
error: Color::Red,
border: Color::Black,
border_focused: Color::Blue,
highlight: Color::Rgb(220, 235, 255),
provider_colors,
}
}
}
impl Theme {
pub fn provider_color(&self, provider_id: &str) -> Color {
self.provider_colors
.get(provider_id)
.copied()
.unwrap_or(self.text_dim)
}
}
pub fn format_relative_time(timestamp: Option<i64>) -> String {
let Some(ts) = timestamp else {
return "-".to_string();
};
let now = Utc::now().timestamp();
let diff = now - ts;
if diff < 60 {
"just now".to_string()
} else if diff < 3600 {
format!("{} minutes ago", diff / 60)
} else if diff < 86400 {
format!("{} hours ago", diff / 3600)
} else if diff < 604800 {
format!("{} days ago", diff / 86400)
} else {
let dt = DateTime::<Utc>::from_timestamp(ts, 0);
dt.map(|d| d.format("%Y-%m-%d").to_string())
.unwrap_or_else(|| "-".to_string())
}
}
pub fn truncate(s: &str, max_chars: usize) -> String {
let count = s.chars().count();
if count <= max_chars {
s.to_string()
} else {
let mut result: String = s.chars().take(max_chars - 3).collect();
result.push_str("...");
result
}
}