diff --git a/Cargo.lock b/Cargo.lock index 3536715b..f71dcb80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3458,6 +3458,7 @@ dependencies = [ "serde", "serde-wasm-bindgen", "serde_json", + "time 0.3.28", "typhon-types", "wasm-bindgen-futures", "web-sys", diff --git a/Cargo.toml b/Cargo.toml index eb6c0f53..d860c275 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ sha256 = "1.1" stderrlog = "0.5" substring = "1.4" surf = "2.3" +time = "0.3" tokio = { version = "1.22", features = ["full"] } wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = ["Navigator", "Clipboard", "ReadableStream", "Response"] } diff --git a/typhon-webapp/Cargo.toml b/typhon-webapp/Cargo.toml index 34069668..77c06389 100644 --- a/typhon-webapp/Cargo.toml +++ b/typhon-webapp/Cargo.toml @@ -20,5 +20,6 @@ seed.workspace = true serde-wasm-bindgen.workspace = true serde.workspace = true serde_json.workspace = true +time.workspace = true wasm-bindgen-futures.workspace = true web-sys.workspace = true diff --git a/typhon-webapp/src/jobset.rs b/typhon-webapp/src/jobset.rs index 4aeaaa88..03c60a6c 100644 --- a/typhon-webapp/src/jobset.rs +++ b/typhon-webapp/src/jobset.rs @@ -1,10 +1,13 @@ +use crate::timestamp; use crate::{appurl::AppUrl, perform_request, view_error}; + use seed::{prelude::*, *}; use typhon_types::*; #[derive(Clone)] pub struct Model { error: Option, + evaluations: Vec<(i32, timestamp::Model)>, handle: handles::Jobset, info: Option, } @@ -29,6 +32,7 @@ pub fn init(orders: &mut impl Orders, handle: handles::Jobset) -> Model { orders.send_msg(Msg::FetchInfo); Model { error: None, + evaluations: Vec::new(), handle: handle.clone(), info: None, } @@ -66,6 +70,11 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders) { ); } Msg::GetInfo(info) => { + model.evaluations = info + .evaluations + .iter() + .map(|(id, time)| (id.clone(), timestamp::init(time))) + .collect(); model.info = Some(info); } Msg::Noop => (), @@ -91,8 +100,8 @@ fn view_jobset(model: &Model) -> Node { Some(info) => div![div![ format!("Flake: {}", info.flake), h3!["Evaluations"], - ul![info.evaluations.iter().map(|(id, time)| li![a![ - format!("{}", time), // TODO: format timestamp properly + ul![model.evaluations.iter().map(|(id, time)| li![a![ + timestamp::view(time).map_msg(|_| Msg::Noop), attrs! { At::Href => crate::Urls::evaluation( &handles::Evaluation{ jobset: model.handle.clone(), diff --git a/typhon-webapp/src/lib.rs b/typhon-webapp/src/lib.rs index 2b860851..1e377bb0 100644 --- a/typhon-webapp/src/lib.rs +++ b/typhon-webapp/src/lib.rs @@ -6,6 +6,7 @@ mod job; mod jobset; mod login; mod project; +mod timestamp; use appurl::AppUrl; use once_cell::sync::OnceCell; diff --git a/typhon-webapp/src/timestamp.rs b/typhon-webapp/src/timestamp.rs new file mode 100644 index 00000000..46465c44 --- /dev/null +++ b/typhon-webapp/src/timestamp.rs @@ -0,0 +1,41 @@ +use seed::{prelude::*, *}; +use time; + +#[derive(Clone)] +pub struct Model { + date_time: time::OffsetDateTime, + duration_from_now: time::Duration, +} + +#[derive(Clone, Debug)] +pub enum Msg { + Update, +} + +fn now() -> time::OffsetDateTime { + let timestamp = js_sys::Date::now(); + let duration = time::Duration::new(timestamp as i64 / 1000, 0); + time::OffsetDateTime::UNIX_EPOCH + duration +} + +pub fn init(timestamp: &i64) -> Model { + let duration = time::Duration::new(*timestamp, 0); + let date_time = time::OffsetDateTime::UNIX_EPOCH + duration; + let duration_from_now = now() - date_time; + Model { + date_time, + duration_from_now, + } +} + +pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders) { + match msg { + Msg::Update => { + model.duration_from_now = time::OffsetDateTime::now_utc() - model.date_time; + } + } +} + +pub fn view(model: &Model) -> Node { + div![format!("{} ago", model.duration_from_now)] +}