melib: insert sent_folder content to other mailboxes

embed
Manos Pitsidianakis 2018-09-10 02:21:46 +03:00
parent 1e04e6a4ea
commit 4993db745a
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 117 additions and 33 deletions

View File

@ -63,6 +63,11 @@ impl Collection {
self.threads.insert(&mut envelope);
self.envelopes.insert(hash, envelope);
}
pub(crate) fn insert_reply(&mut self, hash: EnvelopeHash, mut envelope: Envelope) {
if self.threads.insert_reply(&mut envelope) {
self.envelopes.insert(hash, envelope);
}
}
}
impl Deref for Collection {

View File

@ -44,6 +44,7 @@ use std::option::Option;
pub struct Mailbox {
pub folder: Folder,
pub collection: Collection,
has_sent: bool,
}
impl Clone for Mailbox {
@ -51,6 +52,7 @@ impl Clone for Mailbox {
Mailbox {
folder: self.folder.clone(),
collection: self.collection.clone(),
has_sent: self.has_sent,
}
}
}
@ -59,22 +61,20 @@ impl Default for Mailbox {
Mailbox {
folder: folder_default(),
collection: Collection::default(),
has_sent: false,
}
}
}
impl Mailbox {
pub fn new(
folder: &Folder,
sent_folder: &Option<Result<Mailbox>>,
envelopes: Result<Vec<Envelope>>,
) -> Result<Mailbox> {
pub fn new(folder: &Folder, envelopes: Result<Vec<Envelope>>) -> Result<Mailbox> {
let mut envelopes: Vec<Envelope> = envelopes?;
envelopes.sort_by(|a, b| a.date().cmp(&b.date()));
let collection = Collection::new(envelopes, folder.name());
Ok(Mailbox {
folder: (*folder).clone(),
collection,
..Default::default()
})
}
pub fn is_empty(&self) -> bool {
@ -107,6 +107,15 @@ impl Mailbox {
&self.collection.threads.thread_nodes()[i]
}
pub fn insert_sent_folder(&mut self, sent: &Mailbox) {
if !self.has_sent {
for envelope in sent.collection.envelopes.values().cloned() {
self.insert_reply(envelope);
}
self.has_sent = true;
}
}
pub fn update(&mut self, old_hash: EnvelopeHash, envelope: Envelope) {
self.collection.remove(&old_hash);
self.collection.insert(envelope.hash(), envelope);
@ -115,10 +124,14 @@ impl Mailbox {
pub fn insert(&mut self, envelope: Envelope) -> &Envelope {
let hash = envelope.hash();
self.collection.insert(hash, envelope);
eprintln!("Inserted envelope");
&self.collection[&hash]
}
fn insert_reply(&mut self, envelope: Envelope) {
let hash = envelope.hash();
self.collection.insert_reply(hash, envelope);
}
pub fn remove(&mut self, envelope_hash: EnvelopeHash) {
self.collection.remove(&envelope_hash);
// eprintln!("envelope_hash: {}\ncollection:\n{:?}", envelope_hash, self.collection);

View File

@ -338,6 +338,62 @@ impl Threads {
);
}
pub fn insert_reply(&mut self, envelope: &mut Envelope) -> bool {
{
let in_reply_to = envelope.in_reply_to_raw();
if !self.message_ids.contains_key(in_reply_to.as_ref()) {
return false;
}
}
/* FIXME: This does not update show_subject and len which is done in node_build upon
* creation */
link_envelope(
&mut self.thread_nodes,
&mut self.message_ids,
&mut self.hash_set,
envelope,
);
self.rebuild_thread(envelope);
return true;
}
/* Update thread tree information on envelope insertion */
fn rebuild_thread(&mut self, envelope: &Envelope) {
let m_id = envelope.message_id_raw();
let mut node_idx = self.message_ids[m_id.as_ref()];
let mut stack = Vec::with_capacity(32);
/* Trace path back to root ThreadNode */
while let Some(p) = &self.thread_nodes[node_idx].parent {
node_idx = *p;
stack.push(node_idx);
}
for &p in stack.iter() {
self.thread_nodes[p].len += 1;
}
/* Trace path from root ThreadTree to the envelope's parent */
let mut tree = self.tree.get_mut();
for &s in stack.iter().rev() {
/* Borrow checker is being a tad silly here, so the following
* is basically this:
*
* let tree = &mut tree[s].children;
*/
let temp_tree = tree;
let pos = temp_tree.iter().position(|v| v.id == s).unwrap();
match temp_tree[pos].children {
ref mut v => {
tree = v;
}
}
}
/* Add new child */
tree.push(ThreadTree::new(self.message_ids[m_id.as_ref()]));
}
/*
* Finalize instance by building the thread tree, set show subject and thread lengths etc. */
fn build_collection(&mut self, collection: &FnvHashMap<EnvelopeHash, Envelope>) {
{
let tree = self.tree.get_mut();
@ -649,11 +705,6 @@ fn node_build(
}
}
}
if thread_nodes[idx].has_parent()
&& !thread_nodes[thread_nodes[idx].parent().unwrap()].has_message()
{
thread_nodes[idx].parent = None;
}
let indentation = if thread_nodes[idx].has_message() {
thread_nodes[idx].indentation = indentation;
indentation + 1

View File

@ -141,39 +141,54 @@ impl Account {
}
fn load_mailbox(&mut self, index: usize, envelopes: Result<Vec<Envelope>>) {
// TODO: Cleanup this function
let folders = self.backend.folders();
let folder = &folders[index];
if self.sent_folder.is_some() {
let id = self.sent_folder.unwrap();
if id == index {
/* ======================== */
self.folders[index] = Some(Mailbox::new(folder, &None, envelopes));
/* ======================== */
} else {
if self.sent_folder.is_some() && self.sent_folder.unwrap() == index {
self.folders[index] = Some(Mailbox::new(folder, envelopes));
/* Add our replies to other folders */
for id in (0..self.folders.len()).filter(|i| *i != index) {
self.add_replies_to_folder(id);
}
} else {
self.folders[index] = Some(Mailbox::new(folder, envelopes));
self.add_replies_to_folder(index);
};
}
fn add_replies_to_folder(&mut self, folder_index: usize) {
if let Some(sent_index) = self.sent_folder.as_ref() {
if self.folders[*sent_index]
.as_ref()
.map(|v| v.is_ok())
.unwrap_or(false)
&& self.folders[folder_index]
.as_ref()
.map(|v| v.is_ok())
.unwrap_or(false)
{
let (sent, cur) = {
let ptr = self.folders.as_mut_ptr();
unsafe {
use std::slice::from_raw_parts_mut;
(
from_raw_parts_mut(ptr.offset(id as isize), id + 1),
from_raw_parts_mut(ptr.offset(index as isize), index + 1),
from_raw_parts_mut(ptr.offset(*sent_index as isize), *sent_index + 1)
[0]
.as_mut()
.unwrap()
.as_mut()
.unwrap(),
from_raw_parts_mut(ptr.offset(folder_index as isize), folder_index + 1)
[0]
.as_mut()
.unwrap()
.as_mut()
.unwrap(),
)
}
};
let sent_path = &folders[id];
if sent[0].is_none() {
sent[0] = Some(Mailbox::new(sent_path, &None, envelopes.clone()));
}
/* ======================== */
cur[0] = Some(Mailbox::new(folder, &sent[0], envelopes));
/* ======================== */
cur.insert_sent_folder(&sent);
}
} else {
/* ======================== */
self.folders[index] = Some(Mailbox::new(folder, &None, envelopes));
/* ======================== */
};
}
}
pub fn status(&mut self, index: usize) -> result::Result<(), usize> {