diff --git a/melib/src/email.rs b/melib/src/email.rs index 9c3c68b35..90de20713 100644 --- a/melib/src/email.rs +++ b/melib/src/email.rs @@ -771,8 +771,8 @@ impl Envelope { self.timestamp = new_val.timestamp() as UnixTimestamp; } pub fn set_flag(&mut self, f: Flag, mut operation: Box) -> Result<()> { + self.flags.toggle(f); operation.set_flag(self, f)?; - self.flags |= f; Ok(()) } pub fn flags(&self) -> Flag { @@ -781,6 +781,9 @@ impl Envelope { pub fn set_seen(&mut self, operation: Box) -> Result<()> { self.set_flag(Flag::SEEN, operation) } + pub fn set_unseen(&mut self, operation: Box) -> Result<()> { + self.set_flag(Flag::SEEN, operation) + } pub fn is_seen(&self) -> bool { self.flags.contains(Flag::SEEN) } diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs index 36efe45ec..7c6568568 100644 --- a/ui/src/components/mail/listing/compact.rs +++ b/ui/src/components/mail/listing/compact.rs @@ -1145,6 +1145,63 @@ impl Component for CompactListing { self.filter(filter_term, context); self.dirty = true; } + Action::Listing(a @ SetRead) + | Action::Listing(a @ SetUnread) + | Action::Listing(a @ Delete) => { + let account = &mut context.accounts[self.cursor_pos.0]; + let folder_hash = account[self.cursor_pos.1] + .as_ref() + .map(|m| m.folder.hash()) + .unwrap(); + let threads = &account.collection.threads[&folder_hash]; + let i = if self.filtered_selection.is_empty() { + let thread_node = threads.root_set(self.cursor_pos.2); + let thread_node = &threads.thread_nodes()[&thread_node]; + if let Some(i) = thread_node.message() { + i + } else { + let mut iter_ptr = thread_node.children()[0]; + while threads.thread_nodes()[&iter_ptr].message().is_none() { + iter_ptr = threads.thread_nodes()[&iter_ptr].children()[0]; + } + threads.thread_nodes()[&iter_ptr].message().unwrap() + } + } else { + self.filtered_selection[self.cursor_pos.2] + }; + if !account.contains_key(i) { + /* The envelope has been renamed or removed, so wait for the appropriate event to + * arrive */ + return true; + } + match a { + SetRead => { + let (hash, is_seen) = { + let envelope: &Envelope = &account.get_env(&i); + (envelope.hash(), envelope.is_seen()) + }; + if !is_seen { + let op = account.operation(hash); + let envelope: &mut Envelope = &mut account.get_env_mut(&i); + envelope.set_seen(op).unwrap(); + } + } + SetUnread => { + let (hash, is_seen) = { + let envelope: &Envelope = &account.get_env(&i); + (envelope.hash(), envelope.is_seen()) + }; + if is_seen { + let op = account.operation(hash); + let envelope: &mut Envelope = &mut account.get_env_mut(&i); + envelope.set_unseen(op).unwrap(); + } + } + Delete => { /* do nothing */ } + _ => unreachable!(), + } + } + _ => {} }, UIEvent::Input(Key::Esc) => { diff --git a/ui/src/execute.rs b/ui/src/execute.rs index d74da6485..c48b27395 100644 --- a/ui/src/execute.rs +++ b/ui/src/execute.rs @@ -90,6 +90,10 @@ named!( toggle, preceded!(tag!("set "), alt_complete!(threaded | plain | compact)) ); +named!( + listing_action, + alt_complete!(toggle | envelope_action | filter | toggle_thread_snooze) +); named!( toggle_thread_snooze, @@ -118,6 +122,19 @@ named!( ) ); +named!( + envelope_action, + alt_complete!( + preceded!( + ws!(tag!("set")), + alt_complete!( + map!(ws!(tag!("read")), |_| Listing(SetRead)) + | map!(ws!(tag!("unread")), |_| Listing(SetUnread)) + ) + ) | map!(ws!(tag!("delete")), |_| Listing(Delete)) + ) +); + named!(pub parse_command, - alt_complete!( goto | toggle | sort | subsort | close | toggle_thread_snooze | mailinglist |filter) + alt_complete!( goto | listing_action | sort | subsort | close | mailinglist) ); diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs index d7de81f92..5b17a9473 100644 --- a/ui/src/execute/actions.rs +++ b/ui/src/execute/actions.rs @@ -37,6 +37,9 @@ pub enum ListingAction { SetThreaded, SetCompact, Filter(String), + SetRead, + SetUnread, + Delete, } #[derive(Debug)]