diff --git a/src/ui/components/monitor_list.rs b/src/ui/components/monitor_list.rs index 96baf77..24f6081 100644 --- a/src/ui/components/monitor_list.rs +++ b/src/ui/components/monitor_list.rs @@ -6,11 +6,14 @@ use std::{ sync::{OnceLock, RwLock}, }; -use crate::i18n::t; -use crate::ui::dashboard::{ - MonitorStatus, MonitorViewState, - model::{BORDER_LINES_VIEW, DashboardViewState, GroupViewState}, +use crate::{ + i18n::t, + ui::dashboard::{ + MonitorStatus, MonitorViewState, + model::{BORDER_LINES_VIEW, DashboardViewState, GroupViewState}, + }, }; +use once_cell::sync::Lazy; use ratatui::{ Frame, layout::{Alignment, Constraint, Direction, Layout, Rect}, @@ -21,8 +24,17 @@ use ratatui::{ const STATUS_LINE_LENGTH: usize = 100; const MAX_NAME_LENGTH: usize = 30; -static STATUS_SPANS: OnceLock>> = OnceLock::new(); -static STATUS_LINE_CACHE: OnceLock>>>> = OnceLock::new(); + +static UP_SPAN: Lazy> = + Lazy::new(|| Span::styled("■", Style::default().fg(Color::Green))); + +static DOWN_SPAN: Lazy> = + Lazy::new(|| Span::styled("■", Style::default().fg(Color::Red))); + +static UNKNOWN_SPAN: Lazy> = + Lazy::new(|| Span::styled("■", Style::default().fg(Color::Yellow))); + +static STATUS_LINE_CACHE: OnceLock>>>> = OnceLock::new(); pub fn render_monitor_list(main_frame: &mut Frame, area: Rect, state: &mut DashboardViewState) { let available_height = area.height as usize; @@ -209,24 +221,12 @@ fn get_formated_line(text: String, color: Color, modifier: Modifier) -> Line<'st )]) } -fn get_cached_status_span(status: &MonitorStatus) -> Span<'static> { - let cache = STATUS_SPANS.get_or_init(|| { - let mut m = HashMap::new(); - m.insert( - MonitorStatus::Up, - Span::styled("■", Style::default().fg(Color::Green)), - ); - m.insert( - MonitorStatus::Down, - Span::styled("■", Style::default().fg(Color::Red)), - ); - m.insert( - MonitorStatus::Unknown, - Span::styled("■", Style::default().fg(Color::Yellow)), - ); - m - }); - cache.get(status).cloned().unwrap_or_default() +fn get_status_span(status: &MonitorStatus) -> &'static Span<'static> { + match status { + MonitorStatus::Up => &UP_SPAN, + MonitorStatus::Down => &DOWN_SPAN, + MonitorStatus::Unknown => &UNKNOWN_SPAN, + } } fn title_style() -> Style { @@ -252,27 +252,25 @@ fn get_cached_status_line(status_history: &[MonitorStatus]) -> Line<'static> { { let read = cache.read().unwrap(); if let Some(spans) = read.get(&hash) { - return Line::from(spans.clone()); + return Line::from(spans.iter().map(|&span| span.clone()).collect::>()); } } - let spans: Vec> = status_history + let spans: Vec<&'static Span<'static>> = status_history .iter() .rev() .take(STATUS_LINE_LENGTH) - .map(|status| get_cached_status_span(status)) + .map(|status| get_status_span(status)) .collect(); let mut write = cache.write().unwrap(); if write.len() > 1000 { - let keys_to_remove: Vec<_> = write.keys().take(250).copied().collect(); for key in keys_to_remove { write.remove(&key); } - } write.insert(hash, spans.clone()); - Line::from(spans) + Line::from(spans.iter().map(|&span| span.clone()).collect::>()) }