diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2019-12-01 22:28:50 +0200 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2019-12-07 20:47:59 +0200 |
commit | f632bc4c08b7a9d4630b34c446863f2126716316 (patch) | |
tree | af2b5b1ef46c55b5b25aee039d172cc12a439383 /ui/src/components | |
parent | c6f1fa9be03616a66d3fadc1fdd439125c0b4702 (diff) |
ui: update rows on TagAdd/TagRemove
Except for threadlisting
Diffstat (limited to 'ui/src/components')
-rw-r--r-- | ui/src/components/mail/listing.rs | 15 | ||||
-rw-r--r-- | ui/src/components/mail/listing/compact.rs | 289 | ||||
-rw-r--r-- | ui/src/components/mail/listing/conversations.rs | 257 | ||||
-rw-r--r-- | ui/src/components/mail/listing/plain.rs | 43 | ||||
-rw-r--r-- | ui/src/components/mail/listing/thread.rs | 4 |
5 files changed, 428 insertions, 180 deletions
diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs index cd1d5f64..ad53231a 100644 --- a/ui/src/components/mail/listing.rs +++ b/ui/src/components/mail/listing.rs @@ -92,7 +92,6 @@ pub trait MailListingTrait: ListingTrait { StatusEvent::DisplayMessage(e.to_string()), )); } - self.row_updates().push(thread_hash); } ListingAction::SetUnseen => { if let Err(e) = envelope.set_unseen(op) { @@ -153,8 +152,7 @@ pub trait MailListingTrait: ListingTrait { } fn row_updates(&mut self) -> &mut StackVec<ThreadHash>; - - fn update_line(&mut self, context: &Context, thread_hash: ThreadHash); + fn get_focused_items(&self, _context: &Context) -> StackVec<ThreadHash>; } pub trait ListingTrait: Component { @@ -508,6 +506,17 @@ impl Component for Listing { self.component.set_style(IndexStyle::Conversations); return true; } + Action::Listing(a @ ListingAction::SetSeen) + | Action::Listing(a @ ListingAction::SetUnseen) + | Action::Listing(a @ ListingAction::Delete) + | Action::Listing(a @ ListingAction::Tag(_)) => { + let focused = self.component.get_focused_items(context); + for i in focused { + self.component.perform_action(context, i, a); + } + self.component.set_dirty(); + return true; + } _ => {} }, UIEvent::RefreshMailbox((idxa, folder_hash)) => { diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs index 15a86a0a..c9f24c1d 100644 --- a/ui/src/components/mail/listing/compact.rs +++ b/ui/src/components/mail/listing/compact.rs @@ -79,68 +79,23 @@ impl MailListingTrait for CompactListing { &mut self.row_updates } - fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) { - let account = &context.accounts[self.cursor_pos.0]; - let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); - let threads = &account.collection.threads[&folder_hash]; - if let Some(env_hash) = threads[&thread_hash].message() { - if !account.contains_key(env_hash) { - /* The envelope has been renamed or removed, so wait for the appropriate event to - * arrive */ - return; - } - let envelope: EnvelopeRef = account.collection.get_env(env_hash); - let has_attachments = envelope.has_attachments(); - drop(envelope); - let fg_color = if threads[&thread_hash].has_unseen() { - Color::Byte(0) - } else { - Color::Default - }; - let idx = self.order[&thread_hash]; - let bg_color = if context.settings.terminal.theme == "light" { - if threads[&thread_hash].has_unseen() { - Color::Byte(251) - } else if idx % 2 == 0 { - Color::Byte(252) - } else { - Color::Default - } - } else { - if threads[&thread_hash].has_unseen() { - Color::Byte(253) - } else if idx % 2 == 0 { - Color::Byte(236) - } else { - Color::Default - } - }; - for i in 0..self.data_columns.columns.len() { - let column_width = self.data_columns.columns[i].size().0; - if column_width == 0 { - continue; - } - change_colors( - &mut self.data_columns.columns[i], - ((0, idx), (column_width - 1, idx)), - fg_color, - bg_color, - ); - } - match (threads.is_snoozed(thread_hash), has_attachments) { - (true, true) => { - self.data_columns.columns[3][(0, idx)].set_fg(Color::Byte(103)); - self.data_columns.columns[3][(2, idx)].set_fg(Color::Red); - } - (true, false) => { - self.data_columns.columns[3][(0, idx)].set_fg(Color::Red); - } - (false, true) => { - self.data_columns.columns[3][(0, idx)].set_fg(Color::Byte(103)); - } - (false, false) => {} - } - } + fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> { + let is_selection_empty = self.selection.values().cloned().any(std::convert::identity); + let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)]; + let cursor_iter; + let sel_iter = if is_selection_empty { + cursor_iter = None; + Some(self.selection.iter().filter(|(_, v)| **v).map(|(k, _)| k)) + } else { + cursor_iter = Some(i.iter()); + None + }; + let iter = sel_iter + .into_iter() + .flatten() + .chain(cursor_iter.into_iter().flatten()) + .cloned(); + StackVec::from_iter(iter.into_iter()) } } @@ -564,7 +519,7 @@ impl CompactListing { } fn make_entry_string( &self, - e: EnvelopeRef, + e: &Envelope, context: &Context, thread_node: &ThreadNode, is_snoozed: bool, @@ -592,10 +547,16 @@ impl CompactListing { tags.push(' '); tags.push_str(tags_lck.get(t).as_ref().unwrap()); tags.push(' '); - if let Some(&c) = context.settings.tags.colors.get(t) { + if let Some(&c) = folder + .conf_override + .tags + .as_ref() + .map(|s| s.colors.get(t)) + .unwrap_or(None) + { colors.push(c); } else { - colors.push(8); + colors.push(Color::Byte(8)); } } if !tags.is_empty() { @@ -732,7 +693,7 @@ impl CompactListing { context.accounts[self.cursor_pos.0].collection.get_env(i); let entry_strings = self.make_entry_string( - root_envelope, + &root_envelope, context, thread_node, threads.is_snoozed(root_idx), @@ -885,14 +846,14 @@ impl CompactListing { t, &mut self.data_columns.columns[4], Color::White, - Color::Byte(color), + color, Attr::Bold, ((x + 1, idx), (min_width.4, idx)), None, ); - self.data_columns.columns[4][(x, idx)].set_bg(Color::Byte(color)); + self.data_columns.columns[4][(x, idx)].set_bg(color); if _x < min_width.4 { - self.data_columns.columns[4][(_x, idx)].set_bg(Color::Byte(color)); + self.data_columns.columns[4][(_x, idx)].set_bg(color); self.data_columns.columns[4][(_x, idx)].set_keep_bg(true); } for x in (x + 1).._x { @@ -905,6 +866,7 @@ impl CompactListing { x }; for x in x..min_width.4 { + self.data_columns.columns[4][(x, idx)].set_ch(' '); self.data_columns.columns[4][(x, idx)].set_bg(bg_color); } match ( @@ -958,6 +920,163 @@ impl CompactListing { self.filtered_selection[cursor] } } + + fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) { + let account = &context.accounts[self.cursor_pos.0]; + let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); + let threads = &account.collection.threads[&folder_hash]; + if let Some(env_hash) = threads[&thread_hash].message() { + if !account.contains_key(env_hash) { + /* The envelope has been renamed or removed, so wait for the appropriate event to + * arrive */ + return; + } + let envelope: EnvelopeRef = account.collection.get_env(env_hash); + let has_attachments = envelope.has_attachments(); + let fg_color = if threads[&thread_hash].has_unseen() { + Color::Byte(0) + } else { + Color::Default + }; + let idx = self.order[&thread_hash]; + let bg_color = if context.settings.terminal.theme == "light" { + if threads[&thread_hash].has_unseen() { + Color::Byte(251) + } else if idx % 2 == 0 { + Color::Byte(252) + } else { + Color::Default + } + } else { + if threads[&thread_hash].has_unseen() { + Color::Byte(253) + } else if idx % 2 == 0 { + Color::Byte(236) + } else { + Color::Default + } + }; + let strings = self.make_entry_string( + &envelope, + context, + &threads[&thread_hash], + threads.is_snoozed(thread_hash), + ); + drop(envelope); + let columns = &mut self.data_columns.columns; + let min_width = ( + columns[0].size().0, + columns[1].size().0, + columns[2].size().0, + columns[3].size().0, + columns[4].size().0, + ); + let (x, _) = write_string_to_grid( + &idx.to_string(), + &mut columns[0], + fg_color, + bg_color, + Attr::Default, + ((0, idx), (min_width.0, idx)), + None, + ); + for c in columns[0].row_iter((x, min_width.0.saturating_sub(1)), idx) { + columns[0][c].set_bg(bg_color); + } + let (x, _) = write_string_to_grid( + &strings.date, + &mut columns[1], + fg_color, + bg_color, + Attr::Default, + ((0, idx), (min_width.1.saturating_sub(1), idx)), + None, + ); + for c in columns[1].row_iter((x, min_width.1.saturating_sub(1)), idx) { + columns[1][c].set_bg(bg_color); + } + let (x, _) = write_string_to_grid( + &strings.from, + &mut columns[2], + fg_color, + bg_color, + Attr::Default, + ((0, idx), (min_width.2, idx)), + None, + ); + for c in columns[2].row_iter((x, min_width.2.saturating_sub(1)), idx) { + columns[2][c].set_bg(bg_color); + } + let (x, _) = write_string_to_grid( + &strings.flag, + &mut columns[3], + fg_color, + bg_color, + Attr::Default, + ((0, idx), (min_width.3, idx)), + None, + ); + for c in columns[3].row_iter((x, min_width.3.saturating_sub(1)), idx) { + columns[3][c].set_bg(bg_color); + } + let (x, _) = write_string_to_grid( + &strings.subject, + &mut columns[4], + fg_color, + bg_color, + Attr::Default, + ((0, idx), (min_width.4, idx)), + None, + ); + let x = { + let mut x = x + 1; + for (t, &color) in strings.tags.split_whitespace().zip(strings.tags.1.iter()) { + let (_x, _) = write_string_to_grid( + t, + &mut columns[4], + Color::White, + color, + Attr::Bold, + ((x + 1, idx), (min_width.4, idx)), + None, + ); + for c in columns[4].row_iter((x, x), idx) { + columns[4][c].set_bg(color); + } + for c in columns[4].row_iter((_x, _x), idx) { + columns[4][c].set_bg(color); + columns[4][c].set_keep_bg(true); + } + for c in columns[4].row_iter((x + 1, _x), idx) { + columns[4][c].set_keep_fg(true); + columns[4][c].set_keep_bg(true); + } + for c in columns[4].row_iter((x, x), idx) { + columns[4][c].set_keep_bg(true); + } + x = _x + 1; + } + x + }; + for c in columns[4].row_iter((x, min_width.4.saturating_sub(1)), idx) { + columns[4][c].set_ch(' '); + columns[4][c].set_bg(bg_color); + } + match (threads.is_snoozed(thread_hash), has_attachments) { + (true, true) => { + columns[3][(0, idx)].set_fg(Color::Byte(103)); + columns[3][(2, idx)].set_fg(Color::Red); + } + (true, false) => { + columns[3][(0, idx)].set_fg(Color::Red); + } + (false, true) => { + columns[3][(0, idx)].set_fg(Color::Byte(103)); + } + (false, false) => {} + } + } + } } impl Component for CompactListing { @@ -1132,38 +1251,6 @@ impl Component for CompactListing { self.refresh_mailbox(context); return true; } - Action::Listing(a @ ListingAction::SetSeen) - | Action::Listing(a @ ListingAction::SetUnseen) - | Action::Listing(a @ ListingAction::Delete) - | Action::Listing(a @ ListingAction::Tag(_)) - if !self.unfocused => - { - let is_selection_empty = - self.selection.values().cloned().any(std::convert::identity); - let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)]; - let cursor_iter; - let sel_iter = if is_selection_empty { - cursor_iter = None; - Some(self.selection.iter().filter(|(_, v)| **v).map(|(k, _)| k)) - } else { - cursor_iter = Some(i.iter()); - None - }; - let iter = sel_iter - .into_iter() - .flatten() - .chain(cursor_iter.into_iter().flatten()) - .cloned(); - let stack = StackVec::from_iter(iter.into_iter()); - for i in stack { - self.perform_action(context, i, a); - } - self.dirty = true; - for v in self.selection.values_mut() { - *v = false; - } - return true; - } _ => {} }, diff --git a/ui/src/components/mail/listing/conversations.rs b/ui/src/components/mail/listing/conversations.rs index 7de6631e..b8019871 100644 --- a/ui/src/components/mail/listing/conversations.rs +++ b/ui/src/components/mail/listing/conversations.rs @@ -73,7 +73,7 @@ column_str!(struct DateString(String)); column_str!(struct FromString(String)); column_str!(struct SubjectString(String)); column_str!(struct FlagString(String)); -column_str!(struct TagString(String, StackVec<u8>)); +column_str!(struct TagString(String, StackVec<Color>)); /// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a /// `ThreadView`. @@ -111,43 +111,26 @@ impl MailListingTrait for ConversationsListing { &mut self.row_updates } - fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) { - let account = &context.accounts[self.cursor_pos.0]; - let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); - let threads = &account.collection.threads[&folder_hash]; - let thread_node = &threads.thread_nodes[&thread_hash]; - let row: usize = self.order[&thread_hash]; - let width = self.content.size().0; - - let fg_color = if thread_node.has_unseen() { - Color::Byte(0) + fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> { + let is_selection_empty = self.selection.values().cloned().any(std::convert::identity); + let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)]; + let cursor_iter; + let sel_iter = if is_selection_empty { + cursor_iter = None; + Some(self.selection.iter().filter(|(_, v)| **v).map(|(k, _)| k)) } else { - Color::Default - }; - let bg_color = if thread_node.has_unseen() { - Color::Byte(251) - } else { - Color::Default + cursor_iter = Some(i.iter()); + None }; - change_colors( - &mut self.content, - ((0, 3 * row), (width - 1, 3 * row + 1)), - fg_color, - bg_color, - ); - let padding_fg = if context.settings.terminal.theme == "light" { - Color::Byte(254) - } else { - Color::Byte(235) - }; - change_colors( - &mut self.content, - ((0, 3 * row + 2), (width - 1, 3 * row + 2)), - padding_fg, - bg_color, - ); + let iter = sel_iter + .into_iter() + .flatten() + .chain(cursor_iter.into_iter().flatten()) + .cloned(); + StackVec::from_iter(iter.into_iter()) } } + impl ListingTrait for ConversationsListing { fn coordinates(&self) -> (usize, usize) { (self.new_cursor_pos.0, self.new_cursor_pos.1) @@ -559,10 +542,16 @@ impl ConversationsListing { tags.push(' '); tags.push_str(tags_lck.get(t).as_ref().unwrap()); tags.push(' '); - if let Some(&c) = context.settings.tags.colors.get(t) { + if let Some(&c) = folder + .conf_override + .tags + .as_ref() + .map(|s| s.colors.get(t)) + .unwrap_or(None) + { colors.push(c); } else { - colors.push(8); + colors.push(Color::Byte(8)); } } if !tags.is_empty() { @@ -830,14 +819,14 @@ impl ConversationsListing { t, &mut self.content, Color::White, - Color::Byte(color), + color, Attr::Bold, ((x + 1, 3 * idx), (width - 1, 3 * idx)), None, ); - self.content[(x, 3 * idx)].set_bg(Color::Byte(color)); + self.content[(x, 3 * idx)].set_bg(color); if _x < width { - self.content[(_x, 3 * idx)].set_bg(Color::Byte(color)); + self.content[(_x, 3 * idx)].set_bg(color); self.content[(_x, 3 * idx)].set_keep_bg(true); } for x in (x + 1).._x { @@ -848,6 +837,7 @@ impl ConversationsListing { x = _x + 1; } for x in x..width { + self.content[(x, 3 * idx)].set_ch(' '); self.content[(x, 3 * idx)].set_bg(bg_color); } /* Next line, draw date */ @@ -940,6 +930,164 @@ impl ConversationsListing { self.filtered_selection[cursor] } } + + fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) { + let account = &context.accounts[self.cursor_pos.0]; + let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); + let threads = &account.collection.threads[&folder_hash]; + let thread_node = &threads.thread_nodes[&thread_hash]; + let idx: usize = self.order[&thread_hash]; + let width = self.content.size().0; + + let fg_color = if thread_node.has_unseen() { + Color::Byte(0) + } else { + Color::Default + }; + let bg_color = if thread_node.has_unseen() { + Color::Byte(251) + } else { + Color::Default + }; + let padding_fg = if context.settings.terminal.theme == "light" { + Color::Byte(254) + } else { + Color::Byte(235) + }; + let mut from_address_list = Vec::new(); + let mut from_address_set: std::collections::HashSet<Vec<u8>> = + std::collections::HashSet::new(); + let mut stack = StackVec::new(); + stack.push(thread_hash); + while let Some(h) = stack.pop() { + let env_hash = if let Some(h) = threads.thread_nodes()[&h].message() { + h + } else { + break; + }; + + let envelope: &EnvelopeRef = &context.accounts[self.cursor_pos.0] + .collection + .get_env(env_hash); + for addr in envelope.from().iter() { + if from_address_set.contains(addr.raw()) { + continue; + } + from_address_set.insert(addr.raw().to_vec()); + from_address_list.push(addr.clone()); + } + for c in threads.thread_nodes()[&h].children() { + stack.push(*c); + } + } + let env_hash = threads[&thread_hash].message().unwrap(); + let envelope: EnvelopeRef = account.collection.get_env(env_hash); + let strings = self.make_entry_string( + &envelope, + context, + &from_address_list, + &threads[&thread_hash], + threads.is_snoozed(thread_hash), + ); + drop(envelope); + /* draw flags */ + let (x, _) = write_string_to_grid( + &strings.flag, + &mut self.content, + fg_color, + bg_color, + Attr::Default, + ((0, 3 * idx), (width - 1, 3 * idx)), + None, + ); + for c in self.content.row_iter((x, x + 3), 3 * idx) { + self.content[c].set_bg(bg_color); + } + /* draw subject */ + let (x, _) = write_string_to_grid( + &strings.subject, + &mut self.content, + fg_color, + bg_color, + Attr::Bold, + ((x, 3 * idx), (width - 1, 3 * idx)), + None, + ); + let x = { + let mut x = x + 1; + for (t, &color) in strings.tags.split_whitespace().zip(strings.tags.1.iter()) { + let (_x, _) = write_string_to_grid( + t, + &mut self.content, + Color::White, + color, + Attr::Bold, + ((x + 1, 3 * idx), (width - 1, 3 * idx)), + None, + ); + for c in self.content.row_iter((x, x), 3 * idx) { + self.content[c].set_bg(color); + } + for c in self.content.row_iter((_x, _x), 3 * idx) { + self.content[c].set_bg(color); + self.content[c].set_keep_bg(true); + } + for c in self.content.row_iter((x + 1, _x), 3 * idx) { + self.content[c].set_keep_fg(true); + self.content[c].set_keep_bg(true); + } + for c in self.content.row_iter((x, x), 3 * idx) { + self.content[c].set_keep_bg(true); + } + x = _x + 1; + } + x + }; + for c in self.content.row_iter((x, width.saturating_sub(1)), 3 * idx) { + self.content[c].set_ch(' '); + self.content[c].set_bg(bg_color); + } + /* Next line, draw date */ + let (x, _) = write_string_to_grid( + &strings.date, + &mut self.content, + fg_color, + bg_color, + Attr::Default, + ((0, 3 * idx + 1), (width - 1, 3 * idx + 1)), + None, + ); + for c in self.content.row_iter((x, x + 4), 3 * idx + 1) { + self.content[c].set_ch('▁'); + self.content[c].set_bg(bg_color); + } + /* draw from */ + let (x, _) = write_string_to_grid( + &strings.from, + &mut self.content, + fg_color, + bg_color, + Attr::Default, + ((x + 4, 3 * idx + 1), (width - 1, 3 * idx + 1)), + None, + ); + + for c in self + .content + .row_iter((x, width.saturating_sub(1)), 3 * idx + 1) + { + self.content[c].set_ch('▁'); + self.content[c].set_bg(bg_color); + } + for c in self + .content + .row_iter((0, width.saturating_sub(1)), 3 * idx + 2) + { + self.content[c].set_ch('▓'); + self.content[c].set_fg(padding_fg); + self.content[c].set_bg(bg_color); + } + } } impl Component for ConversationsListing { @@ -1191,37 +1339,6 @@ impl Component for ConversationsListing { self.refresh_mailbox(context); return true; } - Action::Listing(a @ ListingAction::SetSeen) - | Action::Listing(a @ ListingAction::SetUnseen) - | Action::Listing(a @ ListingAction::Delete) - if !self.unfocused => - { - let is_selection_empty = - self.selection.values().cloned().any(std::convert::identity); - let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)]; - let cursor_iter; - let sel_iter = if is_selection_empty { - cursor_iter = None; - Some(self.selection.iter().filter(|(_, v)| **v).map(|(k, _)| k)) - } else { - cursor_iter = Some(i.iter()); - None - }; - let iter = sel_iter - .into_iter() - .flatten() - .chain(cursor_iter.into_iter().flatten()) - .cloned(); - let stack = StackVec::from_iter(iter.into_iter()); - for i in stack { - self.perform_action(context, i, a); - } - self.dirty = true; - for v in self.selection.values_mut() { - *v = false; - } - return true; - } _ => {} }, _ => {} diff --git a/ui/src/components/mail/listing/plain.rs b/ui/src/components/mail/listing/plain.rs index eb79c350..28f83284 100644 --- a/ui/src/components/mail/listing/plain.rs +++ b/ui/src/components/mail/listing/plain.rs @@ -62,6 +62,7 @@ pub struct PlainListing { filtered_selection: Vec<EnvelopeHash>, filtered_order: FnvHashMap<EnvelopeHash, usize>, selection: FnvHashMap<EnvelopeHash, bool>, + thread_hashes: FnvHashMap<EnvelopeHash, ThreadHash>, local_collection: Vec<EnvelopeHash>, /// If we must redraw on next redraw event dirty: bool, @@ -81,7 +82,20 @@ impl MailListingTrait for PlainListing { &mut self._row_updates } - fn update_line(&mut self, _context: &Context, _thread_hash: ThreadHash) {} + fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> { + let is_selection_empty = self.selection.values().cloned().any(std::convert::identity); + if is_selection_empty { + self.selection + .iter() + .filter(|(_, v)| **v) + .map(|(k, _)| self.thread_hashes[k]) + .collect() + } else { + let mut ret = StackVec::new(); + ret.push(self.get_thread_under_cursor(self.cursor_pos.2, context)); + ret + } + } } impl ListingTrait for PlainListing { @@ -470,6 +484,7 @@ impl PlainListing { subsort: (SortField::Date, SortOrder::Desc), all_envelopes: fnv::FnvHashSet::default(), local_collection: Vec::new(), + thread_hashes: FnvHashMap::default(), order: FnvHashMap::default(), filter_term: String::new(), filtered_selection: Vec::new(), @@ -520,7 +535,7 @@ impl PlainListing { { colors.push(c); } else { - colors.push(8); + colors.push(Color::Byte(8)); } } if !tags.is_empty() { @@ -587,6 +602,18 @@ impl PlainListing { .iter() .cloned() .collect(); + let env_lck = context.accounts[self.cursor_pos.0] + .collection + .envelopes + .read() + .unwrap(); + self.thread_hashes = context.accounts[self.cursor_pos.0][folder_hash] + .unwrap() + .envelopes + .iter() + .map(|h| (*h, env_lck[h].thread())) + .collect(); + drop(env_lck); self.redraw_list(context); if self.length > 0 { @@ -803,16 +830,16 @@ impl PlainListing { t, &mut columns[4], Color::White, - Color::Byte(color), + color, Attr::Bold, ((x + 1, idx), (min_width.4, idx)), None, ); for c in columns[4].row_iter((x, x), idx) { - columns[4][c].set_bg(Color::Byte(color)); + columns[4][c].set_bg(color); } for c in columns[4].row_iter((_x, _x), idx) { - columns[4][c].set_bg(Color::Byte(color)); + columns[4][c].set_bg(color); columns[4][c].set_keep_bg(true); } for c in columns[4].row_iter((x + 1, _x), idx) { @@ -866,6 +893,12 @@ impl PlainListing { } } + fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash { + let account = &context.accounts[self.cursor_pos.0]; + let env_hash = self.get_env_under_cursor(cursor, context); + account.collection.get_env(env_hash).thread() + } + fn format_date(envelope: &Envelope) -> String { let d = std::time::UNIX_EPOCH + std::time::Duration::from_secs(envelope.date()); let now: std::time::Duration = std::time::SystemTime::now() diff --git a/ui/src/components/mail/listing/thread.rs b/ui/src/components/mail/listing/thread.rs index 5d005e6a..5312c93e 100644 --- a/ui/src/components/mail/listing/thread.rs +++ b/ui/src/components/mail/listing/thread.rs @@ -54,7 +54,9 @@ impl MailListingTrait for ThreadListing { &mut self.row_updates } - fn update_line(&mut self, _context: &Context, _thread_hash: ThreadHash) {} + fn get_focused_items(&self, _context: &Context) -> StackVec<ThreadHash> { + StackVec::new() + } } impl ListingTrait for ThreadListing { |