diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs index b85d00f9..cd1d5f64 100644 --- a/ui/src/components/mail/listing.rs +++ b/ui/src/components/mail/listing.rs @@ -105,6 +105,46 @@ pub trait MailListingTrait: ListingTrait { /* do nothing */ continue; } + ListingAction::Tag(Remove(ref tag_str)) => { + use std::collections::hash_map::DefaultHasher; + use std::hash::Hasher; + let h = { + let mut hasher = DefaultHasher::new(); + hasher.write(tag_str.as_bytes()); + hasher.finish() + }; + let backend_lck = account.backend.write().unwrap(); + if let Some(t) = backend_lck.tags() { + let mut tags_lck = t.write().unwrap(); + if !tags_lck.contains_key(&h) { + tags_lck.insert(h, tag_str.to_string()); + } + if let Some(pos) = envelope.labels().iter().position(|&el| el == h) { + envelope.labels_mut().remove(pos); + } + } else { + return; + } + } + ListingAction::Tag(Add(ref tag_str)) => { + use std::collections::hash_map::DefaultHasher; + use std::hash::Hasher; + let h = { + let mut hasher = DefaultHasher::new(); + hasher.write(tag_str.as_bytes()); + hasher.finish() + }; + let backend_lck = account.backend.write().unwrap(); + if let Some(t) = backend_lck.tags() { + let mut tags_lck = t.write().unwrap(); + if !tags_lck.contains_key(&h) { + tags_lck.insert(h, tag_str.to_string()); + } + envelope.labels_mut().push(h); + } else { + return; + } + } _ => unreachable!(), } self.row_updates().push(thread_hash); diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs index 4106c181..15a86a0a 100644 --- a/ui/src/components/mail/listing/compact.rs +++ b/ui/src/components/mail/listing/compact.rs @@ -1135,6 +1135,7 @@ impl Component for CompactListing { Action::Listing(a @ ListingAction::SetSeen) | Action::Listing(a @ ListingAction::SetUnseen) | Action::Listing(a @ ListingAction::Delete) + | Action::Listing(a @ ListingAction::Tag(_)) if !self.unfocused => { let is_selection_empty = diff --git a/ui/src/execute.rs b/ui/src/execute.rs index 6387a32e..2d50686a 100644 --- a/ui/src/execute.rs +++ b/ui/src/execute.rs @@ -33,6 +33,7 @@ pub use crate::actions::ComposeAction::{self, *}; pub use crate::actions::ListingAction::{self, *}; pub use crate::actions::MailingListAction::{self, *}; pub use crate::actions::TabAction::{self, *}; +pub use crate::actions::TagAction::{self, *}; pub use crate::actions::ViewAction::{self, *}; use std::str::FromStr; @@ -333,7 +334,28 @@ define_commands!([ ) ); ) - } + }, + { tags: ["tag", "tag add", "tag remove"], + desc: "tag [add/remove], edits message's tags.", + parser: + ( named!( + tag, + preceded!( + ws!(tag!("tag")), + alt_complete!( + do_parse!( + ws!(tag!("add")) + >> tag: ws!(map_res!(call!(not_line_ending), std::str::from_utf8)) + >> (Listing(Tag(Add(tag.to_string()))))) + | do_parse!( + ws!(tag!("remove")) + >> tag: ws!(map_res!(call!(not_line_ending), std::str::from_utf8)) + >> (Listing(Tag(Remove(tag.to_string()))))) + + ) + ) + ); ) + } ]); named!( @@ -382,7 +404,7 @@ named!( named!( listing_action, - alt_complete!(toggle | envelope_action | filter | toggle_thread_snooze | open_in_new_tab) + alt_complete!(toggle | envelope_action | filter | toggle_thread_snooze | open_in_new_tab | tag) ); named!( diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs index 07f79c57..86f1ab13 100644 --- a/ui/src/execute/actions.rs +++ b/ui/src/execute/actions.rs @@ -32,6 +32,12 @@ use melib::{Draft, EnvelopeHash}; extern crate uuid; use uuid::Uuid; +#[derive(Debug)] +pub enum TagAction { + Add(String), + Remove(String), +} + #[derive(Debug)] pub enum ListingAction { SetPlain, @@ -43,6 +49,7 @@ pub enum ListingAction { SetUnseen, Delete, OpenInNewTab, + Tag(TagAction), } #[derive(Debug)]