use crate::{
mods::ModListValidationResult, traits::LogIfErr, validate, widgets::ModListing, ModMetaData,
};
use eframe::egui::{Response, Ui, Widget};
use egui_extras::{Column, TableBuilder};
use std::{
cell::RefCell,
collections::HashMap,
rc::Rc,
sync::{Arc, Mutex},
time::SystemTime,
};
pub const UPDATE_FREQUENCY_MS: u128 = 1000;
#[derive(Debug)]
pub struct Status<'a> {
active_mods: Rc<RefCell<ModListing<'a>>>,
mmd: Arc<Mutex<HashMap<String, ModMetaData>>>,
latest: Option<ModListValidationResult>,
last_updated: SystemTime,
}
impl<'a> Status<'a> {
#[must_use]
pub fn new(
active_mods: Rc<RefCell<ModListing<'a>>>,
mmd: Arc<Mutex<HashMap<String, ModMetaData>>>,
) -> Self {
Self {
active_mods,
mmd,
latest: None,
last_updated: SystemTime::UNIX_EPOCH,
}
}
fn update(&mut self) {
let mods: Vec<_> = self
.active_mods
.borrow()
.items
.iter()
.map(|item| item.package_id.clone())
.collect();
self.latest = Some(validate(&self.mmd, &mods));
}
fn display(ui: &mut Ui, res: &ModListValidationResult) {
let w = ui.available_width() / 2.0;
let h = 16.0;
TableBuilder::new(ui)
.column(Column::exact(w))
.column(Column::remainder())
.body(|mut body| {
body.row(h, |mut row| {
row.col(|ui| {
ui.label(format!("Warnings: {}", res.warnings().map_or(0, Vec::len)));
});
row.col(|ui| {
ui.label(format!("Errors: {}", res.errors().map_or(0, Vec::len)));
});
});
});
}
}
impl Widget for &mut Status<'_> {
fn ui(self, ui: &mut Ui) -> Response {
if let Some(elapsed) = self.last_updated.elapsed().log_if_err() {
if elapsed.as_millis() > UPDATE_FREQUENCY_MS {
self.update();
}
}
ui.scope(|ui| {
if let Some(res) = self.latest.as_ref() {
Status::display(ui, res);
}
})
.response
}
}