use std::sync::OnceLock;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Theme {
#[default]
Dark,
Light,
}
static CURRENT_THEME: OnceLock<Theme> = OnceLock::new();
pub fn init_theme(override_theme: Option<Theme>) {
let theme = override_theme.unwrap_or_else(detect_theme);
let _ = CURRENT_THEME.set(theme);
}
pub fn current_theme() -> Theme {
*CURRENT_THEME.get_or_init(detect_theme)
}
pub fn is_light_mode() -> bool {
current_theme() == Theme::Light
}
fn detect_theme() -> Theme {
if let Ok(theme_env) = std::env::var("STAKPAK_THEME") {
match theme_env.to_lowercase().as_str() {
"light" => return Theme::Light,
"dark" => return Theme::Dark,
_ => {} }
}
#[cfg(unix)]
{
use std::sync::mpsc;
use std::time::Duration;
let (tx, rx) = mpsc::channel();
std::thread::spawn(move || {
let _ = tx.send(terminal_light::luma());
});
match rx.recv_timeout(Duration::from_millis(100)) {
Ok(Ok(luma)) if luma > 0.5 => return Theme::Light,
Ok(Ok(_)) => return Theme::Dark,
Ok(Err(_)) | Err(_) => {
}
}
}
detect_theme_from_colorfgbg()
}
fn detect_theme_from_colorfgbg() -> Theme {
if let Ok(colorfgbg) = std::env::var("COLORFGBG")
&& let Some(bg_str) = colorfgbg.split(';').next_back()
&& let Ok(bg) = bg_str.trim().parse::<u8>()
{
if bg == 15 || bg == 7 {
return Theme::Light;
}
}
Theme::Dark }