Implementing auto refresh

This commit is contained in:
Marco De Araujo 2025-12-24 19:05:20 -04:00
parent 4f9ced3e29
commit 2819df185e
7 changed files with 27 additions and 23 deletions

View file

@ -30,5 +30,6 @@ pub fn unify_data(status_page: &StatusPageResponse, heartbeat: &HeartbeatRespons
title: status_page.config.title.clone(), title: status_page.config.title.clone(),
description: status_page.config.description.clone(), description: status_page.config.description.clone(),
monitors, monitors,
audo_refresh_interval: status_page.config.auto_refresh_interval,
} }
} }

View file

@ -13,4 +13,5 @@ pub struct UnifiedData {
pub title: String, pub title: String,
pub description: Option<String>, pub description: Option<String>,
pub monitors: Vec<UnifiedMonitorData>, pub monitors: Vec<UnifiedMonitorData>,
pub audo_refresh_interval: u32,
} }

View file

@ -23,3 +23,5 @@ update-fail = Failed to update data: {error}
now = Now now = Now
uptime = Uptime uptime = Uptime
history = History history = History
auto-update-enabled = Auto-update enabled ({interval} min)
update-failed = Update failed: {error}

View file

@ -23,3 +23,5 @@ auto-update-failed = Falha na atualização automática
update-fail = Falha ao atualizar dados update-fail = Falha ao atualizar dados
now = Agora now = Agora
history = Historico history = Historico
auto-update-enabled = Auto-atualização ativada ({interval} min)
update-failed = Falha na atualização: {error}

View file

@ -25,6 +25,8 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
const INITIAL_INTERVAL: u32 = 300;
pub struct App { pub struct App {
state: DashboardViewState, state: DashboardViewState,
terminal: Terminal<CrosstermBackend<io::Stdout>>, terminal: Terminal<CrosstermBackend<io::Stdout>>,
@ -157,11 +159,15 @@ impl App {
self.state.is_loading = true; self.state.is_loading = true;
self.render(); self.render();
if let Err(e) = self.fetch_and_update_data() { match self.fetch_and_update_data() {
let mut error = HashMap::new(); Ok(()) => {
error.insert("error", e.to_string()); self.update_interval = Duration::from_secs(self.state.auto_refresh_interval as u64)
}
self.state.error_message = Some(t_with_args("update-fail", &error)) Err(e) => {
let mut error = HashMap::new();
error.insert("error", e.to_string());
self.state.error_message = Some(t_with_args("update-fail", &error));
}
} }
self.state.is_loading = false; self.state.is_loading = false;
@ -175,12 +181,14 @@ impl App {
let state = DashboardViewState::new(); let state = DashboardViewState::new();
let initial_interval = Duration::from_secs(INITIAL_INTERVAL as u64);
Ok(Self { Ok(Self {
state, state,
terminal, terminal,
should_quit: false, should_quit: false,
last_update: Instant::now(), last_update: Instant::now(),
update_interval: Duration::from_secs(30), update_interval: initial_interval,
endpoints, endpoints,
client: UptimeKumaClient::new(), client: UptimeKumaClient::new(),
}) })
@ -195,7 +203,9 @@ impl App {
} }
fn load_initial_data(&mut self) -> io::Result<()> { fn load_initial_data(&mut self) -> io::Result<()> {
self.refresh_data() self.refresh_data()?;
self.update_interval = Duration::from_secs(self.state.auto_refresh_interval as u64);
Ok(())
} }
pub fn run(&mut self) -> io::Result<()> { pub fn run(&mut self) -> io::Result<()> {

View file

@ -30,7 +30,7 @@ pub fn render_monitor_list(frame: &mut Frame, area: Rect, state: &DashboardViewS
Constraint::Length(MAX_NAME_LENGTH as u16), Constraint::Length(MAX_NAME_LENGTH as u16),
Constraint::Length(10), Constraint::Length(10),
Constraint::Length(10), Constraint::Length(10),
Constraint::Length(STATUS_LINE_LENGTH as u16 + 16), Constraint::Length(STATUS_LINE_LENGTH as u16 + 8),
]; ];
let available_height = area.height.saturating_sub(2); let available_height = area.height.saturating_sub(2);
@ -118,26 +118,11 @@ fn create_status_line_spans(status_history: &[MonitorStatus]) -> Line<'_> {
.take(STATUS_LINE_LENGTH) .take(STATUS_LINE_LENGTH)
.collect(); .collect();
spans.push(Span::styled(
"(1h)",
Style::default()
.fg(Color::Gray)
.add_modifier(Modifier::ITALIC),
));
spans.push(Span::raw(" "));
for status in recent_status.iter().rev() { for status in recent_status.iter().rev() {
let c = get_status_char(status); let c = get_status_char(status);
let color = get_status_color(status); let color = get_status_color(status);
spans.push(Span::styled(c.to_string(), Style::default().fg(color))); spans.push(Span::styled(c.to_string(), Style::default().fg(color)));
} }
spans.push(Span::raw(" "));
spans.push(Span::styled(
t("now"),
Style::default()
.fg(Color::Gray)
.add_modifier(Modifier::ITALIC),
));
Line::from(spans) Line::from(spans)
} }

View file

@ -28,6 +28,7 @@ pub struct DashboardViewState {
pub monitors: Vec<MonitorViewState>, pub monitors: Vec<MonitorViewState>,
pub is_loading: bool, pub is_loading: bool,
pub error_message: Option<String>, pub error_message: Option<String>,
pub auto_refresh_interval: u32,
} }
impl DashboardViewState { impl DashboardViewState {
@ -38,6 +39,7 @@ impl DashboardViewState {
monitors: Vec::new(), monitors: Vec::new(),
is_loading: true, is_loading: true,
error_message: None, error_message: None,
auto_refresh_interval: 300,
} }
} }
@ -91,6 +93,7 @@ impl DashboardViewState {
monitors, monitors,
is_loading: false, is_loading: false,
error_message: None, error_message: None,
auto_refresh_interval: data.audo_refresh_interval,
} }
} }
} }