From 9dd21eea50ceda147b5e8da27856bc576c1fbfda Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Mon, 30 Nov 2020 00:26:13 +0200 Subject: [PATCH] melib/threads: prefer local ThreadNode env_hash When inserting an envelope in a thread and its Message-ID already exists with an associated envelope, overwrite the association if the previous associated envelope is from a foreign mailbox and current envelope is not. This happens when mail from a sent folder has been inserted in eg your INBOX, but somehow INBOX has a copy of your own message as well. This can happen when mailing lists that send you copies of your own posts. The problem with this was that in IMAP your mailing list copy was unseen and you could not mark it seen because the thread only knew about your Sent mailbox copy. --- melib/src/backends/notmuch/message.rs | 1 + melib/src/thread.rs | 41 ++++++++++++++++++--------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/melib/src/backends/notmuch/message.rs b/melib/src/backends/notmuch/message.rs index a17a7e54..cf9e2d2a 100644 --- a/melib/src/backends/notmuch/message.rs +++ b/melib/src/backends/notmuch/message.rs @@ -137,6 +137,7 @@ impl<'m> Message<'m> { ThreadNode { message: Some(self.env_hash()), parent: None, + other_mailbox: false, children: vec![], date: self.date(), show_subject: true, diff --git a/melib/src/thread.rs b/melib/src/thread.rs index 0fef1cb7..4fecea44 100644 --- a/melib/src/thread.rs +++ b/melib/src/thread.rs @@ -338,6 +338,7 @@ impl Thread { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ThreadNode { pub message: Option, + pub other_mailbox: bool, pub parent: Option, pub children: Vec, pub date: UnixTimestamp, @@ -351,6 +352,7 @@ impl Default for ThreadNode { ThreadNode { message: None, parent: None, + other_mailbox: false, children: Vec::new(), date: UnixTimestamp::default(), show_subject: true, @@ -653,26 +655,36 @@ impl Threads { env_hash: EnvelopeHash, other_mailbox: bool, ) -> bool { + { + let envelopes_lck = envelopes.read().unwrap(); + let message_id = envelopes_lck[&env_hash].message_id().raw(); + if self.message_ids.contains_key(message_id) + && !self.missing_message_ids.contains(message_id) + { + let thread_hash = self.message_ids[message_id]; + let node = self.thread_nodes.entry(thread_hash).or_default(); + drop(message_id); + drop(envelopes_lck); + envelopes + .write() + .unwrap() + .get_mut(&env_hash) + .unwrap() + .set_thread(thread_hash); + + /* If thread node currently has a message from a foreign mailbox and env_hash is + * from current mailbox we want to update it, otherwise return */ + if !(node.other_mailbox && !other_mailbox) { + return false; + } + } + } let envelopes_lck = envelopes.read().unwrap(); let reply_to_id: Option = envelopes_lck[&env_hash] .in_reply_to() .map(StrBuild::raw) .and_then(|r| self.message_ids.get(r).cloned()); let message_id = envelopes_lck[&env_hash].message_id().raw(); - if self.message_ids.contains_key(message_id) - && !self.missing_message_ids.contains(message_id) - { - let thread_hash = self.message_ids[message_id]; - drop(envelopes_lck); - envelopes - .write() - .unwrap() - .get_mut(&env_hash) - .unwrap() - .set_thread(thread_hash); - - return false; - } if other_mailbox && reply_to_id.is_none() @@ -703,6 +715,7 @@ impl Threads { if node.parent.is_none() { node.parent = reply_to_id; } + node.other_mailbox = other_mailbox; node.date = envelopes_lck[&env_hash].date(); node.unseen = !envelopes_lck[&env_hash].is_seen(); }