61 lines
1.5 KiB
Rust
61 lines
1.5 KiB
Rust
use chrono::{DateTime, Utc};
|
|
use std::fmt;
|
|
use yew::prelude::*;
|
|
|
|
pub fn now() -> DateTime<Utc> {
|
|
let now = stdweb::web::Date::now() / 1000.0;
|
|
let now_floor = now.floor();
|
|
let secs = now_floor as i64;
|
|
let nanosecs = ((now - now_floor) * 1e9).round() as u32;
|
|
DateTime::from_utc(chrono::NaiveDateTime::from_timestamp(secs, nanosecs), Utc)
|
|
}
|
|
|
|
struct PrettyFormatDuration(chrono::Duration);
|
|
|
|
impl fmt::Display for PrettyFormatDuration {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
if self.0 == chrono::Duration::zero() {
|
|
return write!(f, "now");
|
|
}
|
|
|
|
let (abs_duration, future) = if self.0 < chrono::Duration::zero() {
|
|
(-self.0, true)
|
|
} else {
|
|
(self.0, false)
|
|
};
|
|
if future {
|
|
write!(f, "in ")?;
|
|
}
|
|
|
|
if abs_duration.num_seconds() < 2 {
|
|
// write!(f, "{}ms", abs_duration.num_milliseconds())?;
|
|
write!(f, "now")?;
|
|
} else if abs_duration.num_seconds() < 120 {
|
|
write!(f, "{}s", abs_duration.num_seconds())?;
|
|
} else if abs_duration.num_minutes() < 120 {
|
|
write!(f, "{}m", abs_duration.num_minutes())?;
|
|
} else if abs_duration.num_hours() < 48 {
|
|
write!(f, "{}h", abs_duration.num_hours())?;
|
|
} else {
|
|
write!(f, "{}d", abs_duration.num_days())?;
|
|
}
|
|
|
|
if !future {
|
|
write!(f, " ago")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub fn ago<COMP>(dt: DateTime<Utc>) -> Html<COMP>
|
|
where
|
|
COMP: Component,
|
|
{
|
|
let duration = now().signed_duration_since(dt);
|
|
let dt_s = format!("{}", dt);
|
|
html! {
|
|
<time datetime=&dt_s title=&dt_s>{ PrettyFormatDuration(duration) }</time>
|
|
}
|
|
}
|