diff --git a/melib/src/mailbox/thread.rs b/melib/src/mailbox/thread.rs index a4e1c47fa..ded6b943d 100644 --- a/melib/src/mailbox/thread.rs +++ b/melib/src/mailbox/thread.rs @@ -359,6 +359,8 @@ pub struct ThreadNode { len: usize, has_unseen: bool, + snoozed: bool, + /* Union/Find set fields */ thread_group: ThreadHash, rank: i32, @@ -376,6 +378,8 @@ impl Default for ThreadNode { len: 0, has_unseen: false, + snoozed: false, + thread_group: ThreadHash::default(), rank: 0, } @@ -428,11 +432,23 @@ impl ThreadNode { pub fn indentation(&self) -> usize { self.indentation } + + pub fn snoozed(&self) -> bool { + self.snoozed + } + + pub fn thread_group(&self) -> ThreadHash { + self.thread_group + } + + pub fn set_snoozed(&mut self, set: bool) { + self.snoozed = set; + } } #[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct Threads { - thread_nodes: FnvHashMap, + pub thread_nodes: FnvHashMap, root_set: RefCell>, tree: RefCell>, @@ -468,6 +484,13 @@ impl<'a> Iterator for RootIterator<'a> { } } } +fn find_ref(buf: &FnvHashMap, h: ThreadHash) -> ThreadHash { + if buf[&h].thread_group == h { + return h; + } + let p = buf[&h].thread_group; + find_ref(buf, p) +} fn find(buf: &mut FnvHashMap, h: ThreadHash) -> ThreadHash { if buf[&h].thread_group == h { return h; @@ -502,7 +525,11 @@ fn union(buf: &mut FnvHashMap, x: ThreadHash, y: ThreadH } impl Threads { - fn find(&mut self, i: ThreadHash) -> ThreadHash { + pub fn is_snoozed(&self, h: ThreadHash) -> bool { + let root = find_ref(&self.thread_nodes, h); + self.thread_nodes[&root].snoozed() + } + pub fn find(&mut self, i: ThreadHash) -> ThreadHash { find(&mut self.thread_nodes, i) } fn union(&mut self, x: ThreadHash, y: ThreadHash) -> ThreadHash { diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs index 39978e03f..242283a7d 100644 --- a/ui/src/components/mail/listing/compact.rs +++ b/ui/src/components/mail/listing/compact.rs @@ -104,20 +104,30 @@ impl MailboxView { e: &Envelope, len: usize, idx: usize, + is_snoozed: bool, ) -> (IndexNoString, FromString, DateString, SubjectString) { if len > 0 { ( IndexNoString(idx.to_string()), FromString(address_list!((e.from()) as comma_sep_list)), DateString(MailboxView::format_date(e)), - SubjectString(format!("{} ({})", e.subject(), len)), + SubjectString(format!( + "{} ({}){}", + e.subject(), + len, + if is_snoozed { " 💤" } else { "" } + )), ) } else { ( IndexNoString(idx.to_string()), FromString(address_list!((e.from()) as comma_sep_list)), DateString(MailboxView::format_date(e)), - SubjectString(e.subject().to_string()), + SubjectString(format!( + "{}{}", + e.subject(), + if is_snoozed { " 💤" } else { "" } + )), ) } } @@ -229,7 +239,13 @@ impl MailboxView { panic!(); } let root_envelope: &Envelope = &mailbox.collection[&i]; - let strings = MailboxView::make_entry_string(root_envelope, thread_node.len(), idx); + + let strings = MailboxView::make_entry_string( + root_envelope, + thread_node.len(), + idx, + threads.is_snoozed(root_idx), + ); min_width.0 = cmp::max(min_width.0, strings.0.len()); /* index */ min_width.1 = cmp::max(min_width.1, strings.2.split_graphemes().len()); /* date */ min_width.2 = cmp::max(min_width.2, strings.3.split_graphemes().len()); /* subject */ @@ -328,6 +344,9 @@ impl MailboxView { ((_x, idx), (widths.2 + _x, idx)), false, ); + if threads.is_snoozed(root_idx) { + self.content[(x - 1, idx)].set_fg(Color::Red); + } self.order.insert(i, idx); @@ -596,8 +615,7 @@ impl Component for MailboxView { } UIEvent::StartupCheck(ref f) if *f - == context.accounts[self.new_cursor_pos.0].folders_order - [self.new_cursor_pos.1] => + == context.accounts[self.cursor_pos.0].folders_order[self.new_cursor_pos.1] => { self.refresh_mailbox(context); self.set_dirty(); @@ -639,6 +657,35 @@ impl Component for MailboxView { self.refresh_mailbox(context); return true; } + Action::ToggleThreadSnooze => { + { + //FIXME NLL + + let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1] + .as_mut() + .unwrap(); + let threads = &mut mailbox.collection.threads; + let thread_group = threads.thread_nodes() + [&threads.root_set(self.cursor_pos.2)] + .thread_group(); + let thread_group = threads.find(thread_group); + /*let i = if let Some(i) = threads.thread_nodes[&thread_group].message() { + i + } else { + let mut iter_ptr = threads.thread_nodes[&thread_group].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() + };*/ + let root_node = threads.thread_nodes.entry(thread_group).or_default(); + let is_snoozed = root_node.snoozed(); + root_node.set_snoozed(!is_snoozed); + //self.row_updates.push(i); + } + self.refresh_mailbox(context); + return true; + } _ => {} }, _ => {} diff --git a/ui/src/conf/accounts.rs b/ui/src/conf/accounts.rs index a927193dc..88b8f177b 100644 --- a/ui/src/conf/accounts.rs +++ b/ui/src/conf/accounts.rs @@ -290,12 +290,20 @@ impl Account { } RefreshEventKind::Create(envelope) => { debug!("create {}", envelope.hash()); - let env: &Envelope = mailbox!(&folder_hash, self.folders).insert(*envelope); + let env_hash: EnvelopeHash = { + let mailbox = mailbox!(&folder_hash, self.folders); + mailbox.insert(*envelope).hash() + }; let ref_folders: FnvHashMap = self.backend.folders(); let folder_conf = &self.settings.folder_confs[&self.folder_names[&folder_hash]]; if folder_conf.ignore.is_true() { return None; } + let (env, thread_node) = + mailbox!(&folder_hash, self.folders).mail_and_thread(env_hash); + if thread_node.snoozed() { + return None; + } return Some(Notification( Some("new mail".into()), format!( diff --git a/ui/src/execute.rs b/ui/src/execute.rs index 0432d22fa..9282516fa 100644 --- a/ui/src/execute.rs +++ b/ui/src/execute.rs @@ -90,6 +90,11 @@ named!( preceded!(tag!("set "), alt_complete!(threaded | plain | compact)) ); +named!( + toggle_thread_snooze, + map!(ws!(tag!("toggle_thread_snooze")), |_| ToggleThreadSnooze) +); + named!(pub parse_command, - alt_complete!( goto | toggle | sort | subsort | close) + alt_complete!( goto | toggle | sort | subsort | close | toggle_thread_snooze) ); diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs index 5402c846c..fa9070a37 100644 --- a/ui/src/execute/actions.rs +++ b/ui/src/execute/actions.rs @@ -54,4 +54,5 @@ pub enum Action { Sort(SortField, SortOrder), SubSort(SortField, SortOrder), Tab(TabAction), + ToggleThreadSnooze, }