summaryrefslogtreecommitdiffstats
path: root/melib
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-09-15 09:44:15 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-09-15 23:38:31 +0300
commit817c338a1371b92edc7ebafed2d4bf66512a44b3 (patch)
tree90e5b54cda5d96fbddbbe9ecfb3a75a490120e3b /melib
parent5ddd68ad9f32ae4be4a6ec5f15f6724d7aa8a2a5 (diff)
melib: fix metadata updates in Envelope updates
Diffstat (limited to 'melib')
-rw-r--r--melib/src/collection.rs25
-rw-r--r--melib/src/thread.rs47
2 files changed, 57 insertions, 15 deletions
diff --git a/melib/src/collection.rs b/melib/src/collection.rs
index 7feb4f20..e850f7ed 100644
--- a/melib/src/collection.rs
+++ b/melib/src/collection.rs
@@ -99,7 +99,7 @@ impl Collection {
.threads
.entry(folder_hash)
.or_default()
- .update_envelope(old_hash, new_hash)
+ .update_envelope(&self.envelopes, old_hash, new_hash)
.is_ok()
{
return;
@@ -114,7 +114,9 @@ impl Collection {
if *h == folder_hash {
continue;
}
- t.update_envelope(old_hash, new_hash).ok().take();
+ t.update_envelope(&self.envelopes, old_hash, new_hash)
+ .ok()
+ .take();
}
}
@@ -227,15 +229,22 @@ impl Collection {
}
}
- pub fn update(&mut self, old_hash: EnvelopeHash, envelope: Envelope, folder_hash: FolderHash) {
- self.envelopes.remove(&old_hash);
+ pub fn update(
+ &mut self,
+ old_hash: EnvelopeHash,
+ mut envelope: Envelope,
+ folder_hash: FolderHash,
+ ) {
+ let old_env = self.envelopes.remove(&old_hash).unwrap();
+ envelope.set_thread(old_env.thread());
let new_hash = envelope.hash();
self.message_ids
.insert(envelope.message_id().raw().to_vec(), new_hash);
self.envelopes.insert(new_hash, envelope);
if self.sent_folder.map(|f| f == folder_hash).unwrap_or(false) {
for (_, t) in self.threads.iter_mut() {
- t.update_envelope(old_hash, new_hash).unwrap_or(());
+ t.update_envelope(&self.envelopes, old_hash, new_hash)
+ .unwrap_or(());
}
}
{
@@ -243,7 +252,7 @@ impl Collection {
.threads
.entry(folder_hash)
.or_default()
- .update_envelope(old_hash, new_hash)
+ .update_envelope(&self.envelopes, old_hash, new_hash)
.is_ok()
{
return;
@@ -258,7 +267,9 @@ impl Collection {
if *h == folder_hash {
continue;
}
- t.update_envelope(old_hash, new_hash).ok().take();
+ t.update_envelope(&self.envelopes, old_hash, new_hash)
+ .ok()
+ .take();
}
}
diff --git a/melib/src/thread.rs b/melib/src/thread.rs
index 9e76879d..ed2c8adb 100644
--- a/melib/src/thread.rs
+++ b/melib/src/thread.rs
@@ -139,12 +139,14 @@ macro_rules! make {
}
let child_date = $buf[&$c].date;
let child_len = $buf[&$c].len;
+ let has_unseen = $buf[&$c].has_unseen;
$buf.entry($c).and_modify(|e| {
e.parent = Some($p);
});
$buf.entry($p).and_modify(|e| {
e.len += child_len + 1;
e.date = std::cmp::max(e.date, child_date);
+ e.has_unseen |= has_unseen;
});
union($buf, $c, $p);
prev_parent
@@ -698,6 +700,7 @@ impl Threads {
pub fn update_envelope(
&mut self,
+ envelopes: &Envelopes,
old_hash: EnvelopeHash,
new_hash: EnvelopeHash,
) -> Result<(), ()> {
@@ -705,15 +708,36 @@ impl Threads {
* - hash_set
* - message fields in thread_nodes
*/
- if let Some(node) = self
+ let thread_hash = if let Some((key, _)) = self
.thread_nodes
- .values_mut()
- .find(|n| n.message.map(|n| n == old_hash).unwrap_or(false))
+ .iter()
+ .find(|(_, n)| n.message.map(|n| n == old_hash).unwrap_or(false))
{
- node.message = Some(new_hash);
+ *key
} else {
return Err(());
};
+
+ self.thread_nodes.get_mut(&thread_hash).unwrap().message = Some(new_hash);
+ self.thread_nodes.get_mut(&thread_hash).unwrap().has_unseen = !envelopes[&new_hash]
+ .is_seen()
+ || self.thread_nodes[&thread_hash]
+ .children
+ .iter()
+ .fold(false, |acc, x| acc || self.thread_nodes[x].has_unseen);
+
+ let mut thread_hash_iter = thread_hash;
+ while self.thread_nodes[&thread_hash_iter].parent.is_some() {
+ let parent_hash = self.thread_nodes[&thread_hash_iter].parent.unwrap();
+
+ self.thread_nodes.get_mut(&parent_hash).unwrap().has_unseen = self.thread_nodes
+ [&parent_hash]
+ .children
+ .iter()
+ .fold(false, |acc, x| acc || self.thread_nodes[x].has_unseen);
+ thread_hash_iter = parent_hash;
+ }
+
self.hash_set.remove(&old_hash);
self.hash_set.insert(new_hash);
Ok(())
@@ -760,7 +784,12 @@ impl Threads {
}
/// Update show_subject details of ThreadNode
- pub fn update_node(&mut self, id: ThreadHash, env_hash: EnvelopeHash, envelopes: &Envelopes) {
+ pub fn update_show_subject(
+ &mut self,
+ id: ThreadHash,
+ env_hash: EnvelopeHash,
+ envelopes: &Envelopes,
+ ) {
let mut subject = envelopes[&env_hash].subject();
let mut subject = subject.to_mut().as_bytes();
let stripped_subject = subject.strip_prefixes();
@@ -818,6 +847,7 @@ impl Threads {
message: Some(env_hash),
parent: reply_to_id,
date: envelopes[&env_hash].date(),
+ has_unseen: !envelopes[&env_hash].is_seen(),
..ThreadNode::new(new_id)
},
);
@@ -854,7 +884,7 @@ impl Threads {
}
self.tree_insert_root(new_id, envelopes);
}
- self.update_node(new_id, env_hash, envelopes);
+ self.update_show_subject(new_id, env_hash, envelopes);
}
/* Insert or update */
@@ -904,7 +934,7 @@ impl Threads {
}
}
}
- self.update_node(id, env_hash, envelopes);
+ self.update_show_subject(id, env_hash, envelopes);
true
} else if let Some(reply_to_id) = reply_to_id {
let new_id = ThreadHash::new();
@@ -914,6 +944,7 @@ impl Threads {
message: Some(env_hash),
parent: Some(reply_to_id),
date: envelopes[&env_hash].date(),
+ has_unseen: !envelopes[&env_hash].is_seen(),
..ThreadNode::new(new_id)
},
);
@@ -927,7 +958,7 @@ impl Threads {
self.hash_set.insert(env_hash);
self.union(reply_to_id, new_id);
make!((reply_to_id) parent of (new_id), &mut self.thread_nodes);
- self.update_node(new_id, env_hash, envelopes);
+ self.update_show_subject(new_id, env_hash, envelopes);
true
} else {
false