upub_web/components/
mod.rs1mod login;
2pub use login::*;
3
4mod navigation;
5pub use navigation::*;
6
7mod user;
8pub use user::*;
9
10mod post;
11pub use post::*;
12
13use leptos::prelude::*;
14
15#[component]
16pub fn DateTime(t: Option<chrono::DateTime<chrono::Utc>>) -> impl IntoView {
17 match t {
18 Some(t) => {
19 let delta = chrono::Utc::now() - t;
20 let pretty = if delta.num_seconds() < 60 {
21 format!("{}s ago", delta.num_seconds())
22 } else if delta.num_minutes() < 60 {
23 format!("{}m ago", delta.num_minutes())
24 } else if delta.num_hours() < 24 {
25 format!("{}h ago", delta.num_hours())
26 } else if delta.num_days() < 90 {
27 format!("{}d ago", delta.num_days())
28 } else {
29 t.format("%d/%m/%Y").to_string()
30 };
31 let rfc = t.to_rfc2822();
32 Some(view! {
33 <small title={rfc}>{pretty}</small>
34 })
35 },
36 None => None,
37 }
38}
39
40#[component]
41pub fn PrivacyMarker(
42 privacy: Privacy,
43 #[prop(optional)] to: Vec<String>,
44 #[prop(optional)] cc: Vec<String>,
45 #[prop(optional)] big: bool,
46) -> impl IntoView {
47 let to_txt = if to.is_empty() { String::new() } else { format!("to: {}", to.join(", ")) };
48 let cc_txt = if cc.is_empty() { String::new() } else { format!("cc: {}", cc.join(", ")) };
49 let audience = format!("{to_txt}\n{cc_txt}");
50 view! {
51 <span class:big-emoji=big class="emoji ml-1 mr-s moreinfo" title={audience} >{privacy.icon()}</span>
52 }
53}