melib/Collection: put all fields behind a mutex
parent
1112ef4717
commit
0882dbbad0
|
@ -60,12 +60,19 @@ impl DerefMut for EnvelopeRefMut<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Collection {
|
pub struct Collection {
|
||||||
pub envelopes: Arc<RwLock<HashMap<EnvelopeHash, Envelope>>>,
|
pub envelopes: Arc<RwLock<HashMap<EnvelopeHash, Envelope>>>,
|
||||||
pub threads: HashMap<MailboxHash, Threads>,
|
pub message_id_index: Arc<RwLock<HashMap<Vec<u8>, EnvelopeHash>>>,
|
||||||
sent_mailbox: Option<MailboxHash>,
|
pub threads: Arc<RwLock<HashMap<MailboxHash, Threads>>>,
|
||||||
pub mailboxes: HashMap<MailboxHash, HashSet<EnvelopeHash>>,
|
sent_mailbox: Arc<RwLock<Option<MailboxHash>>>,
|
||||||
|
pub mailboxes: Arc<RwLock<HashMap<MailboxHash, HashSet<EnvelopeHash>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Collection {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -89,15 +96,26 @@ impl Drop for Collection {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl Collection {
|
impl Collection {
|
||||||
pub fn new(envelopes: HashMap<EnvelopeHash, Envelope>) -> Collection {
|
pub fn new() -> Collection {
|
||||||
let threads = HashMap::with_capacity_and_hasher(16, Default::default());
|
let message_id_index = Arc::new(RwLock::new(HashMap::with_capacity_and_hasher(
|
||||||
let mailboxes = HashMap::with_capacity_and_hasher(16, Default::default());
|
16,
|
||||||
|
Default::default(),
|
||||||
|
)));
|
||||||
|
let threads = Arc::new(RwLock::new(HashMap::with_capacity_and_hasher(
|
||||||
|
16,
|
||||||
|
Default::default(),
|
||||||
|
)));
|
||||||
|
let mailboxes = Arc::new(RwLock::new(HashMap::with_capacity_and_hasher(
|
||||||
|
16,
|
||||||
|
Default::default(),
|
||||||
|
)));
|
||||||
|
|
||||||
Collection {
|
Collection {
|
||||||
envelopes: Arc::new(RwLock::new(envelopes)),
|
envelopes: Arc::new(RwLock::new(Default::default())),
|
||||||
|
message_id_index,
|
||||||
threads,
|
threads,
|
||||||
mailboxes,
|
mailboxes,
|
||||||
sent_mailbox: None,
|
sent_mailbox: Arc::new(RwLock::new(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,14 +130,19 @@ impl Collection {
|
||||||
pub fn remove(&mut self, envelope_hash: EnvelopeHash, mailbox_hash: MailboxHash) {
|
pub fn remove(&mut self, envelope_hash: EnvelopeHash, mailbox_hash: MailboxHash) {
|
||||||
debug!("DEBUG: Removing {}", envelope_hash);
|
debug!("DEBUG: Removing {}", envelope_hash);
|
||||||
self.envelopes.write().unwrap().remove(&envelope_hash);
|
self.envelopes.write().unwrap().remove(&envelope_hash);
|
||||||
self.mailboxes.entry(mailbox_hash).and_modify(|m| {
|
self.mailboxes
|
||||||
m.remove(&envelope_hash);
|
.write()
|
||||||
});
|
.unwrap()
|
||||||
self.threads
|
.entry(mailbox_hash)
|
||||||
|
.and_modify(|m| {
|
||||||
|
m.remove(&envelope_hash);
|
||||||
|
});
|
||||||
|
let mut threads_lck = self.threads.write().unwrap();
|
||||||
|
threads_lck
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.remove(envelope_hash);
|
.remove(envelope_hash);
|
||||||
for (h, t) in self.threads.iter_mut() {
|
for (h, t) in threads_lck.iter_mut() {
|
||||||
if *h == mailbox_hash {
|
if *h == mailbox_hash {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -137,15 +160,19 @@ impl Collection {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let mut envelope = self.envelopes.write().unwrap().remove(&old_hash).unwrap();
|
let mut envelope = self.envelopes.write().unwrap().remove(&old_hash).unwrap();
|
||||||
self.mailboxes.entry(mailbox_hash).and_modify(|m| {
|
self.mailboxes
|
||||||
m.remove(&old_hash);
|
.write()
|
||||||
m.insert(new_hash);
|
.unwrap()
|
||||||
});
|
.entry(mailbox_hash)
|
||||||
|
.and_modify(|m| {
|
||||||
|
m.remove(&old_hash);
|
||||||
|
m.insert(new_hash);
|
||||||
|
});
|
||||||
envelope.set_hash(new_hash);
|
envelope.set_hash(new_hash);
|
||||||
self.envelopes.write().unwrap().insert(new_hash, envelope);
|
self.envelopes.write().unwrap().insert(new_hash, envelope);
|
||||||
|
let mut threads_lck = self.threads.write().unwrap();
|
||||||
{
|
{
|
||||||
if self
|
if threads_lck
|
||||||
.threads
|
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.update_envelope(&self.envelopes, old_hash, new_hash)
|
.update_envelope(&self.envelopes, old_hash, new_hash)
|
||||||
|
@ -155,11 +182,11 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* envelope is not in threads, so insert it */
|
/* envelope is not in threads, so insert it */
|
||||||
self.threads
|
threads_lck
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(&mut self.envelopes, new_hash);
|
.insert(&mut self.envelopes, new_hash);
|
||||||
for (h, t) in self.threads.iter_mut() {
|
for (h, t) in threads_lck.iter_mut() {
|
||||||
if *h == mailbox_hash {
|
if *h == mailbox_hash {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -178,7 +205,7 @@ impl Collection {
|
||||||
mailbox_hash: MailboxHash,
|
mailbox_hash: MailboxHash,
|
||||||
sent_mailbox: Option<MailboxHash>,
|
sent_mailbox: Option<MailboxHash>,
|
||||||
) -> Option<SmallVec<[MailboxHash; 8]>> {
|
) -> Option<SmallVec<[MailboxHash; 8]>> {
|
||||||
self.sent_mailbox = sent_mailbox;
|
*self.sent_mailbox.write().unwrap() = sent_mailbox;
|
||||||
|
|
||||||
let &mut Collection {
|
let &mut Collection {
|
||||||
ref mut threads,
|
ref mut threads,
|
||||||
|
@ -188,17 +215,19 @@ impl Collection {
|
||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
if !threads.contains_key(&mailbox_hash) {
|
let mut threads_lck = threads.write().unwrap();
|
||||||
threads.insert(mailbox_hash, Threads::new(new_envelopes.len()));
|
let mut mailboxes_lck = mailboxes.write().unwrap();
|
||||||
mailboxes.insert(mailbox_hash, new_envelopes.keys().cloned().collect());
|
if !threads_lck.contains_key(&mailbox_hash) {
|
||||||
|
threads_lck.insert(mailbox_hash, Threads::new(new_envelopes.len()));
|
||||||
|
mailboxes_lck.insert(mailbox_hash, new_envelopes.keys().cloned().collect());
|
||||||
for (h, e) in new_envelopes {
|
for (h, e) in new_envelopes {
|
||||||
envelopes.write().unwrap().insert(h, e);
|
envelopes.write().unwrap().insert(h, e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mailboxes.entry(mailbox_hash).and_modify(|m| {
|
mailboxes_lck.entry(mailbox_hash).and_modify(|m| {
|
||||||
m.extend(new_envelopes.keys().cloned());
|
m.extend(new_envelopes.keys().cloned());
|
||||||
});
|
});
|
||||||
threads.entry(mailbox_hash).and_modify(|t| {
|
threads_lck.entry(mailbox_hash).and_modify(|t| {
|
||||||
let mut ordered_hash_set =
|
let mut ordered_hash_set =
|
||||||
new_envelopes.keys().cloned().collect::<Vec<EnvelopeHash>>();
|
new_envelopes.keys().cloned().collect::<Vec<EnvelopeHash>>();
|
||||||
ordered_hash_set.sort_by(|a, b| {
|
ordered_hash_set.sort_by(|a, b| {
|
||||||
|
@ -218,14 +247,19 @@ impl Collection {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ret = SmallVec::new();
|
let mut ret = SmallVec::new();
|
||||||
let keys = threads.keys().cloned().collect::<Vec<MailboxHash>>();
|
let keys = threads_lck.keys().cloned().collect::<Vec<MailboxHash>>();
|
||||||
for t_fh in keys {
|
for t_fh in keys {
|
||||||
if t_fh == mailbox_hash {
|
if t_fh == mailbox_hash {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if sent_mailbox.map(|f| f == mailbox_hash).unwrap_or(false) {
|
if sent_mailbox
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.map(|f| f == mailbox_hash)
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
let envelopes_lck = envelopes.read().unwrap();
|
let envelopes_lck = envelopes.read().unwrap();
|
||||||
let mut ordered_hash_set = threads[&mailbox_hash]
|
let mut ordered_hash_set = threads_lck[&mailbox_hash]
|
||||||
.hash_set
|
.hash_set
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -239,16 +273,24 @@ impl Collection {
|
||||||
drop(envelopes_lck);
|
drop(envelopes_lck);
|
||||||
let mut updated = false;
|
let mut updated = false;
|
||||||
for h in ordered_hash_set {
|
for h in ordered_hash_set {
|
||||||
updated |= threads.entry(t_fh).or_default().insert_reply(envelopes, h);
|
updated |= threads_lck
|
||||||
|
.entry(t_fh)
|
||||||
|
.or_default()
|
||||||
|
.insert_reply(envelopes, h);
|
||||||
}
|
}
|
||||||
if updated {
|
if updated {
|
||||||
ret.push(t_fh);
|
ret.push(t_fh);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if sent_mailbox.map(|f| f == t_fh).unwrap_or(false) {
|
if sent_mailbox
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.map(|f| f == t_fh)
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
let envelopes_lck = envelopes.read().unwrap();
|
let envelopes_lck = envelopes.read().unwrap();
|
||||||
let mut ordered_hash_set = threads[&t_fh]
|
let mut ordered_hash_set = threads_lck[&t_fh]
|
||||||
.hash_set
|
.hash_set
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -262,7 +304,7 @@ impl Collection {
|
||||||
drop(envelopes_lck);
|
drop(envelopes_lck);
|
||||||
let mut updated = false;
|
let mut updated = false;
|
||||||
for h in ordered_hash_set {
|
for h in ordered_hash_set {
|
||||||
updated |= threads
|
updated |= threads_lck
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert_reply(envelopes, h);
|
.insert_reply(envelopes, h);
|
||||||
|
@ -288,24 +330,30 @@ impl Collection {
|
||||||
let old_env = self.envelopes.write().unwrap().remove(&old_hash).unwrap();
|
let old_env = self.envelopes.write().unwrap().remove(&old_hash).unwrap();
|
||||||
envelope.set_thread(old_env.thread());
|
envelope.set_thread(old_env.thread());
|
||||||
let new_hash = envelope.hash();
|
let new_hash = envelope.hash();
|
||||||
self.mailboxes.entry(mailbox_hash).and_modify(|m| {
|
self.mailboxes
|
||||||
m.remove(&old_hash);
|
.write()
|
||||||
m.insert(new_hash);
|
.unwrap()
|
||||||
});
|
.entry(mailbox_hash)
|
||||||
|
.and_modify(|m| {
|
||||||
|
m.remove(&old_hash);
|
||||||
|
m.insert(new_hash);
|
||||||
|
});
|
||||||
self.envelopes.write().unwrap().insert(new_hash, envelope);
|
self.envelopes.write().unwrap().insert(new_hash, envelope);
|
||||||
|
let mut threads_lck = self.threads.write().unwrap();
|
||||||
if self
|
if self
|
||||||
.sent_mailbox
|
.sent_mailbox
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
.map(|f| f == mailbox_hash)
|
.map(|f| f == mailbox_hash)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
for (_, t) in self.threads.iter_mut() {
|
for (_, t) in threads_lck.iter_mut() {
|
||||||
t.update_envelope(&self.envelopes, old_hash, new_hash)
|
t.update_envelope(&self.envelopes, old_hash, new_hash)
|
||||||
.unwrap_or(());
|
.unwrap_or(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if self
|
if threads_lck
|
||||||
.threads
|
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.update_envelope(&self.envelopes, old_hash, new_hash)
|
.update_envelope(&self.envelopes, old_hash, new_hash)
|
||||||
|
@ -315,11 +363,11 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* envelope is not in threads, so insert it */
|
/* envelope is not in threads, so insert it */
|
||||||
self.threads
|
threads_lck
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(&mut self.envelopes, new_hash);
|
.insert(&mut self.envelopes, new_hash);
|
||||||
for (h, t) in self.threads.iter_mut() {
|
for (h, t) in threads_lck.iter_mut() {
|
||||||
if *h == mailbox_hash {
|
if *h == mailbox_hash {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -330,19 +378,21 @@ impl Collection {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_flags(&mut self, env_hash: EnvelopeHash, mailbox_hash: MailboxHash) {
|
pub fn update_flags(&mut self, env_hash: EnvelopeHash, mailbox_hash: MailboxHash) {
|
||||||
|
let mut threads_lck = self.threads.write().unwrap();
|
||||||
if self
|
if self
|
||||||
.sent_mailbox
|
.sent_mailbox
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
.map(|f| f == mailbox_hash)
|
.map(|f| f == mailbox_hash)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
for (_, t) in self.threads.iter_mut() {
|
for (_, t) in threads_lck.iter_mut() {
|
||||||
t.update_envelope(&self.envelopes, env_hash, env_hash)
|
t.update_envelope(&self.envelopes, env_hash, env_hash)
|
||||||
.unwrap_or(());
|
.unwrap_or(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if self
|
if threads_lck
|
||||||
.threads
|
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.update_envelope(&self.envelopes, env_hash, env_hash)
|
.update_envelope(&self.envelopes, env_hash, env_hash)
|
||||||
|
@ -352,11 +402,11 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* envelope is not in threads, so insert it */
|
/* envelope is not in threads, so insert it */
|
||||||
self.threads
|
threads_lck
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(&mut self.envelopes, env_hash);
|
.insert(&mut self.envelopes, env_hash);
|
||||||
for (h, t) in self.threads.iter_mut() {
|
for (h, t) in threads_lck.iter_mut() {
|
||||||
if *h == mailbox_hash {
|
if *h == mailbox_hash {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -368,16 +418,24 @@ impl Collection {
|
||||||
|
|
||||||
pub fn insert(&mut self, envelope: Envelope, mailbox_hash: MailboxHash) -> bool {
|
pub fn insert(&mut self, envelope: Envelope, mailbox_hash: MailboxHash) -> bool {
|
||||||
let hash = envelope.hash();
|
let hash = envelope.hash();
|
||||||
self.mailboxes.entry(mailbox_hash).and_modify(|m| {
|
self.mailboxes
|
||||||
m.insert(hash);
|
.write()
|
||||||
});
|
.unwrap()
|
||||||
|
.entry(mailbox_hash)
|
||||||
|
.and_modify(|m| {
|
||||||
|
m.insert(hash);
|
||||||
|
});
|
||||||
self.envelopes.write().unwrap().insert(hash, envelope);
|
self.envelopes.write().unwrap().insert(hash, envelope);
|
||||||
self.threads
|
self.threads
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(&mut self.envelopes, hash);
|
.insert(&mut self.envelopes, hash);
|
||||||
if self
|
if self
|
||||||
.sent_mailbox
|
.sent_mailbox
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
.map(|f| f == mailbox_hash)
|
.map(|f| f == mailbox_hash)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
|
@ -388,7 +446,7 @@ impl Collection {
|
||||||
|
|
||||||
pub fn insert_reply(&mut self, env_hash: EnvelopeHash) {
|
pub fn insert_reply(&mut self, env_hash: EnvelopeHash) {
|
||||||
debug_assert!(self.envelopes.read().unwrap().contains_key(&env_hash));
|
debug_assert!(self.envelopes.read().unwrap().contains_key(&env_hash));
|
||||||
for (_, t) in self.threads.iter_mut() {
|
for (_, t) in self.threads.write().unwrap().iter_mut() {
|
||||||
t.insert_reply(&mut self.envelopes, env_hash);
|
t.insert_reply(&mut self.envelopes, env_hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,27 +461,45 @@ impl Collection {
|
||||||
EnvelopeRefMut { guard, env_hash }
|
EnvelopeRefMut { guard, env_hash }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_threads(&'_ self, hash: MailboxHash) -> RwRef<'_, MailboxHash, Threads> {
|
||||||
|
let guard = self.threads.read().unwrap();
|
||||||
|
RwRef { guard, hash }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mailbox(
|
||||||
|
&'_ self,
|
||||||
|
hash: MailboxHash,
|
||||||
|
) -> RwRef<'_, MailboxHash, HashSet<EnvelopeHash>> {
|
||||||
|
let guard = self.mailboxes.read().unwrap();
|
||||||
|
RwRef { guard, hash }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn contains_key(&self, env_hash: &EnvelopeHash) -> bool {
|
pub fn contains_key(&self, env_hash: &EnvelopeHash) -> bool {
|
||||||
self.envelopes.read().unwrap().contains_key(env_hash)
|
self.envelopes.read().unwrap().contains_key(env_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_mailbox(&mut self, mailbox_hash: MailboxHash) {
|
pub fn new_mailbox(&mut self, mailbox_hash: MailboxHash) {
|
||||||
if !self.mailboxes.contains_key(&mailbox_hash) {
|
let mut mailboxes_lck = self.mailboxes.write().unwrap();
|
||||||
self.mailboxes.insert(mailbox_hash, Default::default());
|
if !mailboxes_lck.contains_key(&mailbox_hash) {
|
||||||
self.threads.insert(mailbox_hash, Threads::default());
|
mailboxes_lck.insert(mailbox_hash, Default::default());
|
||||||
|
self.threads
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(mailbox_hash, Threads::default());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<&MailboxHash> for Collection {
|
|
||||||
type Output = HashSet<EnvelopeHash>;
|
pub struct RwRef<'g, K: std::cmp::Eq + std::hash::Hash, V> {
|
||||||
fn index(&self, index: &MailboxHash) -> &HashSet<EnvelopeHash> {
|
guard: RwLockReadGuard<'g, HashMap<K, V>>,
|
||||||
&self.mailboxes[index]
|
hash: K,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndexMut<&MailboxHash> for Collection {
|
impl<K: std::cmp::Eq + std::hash::Hash, V> Deref for RwRef<'_, K, V> {
|
||||||
fn index_mut(&mut self, index: &MailboxHash) -> &mut HashSet<EnvelopeHash> {
|
type Target = V;
|
||||||
self.mailboxes.get_mut(index).unwrap()
|
|
||||||
|
fn deref(&self) -> &V {
|
||||||
|
self.guard.get(&self.hash).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,9 +148,13 @@ pub trait MailListingTrait: ListingTrait {
|
||||||
let account = &mut context.accounts[account_pos];
|
let account = &mut context.accounts[account_pos];
|
||||||
let mut envs_to_set: SmallVec<[EnvelopeHash; 8]> = SmallVec::new();
|
let mut envs_to_set: SmallVec<[EnvelopeHash; 8]> = SmallVec::new();
|
||||||
let mailbox_hash = self.coordinates().1;
|
let mailbox_hash = self.coordinates().1;
|
||||||
for (_, h) in account.collection.threads[&mailbox_hash].thread_group_iter(thread_hash) {
|
for (_, h) in account
|
||||||
|
.collection
|
||||||
|
.get_threads(mailbox_hash)
|
||||||
|
.thread_group_iter(thread_hash)
|
||||||
|
{
|
||||||
envs_to_set.push(
|
envs_to_set.push(
|
||||||
account.collection.threads[&mailbox_hash].thread_nodes()[&h]
|
account.collection.get_threads(mailbox_hash).thread_nodes()[&h]
|
||||||
.message()
|
.message()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
@ -1209,7 +1213,7 @@ impl Component for Listing {
|
||||||
MailboxStatus::Available | MailboxStatus::Parsing(_, _) => format!(
|
MailboxStatus::Available | MailboxStatus::Parsing(_, _) => format!(
|
||||||
"Mailbox: {}, Messages: {}, New: {}",
|
"Mailbox: {}, Messages: {}, New: {}",
|
||||||
account[&mailbox_hash].ref_mailbox.name(),
|
account[&mailbox_hash].ref_mailbox.name(),
|
||||||
account.collection[&mailbox_hash].len(),
|
account.collection.get_mailbox(mailbox_hash).len(),
|
||||||
account[&mailbox_hash]
|
account[&mailbox_hash]
|
||||||
.ref_mailbox
|
.ref_mailbox
|
||||||
.count()
|
.count()
|
||||||
|
|
|
@ -247,7 +247,9 @@ impl MailListingTrait for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let threads = &context.accounts[self.cursor_pos.0].collection.threads[&self.cursor_pos.1];
|
let threads = context.accounts[self.cursor_pos.0]
|
||||||
|
.collection
|
||||||
|
.get_threads(self.cursor_pos.1);
|
||||||
let mut roots = threads.roots();
|
let mut roots = threads.roots();
|
||||||
threads.group_inner_sort_by(
|
threads.group_inner_sort_by(
|
||||||
&mut roots,
|
&mut roots,
|
||||||
|
@ -276,7 +278,7 @@ impl MailListingTrait for CompactListing {
|
||||||
) {
|
) {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
|
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
self.order.clear();
|
self.order.clear();
|
||||||
self.length = 0;
|
self.length = 0;
|
||||||
let mut rows = Vec::with_capacity(1024);
|
let mut rows = Vec::with_capacity(1024);
|
||||||
|
@ -341,7 +343,7 @@ impl MailListingTrait for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let entry_strings = self.make_entry_string(&root_envelope, context, threads, thread);
|
let entry_strings = self.make_entry_string(&root_envelope, context, &threads, thread);
|
||||||
row_widths.1.push(
|
row_widths.1.push(
|
||||||
entry_strings
|
entry_strings
|
||||||
.date
|
.date
|
||||||
|
@ -462,7 +464,7 @@ impl ListingTrait for CompactListing {
|
||||||
let thread_hash = self.get_thread_under_cursor(idx);
|
let thread_hash = self.get_thread_under_cursor(idx);
|
||||||
|
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
let thread = threads.thread_ref(thread_hash);
|
let thread = threads.thread_ref(thread_hash);
|
||||||
|
|
||||||
let row_attr = row_attr!(
|
let row_attr = row_attr!(
|
||||||
|
@ -685,7 +687,7 @@ impl ListingTrait for CompactListing {
|
||||||
}
|
}
|
||||||
|
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
for r in 0..cmp::min(self.length - top_idx, rows) {
|
for r in 0..cmp::min(self.length - top_idx, rows) {
|
||||||
let thread_hash = self.get_thread_under_cursor(r + top_idx);
|
let thread_hash = self.get_thread_under_cursor(r + top_idx);
|
||||||
let row_attr = row_attr!(
|
let row_attr = row_attr!(
|
||||||
|
@ -767,7 +769,7 @@ impl ListingTrait for CompactListing {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
match results {
|
match results {
|
||||||
Ok(results) => {
|
Ok(results) => {
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
for env_hash in results {
|
for env_hash in results {
|
||||||
if !account.collection.contains_key(&env_hash) {
|
if !account.collection.contains_key(&env_hash) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -971,7 +973,7 @@ impl CompactListing {
|
||||||
|
|
||||||
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
|
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
let thread = threads.thread_ref(thread_hash);
|
let thread = threads.thread_ref(thread_hash);
|
||||||
let thread_node_hash = threads.thread_group_iter(thread_hash).next().unwrap().1;
|
let thread_node_hash = threads.thread_group_iter(thread_hash).next().unwrap().1;
|
||||||
if let Some(env_hash) = threads.thread_nodes()[&thread_node_hash].message() {
|
if let Some(env_hash) = threads.thread_nodes()[&thread_node_hash].message() {
|
||||||
|
@ -993,7 +995,7 @@ impl CompactListing {
|
||||||
self.color_cache.odd
|
self.color_cache.odd
|
||||||
};
|
};
|
||||||
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
||||||
let strings = self.make_entry_string(&envelope, context, threads, thread_hash);
|
let strings = self.make_entry_string(&envelope, context, &threads, thread_hash);
|
||||||
drop(envelope);
|
drop(envelope);
|
||||||
let columns = &mut self.data_columns.columns;
|
let columns = &mut self.data_columns.columns;
|
||||||
let min_width = (
|
let min_width = (
|
||||||
|
@ -1136,7 +1138,7 @@ impl CompactListing {
|
||||||
);
|
);
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
|
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
|
|
||||||
for ((idx, (thread_hash, root_env_hash)), strings) in
|
for ((idx, (thread_hash, root_env_hash)), strings) in
|
||||||
self.rows.iter().skip(start).take(end - start + 1)
|
self.rows.iter().skip(start).take(end - start + 1)
|
||||||
|
@ -1309,7 +1311,7 @@ impl CompactListing {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
match results {
|
match results {
|
||||||
Ok(results) => {
|
Ok(results) => {
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
for env_hash in results {
|
for env_hash in results {
|
||||||
if !account.collection.contains_key(&env_hash) {
|
if !account.collection.contains_key(&env_hash) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1497,6 +1499,8 @@ impl Component for CompactListing {
|
||||||
account
|
account
|
||||||
.collection
|
.collection
|
||||||
.threads
|
.threads
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.entry(self.cursor_pos.1)
|
.entry(self.cursor_pos.1)
|
||||||
.and_modify(|threads| {
|
.and_modify(|threads| {
|
||||||
let is_snoozed = threads.thread_ref(thread).snoozed();
|
let is_snoozed = threads.thread_ref(thread).snoozed();
|
||||||
|
@ -1526,7 +1530,7 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
if !account.collection.contains_key(&new_hash) {
|
if !account.collection.contains_key(&new_hash) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1536,6 +1540,7 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
let thread: ThreadHash =
|
let thread: ThreadHash =
|
||||||
threads.find_group(threads.thread_nodes()[&new_env_thread_node_hash].group);
|
threads.find_group(threads.thread_nodes()[&new_env_thread_node_hash].group);
|
||||||
|
drop(threads);
|
||||||
if self.order.contains_key(&thread) {
|
if self.order.contains_key(&thread) {
|
||||||
self.row_updates.push(thread);
|
self.row_updates.push(thread);
|
||||||
}
|
}
|
||||||
|
@ -1553,7 +1558,7 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
UIEvent::EnvelopeUpdate(ref env_hash) => {
|
UIEvent::EnvelopeUpdate(ref env_hash) => {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
if !account.collection.contains_key(&env_hash) {
|
if !account.collection.contains_key(&env_hash) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1563,6 +1568,7 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
let thread: ThreadHash =
|
let thread: ThreadHash =
|
||||||
threads.find_group(threads.thread_nodes()[&new_env_thread_node_hash].group);
|
threads.find_group(threads.thread_nodes()[&new_env_thread_node_hash].group);
|
||||||
|
drop(threads);
|
||||||
if self.order.contains_key(&thread) {
|
if self.order.contains_key(&thread) {
|
||||||
self.row_updates.push(thread);
|
self.row_updates.push(thread);
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,9 @@ impl MailListingTrait for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let threads = &context.accounts[self.cursor_pos.0].collection.threads[&self.cursor_pos.1];
|
let threads = context.accounts[self.cursor_pos.0]
|
||||||
|
.collection
|
||||||
|
.get_threads(self.cursor_pos.1);
|
||||||
self.all_threads.clear();
|
self.all_threads.clear();
|
||||||
let mut roots = threads.roots();
|
let mut roots = threads.roots();
|
||||||
threads.group_inner_sort_by(
|
threads.group_inner_sort_by(
|
||||||
|
@ -183,7 +185,7 @@ impl MailListingTrait for ConversationsListing {
|
||||||
) {
|
) {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
|
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
self.order.clear();
|
self.order.clear();
|
||||||
self.selection.clear();
|
self.selection.clear();
|
||||||
self.length = 0;
|
self.length = 0;
|
||||||
|
@ -255,8 +257,13 @@ impl MailListingTrait for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let strings =
|
let strings = self.make_entry_string(
|
||||||
self.make_entry_string(root_envelope, context, &from_address_list, threads, thread);
|
root_envelope,
|
||||||
|
context,
|
||||||
|
&from_address_list,
|
||||||
|
&threads,
|
||||||
|
thread,
|
||||||
|
);
|
||||||
max_entry_columns = std::cmp::max(
|
max_entry_columns = std::cmp::max(
|
||||||
max_entry_columns,
|
max_entry_columns,
|
||||||
strings.flag.len()
|
strings.flag.len()
|
||||||
|
@ -436,7 +443,7 @@ impl ListingTrait for ConversationsListing {
|
||||||
let thread_hash = self.get_thread_under_cursor(idx);
|
let thread_hash = self.get_thread_under_cursor(idx);
|
||||||
|
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
let thread = threads.thread_ref(thread_hash);
|
let thread = threads.thread_ref(thread_hash);
|
||||||
|
|
||||||
let fg_color = if thread.unseen() > 0 {
|
let fg_color = if thread.unseen() > 0 {
|
||||||
|
@ -717,7 +724,7 @@ impl ListingTrait for ConversationsListing {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
match results {
|
match results {
|
||||||
Ok(results) => {
|
Ok(results) => {
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
for env_hash in results {
|
for env_hash in results {
|
||||||
if !account.collection.contains_key(&env_hash) {
|
if !account.collection.contains_key(&env_hash) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -952,7 +959,7 @@ impl ConversationsListing {
|
||||||
|
|
||||||
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
|
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
let thread = threads.thread_ref(thread_hash);
|
let thread = threads.thread_ref(thread_hash);
|
||||||
let thread_node_hash = threads.thread_group_iter(thread_hash).next().unwrap().1;
|
let thread_node_hash = threads.thread_group_iter(thread_hash).next().unwrap().1;
|
||||||
let idx: usize = self.order[&thread_hash];
|
let idx: usize = self.order[&thread_hash];
|
||||||
|
@ -989,8 +996,13 @@ impl ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
||||||
let strings =
|
let strings = self.make_entry_string(
|
||||||
self.make_entry_string(&envelope, context, &from_address_list, threads, thread_hash);
|
&envelope,
|
||||||
|
context,
|
||||||
|
&from_address_list,
|
||||||
|
&threads,
|
||||||
|
thread_hash,
|
||||||
|
);
|
||||||
drop(envelope);
|
drop(envelope);
|
||||||
/* draw flags */
|
/* draw flags */
|
||||||
let (x, _) = write_string_to_grid(
|
let (x, _) = write_string_to_grid(
|
||||||
|
@ -1236,7 +1248,7 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
if !account.collection.contains_key(&new_hash) {
|
if !account.collection.contains_key(&new_hash) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1246,6 +1258,7 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
let thread: ThreadHash =
|
let thread: ThreadHash =
|
||||||
threads.find_group(threads.thread_nodes()[&env_thread_node_hash].group);
|
threads.find_group(threads.thread_nodes()[&env_thread_node_hash].group);
|
||||||
|
drop(threads);
|
||||||
if self.order.contains_key(&thread) {
|
if self.order.contains_key(&thread) {
|
||||||
self.row_updates.push(thread);
|
self.row_updates.push(thread);
|
||||||
}
|
}
|
||||||
|
@ -1257,7 +1270,7 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
UIEvent::EnvelopeUpdate(ref env_hash) => {
|
UIEvent::EnvelopeUpdate(ref env_hash) => {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
if !account.collection.contains_key(&env_hash) {
|
if !account.collection.contains_key(&env_hash) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1267,6 +1280,7 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
let thread: ThreadHash =
|
let thread: ThreadHash =
|
||||||
threads.find_group(threads.thread_nodes()[&env_thread_node_hash].group);
|
threads.find_group(threads.thread_nodes()[&env_thread_node_hash].group);
|
||||||
|
drop(threads);
|
||||||
if self.order.contains_key(&thread) {
|
if self.order.contains_key(&thread) {
|
||||||
self.row_updates.push(thread);
|
self.row_updates.push(thread);
|
||||||
}
|
}
|
||||||
|
@ -1315,6 +1329,8 @@ impl Component for ConversationsListing {
|
||||||
account
|
account
|
||||||
.collection
|
.collection
|
||||||
.threads
|
.threads
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.entry(self.cursor_pos.1)
|
.entry(self.cursor_pos.1)
|
||||||
.and_modify(|threads| {
|
.and_modify(|threads| {
|
||||||
let is_snoozed = threads.thread_ref(thread).snoozed();
|
let is_snoozed = threads.thread_ref(thread).snoozed();
|
||||||
|
|
|
@ -169,7 +169,9 @@ impl MailListingTrait for PlainListing {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.local_collection = context.accounts[self.cursor_pos.0].collection[&self.cursor_pos.1]
|
self.local_collection = context.accounts[self.cursor_pos.0]
|
||||||
|
.collection
|
||||||
|
.get_mailbox(self.cursor_pos.1)
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -178,8 +180,9 @@ impl MailListingTrait for PlainListing {
|
||||||
.envelopes
|
.envelopes
|
||||||
.read()
|
.read()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.thread_node_hashes = context.accounts[self.cursor_pos.0].collection
|
self.thread_node_hashes = context.accounts[self.cursor_pos.0]
|
||||||
[&self.cursor_pos.1]
|
.collection
|
||||||
|
.get_mailbox(self.cursor_pos.1)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|h| (*h, env_lck[h].thread()))
|
.map(|h| (*h, env_lck[h].thread()))
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -232,7 +235,7 @@ impl MailListingTrait for PlainListing {
|
||||||
items: Box<dyn Iterator<Item = ThreadHash>>,
|
items: Box<dyn Iterator<Item = ThreadHash>>,
|
||||||
) {
|
) {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
let roots = items
|
let roots = items
|
||||||
.filter_map(|r| threads.groups[&r].root().map(|r| r.root))
|
.filter_map(|r| threads.groups[&r].root().map(|r| r.root))
|
||||||
.collect::<_>();
|
.collect::<_>();
|
||||||
|
@ -1218,7 +1221,10 @@ impl Component for PlainListing {
|
||||||
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
if !account.collection.contains_key(new_hash)
|
if !account.collection.contains_key(new_hash)
|
||||||
|| !account.collection[&self.cursor_pos.1].contains(new_hash)
|
|| !account
|
||||||
|
.collection
|
||||||
|
.get_mailbox(self.cursor_pos.1)
|
||||||
|
.contains(new_hash)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1244,7 +1250,10 @@ impl Component for PlainListing {
|
||||||
UIEvent::EnvelopeUpdate(ref env_hash) => {
|
UIEvent::EnvelopeUpdate(ref env_hash) => {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
if !account.collection.contains_key(env_hash)
|
if !account.collection.contains_key(env_hash)
|
||||||
|| !account.collection[&self.cursor_pos.1].contains(env_hash)
|
|| !account
|
||||||
|
.collection
|
||||||
|
.get_mailbox(self.cursor_pos.1)
|
||||||
|
.contains(env_hash)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,9 @@ impl MailListingTrait for ThreadListing {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let threads = &context.accounts[self.cursor_pos.0].collection.threads[&self.cursor_pos.1];
|
let threads = context.accounts[self.cursor_pos.0]
|
||||||
|
.collection
|
||||||
|
.get_threads(self.cursor_pos.1);
|
||||||
let mut roots = threads.roots();
|
let mut roots = threads.roots();
|
||||||
threads.group_inner_sort_by(
|
threads.group_inner_sort_by(
|
||||||
&mut roots,
|
&mut roots,
|
||||||
|
@ -141,7 +143,7 @@ impl MailListingTrait for ThreadListing {
|
||||||
items: Box<dyn Iterator<Item = ThreadHash>>,
|
items: Box<dyn Iterator<Item = ThreadHash>>,
|
||||||
) {
|
) {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
self.length = 0;
|
self.length = 0;
|
||||||
self.order.clear();
|
self.order.clear();
|
||||||
let default_cell = {
|
let default_cell = {
|
||||||
|
@ -226,7 +228,7 @@ impl MailListingTrait for ThreadListing {
|
||||||
idx,
|
idx,
|
||||||
indentation,
|
indentation,
|
||||||
thread_node_hash,
|
thread_node_hash,
|
||||||
threads,
|
&threads,
|
||||||
&indentations,
|
&indentations,
|
||||||
has_sibling,
|
has_sibling,
|
||||||
is_root,
|
is_root,
|
||||||
|
@ -1164,7 +1166,6 @@ impl Component for ThreadListing {
|
||||||
}
|
}
|
||||||
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
|
||||||
if !account.collection.contains_key(&new_hash) {
|
if !account.collection.contains_key(&new_hash) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1188,7 +1189,6 @@ impl Component for ThreadListing {
|
||||||
}
|
}
|
||||||
UIEvent::EnvelopeUpdate(ref env_hash) => {
|
UIEvent::EnvelopeUpdate(ref env_hash) => {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
let threads = &account.collection.threads[&self.cursor_pos.1];
|
|
||||||
if !account.collection.contains_key(env_hash) {
|
if !account.collection.contains_key(env_hash) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ impl ThreadView {
|
||||||
|
|
||||||
fn initiate(&mut self, expanded_hash: Option<ThreadNodeHash>, context: &Context) {
|
fn initiate(&mut self, expanded_hash: Option<ThreadNodeHash>, context: &Context) {
|
||||||
let account = &context.accounts[self.coordinates.0];
|
let account = &context.accounts[self.coordinates.0];
|
||||||
let threads = &account.collection.threads[&self.coordinates.1];
|
let threads = account.collection.get_threads(self.coordinates.1);
|
||||||
|
|
||||||
if !threads.groups.contains_key(&self.thread_group) {
|
if !threads.groups.contains_key(&self.thread_group) {
|
||||||
return;
|
return;
|
||||||
|
@ -648,7 +648,7 @@ impl ThreadView {
|
||||||
let y = if self.dirty {
|
let y = if self.dirty {
|
||||||
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
||||||
let account = &context.accounts[self.coordinates.0];
|
let account = &context.accounts[self.coordinates.0];
|
||||||
let threads = &account.collection.threads[&self.coordinates.1];
|
let threads = account.collection.get_threads(self.coordinates.1);
|
||||||
let thread_root = threads
|
let thread_root = threads
|
||||||
.thread_group_iter(self.thread_group)
|
.thread_group_iter(self.thread_group)
|
||||||
.next()
|
.next()
|
||||||
|
@ -751,7 +751,7 @@ impl ThreadView {
|
||||||
let y = {
|
let y = {
|
||||||
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
||||||
let account = &context.accounts[self.coordinates.0];
|
let account = &context.accounts[self.coordinates.0];
|
||||||
let threads = &account.collection.threads[&self.coordinates.1];
|
let threads = account.collection.get_threads(self.coordinates.1);
|
||||||
let thread_root = threads
|
let thread_root = threads
|
||||||
.thread_group_iter(self.thread_group)
|
.thread_group_iter(self.thread_group)
|
||||||
.next()
|
.next()
|
||||||
|
|
|
@ -726,7 +726,10 @@ impl Account {
|
||||||
RefreshEventKind::Create(envelope) => {
|
RefreshEventKind::Create(envelope) => {
|
||||||
let env_hash = envelope.hash();
|
let env_hash = envelope.hash();
|
||||||
if self.collection.contains_key(&env_hash)
|
if self.collection.contains_key(&env_hash)
|
||||||
&& self.collection[&mailbox_hash].contains(&env_hash)
|
&& self
|
||||||
|
.collection
|
||||||
|
.get_mailbox(mailbox_hash)
|
||||||
|
.contains(&env_hash)
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -770,10 +773,13 @@ impl Account {
|
||||||
|
|
||||||
let thread = {
|
let thread = {
|
||||||
let thread_hash = self.collection.get_env(env_hash).thread();
|
let thread_hash = self.collection.get_env(env_hash).thread();
|
||||||
self.collection.threads[&mailbox_hash]
|
self.collection.get_threads(mailbox_hash).find_group(
|
||||||
.find_group(self.collection.threads[&mailbox_hash][&thread_hash].group)
|
self.collection.get_threads(mailbox_hash)[&thread_hash].group,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
if self.collection.threads[&mailbox_hash]
|
if self
|
||||||
|
.collection
|
||||||
|
.get_threads(mailbox_hash)
|
||||||
.thread_ref(thread)
|
.thread_ref(thread)
|
||||||
.snoozed()
|
.snoozed()
|
||||||
{
|
{
|
||||||
|
@ -797,8 +803,9 @@ impl Account {
|
||||||
RefreshEventKind::Remove(env_hash) => {
|
RefreshEventKind::Remove(env_hash) => {
|
||||||
let thread_hash = {
|
let thread_hash = {
|
||||||
let thread_hash = self.collection.get_env(env_hash).thread();
|
let thread_hash = self.collection.get_env(env_hash).thread();
|
||||||
self.collection.threads[&mailbox_hash]
|
self.collection.get_threads(mailbox_hash).find_group(
|
||||||
.find_group(self.collection.threads[&mailbox_hash][&thread_hash].group)
|
self.collection.get_threads(mailbox_hash)[&thread_hash].group,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
#[cfg(feature = "sqlite3")]
|
#[cfg(feature = "sqlite3")]
|
||||||
{
|
{
|
||||||
|
@ -1006,7 +1013,12 @@ impl Account {
|
||||||
None => {
|
None => {
|
||||||
return match self.mailbox_entries[&mailbox_hash].status {
|
return match self.mailbox_entries[&mailbox_hash].status {
|
||||||
MailboxStatus::Available | MailboxStatus::Parsing(_, _)
|
MailboxStatus::Available | MailboxStatus::Parsing(_, _)
|
||||||
if self.collection.mailboxes.contains_key(&mailbox_hash) =>
|
if self
|
||||||
|
.collection
|
||||||
|
.mailboxes
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.contains_key(&mailbox_hash) =>
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1157,7 +1169,12 @@ impl Account {
|
||||||
}
|
}
|
||||||
if self.mailbox_entries[&mailbox_hash].status.is_available()
|
if self.mailbox_entries[&mailbox_hash].status.is_available()
|
||||||
|| (self.mailbox_entries[&mailbox_hash].status.is_parsing()
|
|| (self.mailbox_entries[&mailbox_hash].status.is_parsing()
|
||||||
&& self.collection.mailboxes.contains_key(&mailbox_hash))
|
&& self
|
||||||
|
.collection
|
||||||
|
.mailboxes
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.contains_key(&mailbox_hash))
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -1346,10 +1363,6 @@ impl Account {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thread(&self, h: ThreadNodeHash, f: MailboxHash) -> &ThreadNode {
|
|
||||||
&self.collection.threads[&f].thread_nodes()[&h]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mailbox_operation(
|
pub fn mailbox_operation(
|
||||||
&mut self,
|
&mut self,
|
||||||
op: crate::execute::actions::MailboxOperation,
|
op: crate::execute::actions::MailboxOperation,
|
||||||
|
@ -1417,9 +1430,13 @@ impl Account {
|
||||||
);
|
);
|
||||||
self.collection
|
self.collection
|
||||||
.threads
|
.threads
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.insert(mailbox_hash, Threads::default());
|
.insert(mailbox_hash, Threads::default());
|
||||||
self.collection
|
self.collection
|
||||||
.mailboxes
|
.mailboxes
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.insert(mailbox_hash, Default::default());
|
.insert(mailbox_hash, Default::default());
|
||||||
build_mailboxes_order(
|
build_mailboxes_order(
|
||||||
&mut self.tree,
|
&mut self.tree,
|
||||||
|
@ -1451,7 +1468,11 @@ impl Account {
|
||||||
if self.sent_mailbox == Some(mailbox_hash) {
|
if self.sent_mailbox == Some(mailbox_hash) {
|
||||||
self.sent_mailbox = None;
|
self.sent_mailbox = None;
|
||||||
}
|
}
|
||||||
self.collection.threads.remove(&mailbox_hash);
|
self.collection
|
||||||
|
.threads
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.remove(&mailbox_hash);
|
||||||
let deleted_mailbox = self.mailbox_entries.remove(&mailbox_hash).unwrap();
|
let deleted_mailbox = self.mailbox_entries.remove(&mailbox_hash).unwrap();
|
||||||
/* if deleted mailbox had parent, we need to update its children field */
|
/* if deleted mailbox had parent, we need to update its children field */
|
||||||
if let Some(parent_hash) = deleted_mailbox.ref_mailbox.parent() {
|
if let Some(parent_hash) = deleted_mailbox.ref_mailbox.parent() {
|
||||||
|
@ -1461,7 +1482,11 @@ impl Account {
|
||||||
parent.ref_mailbox = mailboxes.remove(&parent_hash).unwrap();
|
parent.ref_mailbox = mailboxes.remove(&parent_hash).unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.collection.mailboxes.remove(&mailbox_hash);
|
self.collection
|
||||||
|
.mailboxes
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.remove(&mailbox_hash);
|
||||||
build_mailboxes_order(
|
build_mailboxes_order(
|
||||||
&mut self.tree,
|
&mut self.tree,
|
||||||
&self.mailbox_entries,
|
&self.mailbox_entries,
|
||||||
|
@ -1576,7 +1601,7 @@ impl Account {
|
||||||
let mut ret = SmallVec::new();
|
let mut ret = SmallVec::new();
|
||||||
let envelopes = self.collection.envelopes.read().unwrap();
|
let envelopes = self.collection.envelopes.read().unwrap();
|
||||||
|
|
||||||
for &env_hash in self.collection[&mailbox_hash].iter() {
|
for &env_hash in self.collection.get_mailbox(mailbox_hash).iter() {
|
||||||
let envelope = &envelopes[&env_hash];
|
let envelope = &envelopes[&env_hash];
|
||||||
if envelope.subject().contains(&search_term) {
|
if envelope.subject().contains(&search_term) {
|
||||||
ret.push(env_hash);
|
ret.push(env_hash);
|
||||||
|
|
Loading…
Reference in New Issue