From d4038f40d6d7a30edca1fb60eda4ee26ec268866 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sat, 6 Apr 2024 09:38:00 -0700 Subject: [PATCH] web: add UI to remove tags when viewing messages --- Cargo.lock | 6 +++++ web/src/state.rs | 1 + web/src/view/desktop.rs | 1 + web/src/view/mobile.rs | 1 + web/src/view/mod.rs | 58 ++++++++++++++++++++++++++++++++++++++++- web/src/view/tablet.rs | 1 + web/static/style.css | 4 ++- 7 files changed, 70 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d02bc8d..d7cc63e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1440,6 +1440,11 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "human_format" +version = "1.0.2" +source = "git+https://github.com/wathiede/human-format-rs#c5f59f0b0e4d92e649d415a8509bc46e92413356" + [[package]] name = "hyper" version = "0.10.16" @@ -1727,6 +1732,7 @@ dependencies = [ "console_log", "gloo-net", "graphql_client", + "human_format", "itertools", "log 0.4.20", "notmuch", diff --git a/web/src/state.rs b/web/src/state.rs index 3df4a0c..0a52cec 100644 --- a/web/src/state.rs +++ b/web/src/state.rs @@ -222,6 +222,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders) { if let Err(e) = res { error!("Failed to remove tag {tag} to {query}: {e}"); } + // TODO: reconsider this behavior seed::window() .location() .set_href(&search_url) diff --git a/web/src/view/desktop.rs b/web/src/view/desktop.rs index 8ee7d84..05d90ee 100644 --- a/web/src/view/desktop.rs +++ b/web/src/view/desktop.rs @@ -9,6 +9,7 @@ use crate::{ #[topo::nested] pub(super) fn view(model: &Model) -> Node { + log::info!("tablet::view"); let show_icon_text = true; // Do two queries, one without `unread` so it loads fast, then a second with unread. let content = match &model.context { diff --git a/web/src/view/mobile.rs b/web/src/view/mobile.rs index 8fe43c8..3980df8 100644 --- a/web/src/view/mobile.rs +++ b/web/src/view/mobile.rs @@ -10,6 +10,7 @@ use crate::{ }; pub(super) fn view(model: &Model) -> Node { + log::info!("tablet::view"); let show_icon_text = false; let content = match &model.context { Context::None => div![h1!["Loading"]], diff --git a/web/src/view/mod.rs b/web/src/view/mod.rs index 7963dcf..bdaeb2d 100644 --- a/web/src/view/mod.rs +++ b/web/src/view/mod.rs @@ -61,6 +61,59 @@ fn tags_chiclet(tags: &[String], is_mobile: bool) -> impl Iterator( + thread_id: &'a str, + tags: &'a [String], + is_mobile: bool, +) -> Node { + div![ + C![ + "message-tags", + "field", + "is-grouped", + "is-grouped-multiline" + ], + tags.iter().map(move |tag| { + let hex = compute_color(tag); + let style = style! {St::BackgroundColor=>hex}; + let classes = C!["tag", IF!(is_mobile => "is-small")]; + let attrs = attrs! { + At::Href => urls::search(&format!("tag:{tag}"), 0) + }; + let tag = tag.clone(); + let rm_tag = tag.clone(); + let thread_id = format!("thread:{thread_id}"); + div![ + C!["control"], + div![ + C!["tags", "has-addons"], + a![ + classes, + attrs, + style, + match tag.as_str() { + "attachment" => span!["📎"], + "replied" => span![i![C!["fa-solid", "fa-reply"]]], + _ => span![&tag], + }, + ev(Ev::Click, move |_| Msg::FrontPageRequest { + query: format!("tag:{tag}"), + after: None, + before: None, + first: None, + last: None, + }) + ], + a![ + C!["tag", "is-delete"], + ev(Ev::Click, move |_| Msg::RemoveTag(thread_id, rm_tag)) + ] + ] + ] + }) + ] +} + fn pretty_authors(authors: &str) -> impl Iterator> + '_ { let one_person = authors.matches(',').count() == 0; let authors = authors.split(','); @@ -748,7 +801,10 @@ fn thread( div![ C!["thread"], h3![C!["is-size-5"], subject], - span![C!["tags"], tags_chiclet(&tags, false)], + span![ + C!["tags"], + removable_tags_chiclet(&thread.thread_id, &tags, false) + ], div![ C!["level", "is-mobile"], div![ diff --git a/web/src/view/tablet.rs b/web/src/view/tablet.rs index 9d277f1..f35f008 100644 --- a/web/src/view/tablet.rs +++ b/web/src/view/tablet.rs @@ -6,6 +6,7 @@ use crate::{ }; pub(super) fn view(model: &Model) -> Node { + log::info!("tablet::view"); let show_icon_text = false; // Do two queries, one without `unread` so it loads fast, then a second with unread. let content = match &model.context { diff --git a/web/static/style.css b/web/static/style.css index fa31048..afc1c88 100644 --- a/web/static/style.css +++ b/web/static/style.css @@ -155,12 +155,14 @@ input::placeholder, padding: 1em; } +.tablet .thread h3, .mobile .thread h3 { overflow-wrap: break-word; padding: 1em 1em 0; } -.mobile .thread .tags { +.tablet .thread .message-tags, +.mobile .thread .message-tags { padding: 0 1em; }