summaryrefslogtreecommitdiff
path: root/src/components/mail/listing/compact.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/mail/listing/compact.rs')
-rw-r--r--src/components/mail/listing/compact.rs170
1 files changed, 153 insertions, 17 deletions
diff --git a/src/components/mail/listing/compact.rs b/src/components/mail/listing/compact.rs
index 52387433..3ddc89c6 100644
--- a/src/components/mail/listing/compact.rs
+++ b/src/components/mail/listing/compact.rs
@@ -22,7 +22,9 @@
use super::*;
use crate::components::PageMovement;
use crate::jobs::JoinHandle;
+use indexmap::IndexSet;
use std::cmp;
+use std::collections::BTreeMap;
use std::convert::TryInto;
use std::iter::FromIterator;
@@ -329,6 +331,13 @@ impl MailListingTrait for CompactListing {
SmallVec::new(),
);
+ let tags_lck = account.collection.tag_index.read().unwrap();
+
+ let mut other_subjects = IndexSet::new();
+ let mut tags = IndexSet::new();
+ let mut from_address_list = Vec::new();
+ let mut from_address_set: std::collections::HashSet<Vec<u8>> =
+ std::collections::HashSet::new();
'items_for_loop: for thread in items {
let thread_node = &threads.thread_nodes()[&threads.thread_ref(thread).root()];
let root_env_hash = if let Some(h) = thread_node.message().or_else(|| {
@@ -374,6 +383,45 @@ impl MailListingTrait for CompactListing {
continue;
}
}
+ other_subjects.clear();
+ tags.clear();
+ from_address_list.clear();
+ from_address_set.clear();
+ for (envelope, show_subject) in threads
+ .thread_group_iter(thread)
+ .filter_map(|(_, h)| {
+ Some((
+ threads.thread_nodes()[&h].message()?,
+ threads.thread_nodes()[&h].show_subject(),
+ ))
+ })
+ .map(|(env_hash, show_subject)| {
+ (
+ context.accounts[&self.cursor_pos.0]
+ .collection
+ .get_env(env_hash),
+ show_subject,
+ )
+ })
+ {
+ if show_subject {
+ other_subjects.insert(envelope.subject().to_string());
+ }
+ if account.backend_capabilities.supports_tags {
+ for &t in envelope.tags().iter() {
+ tags.insert(t);
+ }
+ }
+
+ for addr in envelope.from().iter() {
+ if from_address_set.contains(addr.address_spec_raw()) {
+ continue;
+ }
+ from_address_set.insert(addr.address_spec_raw().to_vec());
+ from_address_list.push(addr.clone());
+ }
+ }
+
let row_attr = row_attr!(
self.color_cache,
self.length % 2 == 0,
@@ -383,7 +431,16 @@ impl MailListingTrait for CompactListing {
);
self.rows.row_attr_cache.insert(self.length, row_attr);
- let entry_strings = self.make_entry_string(&root_envelope, context, &threads, thread);
+ let entry_strings = self.make_entry_string(
+ &root_envelope,
+ context,
+ &tags_lck,
+ &from_address_list,
+ &threads,
+ &other_subjects,
+ &tags,
+ thread,
+ );
row_widths
.0
.push(digits_of_num!(self.length).try_into().unwrap_or(255));
@@ -843,18 +900,21 @@ impl CompactListing {
fn make_entry_string(
&self,
- e: &Envelope,
+ root_envelope: &Envelope,
context: &Context,
+ tags_lck: &BTreeMap<TagHash, String>,
+ from: &[Address],
threads: &Threads,
+ other_subjects: &IndexSet<String>,
+ tags: &IndexSet<TagHash>,
hash: ThreadHash,
) -> EntryStrings {
let thread = threads.thread_ref(hash);
- let mut tags = String::new();
+ let mut tags_string = String::new();
let mut colors: SmallVec<[_; 8]> = SmallVec::new();
let account = &context.accounts[&self.cursor_pos.0];
if account.backend_capabilities.supports_tags {
- let tags_lck = account.collection.tag_index.read().unwrap();
- for t in e.tags().iter() {
+ for t in tags {
if mailbox_settings!(
context[self.cursor_pos.0][&self.cursor_pos.1]
.tags
@@ -867,9 +927,9 @@ impl CompactListing {
{
continue;
}
- tags.push(' ');
- tags.push_str(tags_lck.get(t).as_ref().unwrap());
- tags.push(' ');
+ tags_string.push(' ');
+ tags_string.push_str(tags_lck.get(t).as_ref().unwrap());
+ tags_string.push(' ');
colors.push(
mailbox_settings!(context[self.cursor_pos.0][&self.cursor_pos.1].tags.colors)
.get(t)
@@ -882,22 +942,44 @@ impl CompactListing {
}),
);
}
- if !tags.is_empty() {
- tags.pop();
+ if !tags_string.is_empty() {
+ tags_string.pop();
}
}
- let mut subject = e.subject().to_string();
+ let mut subject = if *mailbox_settings!(
+ context[self.cursor_pos.0][&self.cursor_pos.1]
+ .listing
+ .thread_subject_pack
+ ) {
+ other_subjects
+ .into_iter()
+ .fold(String::new(), |mut acc, s| {
+ if !acc.is_empty() {
+ acc.push_str(", ");
+ }
+ acc.push_str(s);
+ acc
+ })
+ } else {
+ root_envelope.subject().to_string()
+ };
subject.truncate_at_boundary(150);
EntryStrings {
date: DateString(ConversationsListing::format_date(context, thread.date())),
subject: if thread.len() > 1 {
- SubjectString(format!("{} ({})", subject, thread.len(),))
+ SubjectString(format!("{} ({})", subject, thread.len()))
} else {
SubjectString(subject)
},
flag: FlagString(format!(
"{selected}{snoozed}{unseen}{attachments}{whitespace}",
- selected = if self.rows.selection.get(&e.hash()).cloned().unwrap_or(false) {
+ selected = if self
+ .rows
+ .selection
+ .get(&root_envelope.hash())
+ .cloned()
+ .unwrap_or(false)
+ {
mailbox_settings!(
context[self.cursor_pos.0][&self.cursor_pos.1]
.listing
@@ -945,7 +1027,12 @@ impl CompactListing {
} else {
""
},
- whitespace = if self.rows.selection.get(&e.hash()).cloned().unwrap_or(false)
+ whitespace = if self
+ .rows
+ .selection
+ .get(&root_envelope.hash())
+ .cloned()
+ .unwrap_or(false)
|| thread.unseen() > 0
|| thread.snoozed()
|| thread.has_attachments()
@@ -955,8 +1042,8 @@ impl CompactListing {
""
},
)),
- from: FromString(address_list!((e.from()) as comma_sep_list)),
- tags: TagString(tags, colors),
+ from: FromString(address_list!((from) as comma_sep_list)),
+ tags: TagString(tags_string, colors),
}
}
@@ -981,6 +1068,7 @@ impl CompactListing {
* arrive */
return;
}
+ let tags_lck = account.collection.tag_index.read().unwrap();
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
let thread_hash = self.rows.env_to_thread[&env_hash];
let threads = account.collection.get_threads(self.cursor_pos.1);
@@ -994,7 +1082,55 @@ impl CompactListing {
self.rows.is_thread_selected(thread_hash)
);
self.rows.row_attr_cache.insert(idx, row_attr);
- let strings = self.make_entry_string(&envelope, context, &threads, thread_hash);
+
+ let mut other_subjects = IndexSet::new();
+ let mut tags = IndexSet::new();
+ let mut from_address_list = Vec::new();
+ let mut from_address_set: std::collections::HashSet<Vec<u8>> =
+ std::collections::HashSet::new();
+ for (envelope, show_subject) in threads
+ .thread_group_iter(thread_hash)
+ .filter_map(|(_, h)| {
+ threads.thread_nodes()[&h]
+ .message()
+ .map(|env_hash| (env_hash, threads.thread_nodes()[&h].show_subject()))
+ })
+ .map(|(env_hash, show_subject)| {
+ (
+ context.accounts[&self.cursor_pos.0]
+ .collection
+ .get_env(env_hash),
+ show_subject,
+ )
+ })
+ {
+ if show_subject {
+ other_subjects.insert(envelope.subject().to_string());
+ }
+ if account.backend_capabilities.supports_tags {
+ for &t in envelope.tags().iter() {
+ tags.insert(t);
+ }
+ }
+ for addr in envelope.from().iter() {
+ if from_address_set.contains(addr.address_spec_raw()) {
+ continue;
+ }
+ from_address_set.insert(addr.address_spec_raw().to_vec());
+ from_address_list.push(addr.clone());
+ }
+ }
+
+ let strings = self.make_entry_string(
+ &envelope,
+ context,
+ &tags_lck,
+ &from_address_list,
+ &threads,
+ &other_subjects,
+ &tags,
+ thread_hash,
+ );
drop(envelope);
let columns = &mut self.data_columns.columns;
let min_width = (