From 735b44f2860307db1b664de43cea2b8c34a71b15 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Wed, 8 May 2024 20:42:06 +0300 Subject: [PATCH] Add 'highlight_self' theme attribute Signed-off-by: Manos Pitsidianakis --- meli/src/conf/themes.rs | 10 +++++ meli/src/mail/listing.rs | 24 ++++++------ meli/src/mail/listing/compact.rs | 45 ++++++++-------------- meli/src/mail/listing/thread.rs | 64 ++++++++++++++++++++++++++++++-- 4 files changed, 97 insertions(+), 46 deletions(-) diff --git a/meli/src/conf/themes.rs b/meli/src/conf/themes.rs index 27d48984..5abbee6a 100644 --- a/meli/src/conf/themes.rs +++ b/meli/src/conf/themes.rs @@ -321,6 +321,7 @@ const DEFAULT_KEYS: &[&str] = &[ "mail.listing.attachment_flag", "mail.listing.thread_snooze_flag", "mail.listing.tag_default", + "mail.listing.highlight_self", "pager.highlight_search", "pager.highlight_search_current", ]; @@ -1730,6 +1731,15 @@ impl Default for Themes { attrs: Attr::BOLD } ); + add!( + "mail.listing.highlight_self", + light = { + fg: Color::BLUE, + }, + dark = { + fg: Color::BLUE, + } + ); add!("pager.highlight_search", light = { fg: Color::White, bg: Color::Byte(6) /* Teal */, attrs: Attr::BOLD }, dark = { fg: Color::White, bg: Color::Byte(6) /* Teal */, attrs: Attr::BOLD }); add!("pager.highlight_search_current", light = { fg: Color::White, bg: Color::Byte(17) /* NavyBlue */, attrs: Attr::BOLD }, dark = { fg: Color::White, bg: Color::Byte(17) /* NavyBlue */, attrs: Attr::BOLD }); diff --git a/meli/src/mail/listing.rs b/meli/src/mail/listing.rs index 626aaa94..3e84d0e0 100644 --- a/meli/src/mail/listing.rs +++ b/meli/src/mail/listing.rs @@ -268,6 +268,7 @@ pub struct ColorCache { pub even_highlighted_selected: ThemeAttribute, pub odd_highlighted_selected: ThemeAttribute, pub tag_default: ThemeAttribute, + pub highlight_self: ThemeAttribute, // Conversations pub subject: ThemeAttribute, @@ -277,6 +278,12 @@ pub struct ColorCache { impl ColorCache { pub fn new(context: &Context, style: IndexStyle) -> Self { + let default = Self { + theme_default: crate::conf::value(context, "theme_default"), + tag_default: crate::conf::value(context, "mail.listing.tag_default"), + highlight_self: crate::conf::value(context, "mail.listing.highlight_self"), + ..Self::default() + }; let mut ret = match style { IndexStyle::Plain => Self { even: crate::conf::value(context, "mail.listing.plain.even"), @@ -298,9 +305,7 @@ impl ColorCache { "mail.listing.plain.even_highlighted_selected", ), odd_selected: crate::conf::value(context, "mail.listing.plain.odd_selected"), - tag_default: crate::conf::value(context, "mail.listing.tag_default"), - theme_default: crate::conf::value(context, "theme_default"), - ..Self::default() + ..default }, IndexStyle::Threaded => Self { even_unseen: crate::conf::value(context, "mail.listing.plain.even_unseen"), @@ -322,9 +327,7 @@ impl ColorCache { ), even: crate::conf::value(context, "mail.listing.plain.even"), odd: crate::conf::value(context, "mail.listing.plain.odd"), - tag_default: crate::conf::value(context, "mail.listing.tag_default"), - theme_default: crate::conf::value(context, "theme_default"), - ..Self::default() + ..default }, IndexStyle::Compact => Self { even_unseen: crate::conf::value(context, "mail.listing.compact.even_unseen"), @@ -349,12 +352,9 @@ impl ColorCache { ), even: crate::conf::value(context, "mail.listing.compact.even"), odd: crate::conf::value(context, "mail.listing.compact.odd"), - tag_default: crate::conf::value(context, "mail.listing.tag_default"), - theme_default: crate::conf::value(context, "theme_default"), - ..Self::default() + ..default }, IndexStyle::Conversations => Self { - theme_default: crate::conf::value(context, "mail.listing.conversations"), subject: crate::conf::value(context, "mail.listing.conversations.subject"), from: crate::conf::value(context, "mail.listing.conversations.from"), date: crate::conf::value(context, "mail.listing.conversations.date"), @@ -365,13 +365,13 @@ impl ColorCache { context, "mail.listing.conversations.highlighted_selected", ), - tag_default: crate::conf::value(context, "mail.listing.tag_default"), - ..Self::default() + ..default }, }; if !context.settings.terminal.use_color() { ret.highlighted.attrs |= Attr::REVERSE; ret.tag_default.attrs |= Attr::REVERSE; + ret.highlight_self.attrs |= Attr::REVERSE; ret.even_highlighted.attrs |= Attr::REVERSE; ret.odd_highlighted.attrs |= Attr::REVERSE; ret.even_highlighted_selected.attrs |= Attr::REVERSE | Attr::DIM; diff --git a/meli/src/mail/listing/compact.rs b/meli/src/mail/listing/compact.rs index a1f8de81..dec6a662 100644 --- a/meli/src/mail/listing/compact.rs +++ b/meli/src/mail/listing/compact.rs @@ -325,6 +325,12 @@ impl MailListingTrait for CompactListing { .settings .account .make_display_name(); + let should_highlight_self = mailbox_settings!( + context[self.cursor_pos.0][&self.cursor_pos.1] + .listing + .highlight_self + ) + .is_true(); '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(|| { @@ -401,11 +407,7 @@ impl MailListingTrait for CompactListing { } } - highlight_self |= envelope - .to() - .iter() - .chain(envelope.cc().iter()) - .any(|a| a == &my_address); + highlight_self |= should_highlight_self && envelope.recipient_any(&my_address); for addr in envelope.from().iter() { if from_address_set.contains(addr.address_spec_raw()) { continue; @@ -414,15 +416,6 @@ impl MailListingTrait for CompactListing { from_address_list.push(addr.clone()); } } - if !mailbox_settings!( - context[self.cursor_pos.0][&self.cursor_pos.1] - .listing - .highlight_self - ) - .is_true() - { - highlight_self = false; - } let row_attr = row_attr!( self.color_cache, @@ -1033,6 +1026,12 @@ impl CompactListing { let mut from_address_set: std::collections::HashSet> = std::collections::HashSet::new(); let mut highlight_self: bool = false; + let should_highlight_self = mailbox_settings!( + context[self.cursor_pos.0][&self.cursor_pos.1] + .listing + .highlight_self + ) + .is_true(); let my_address: Address = context.accounts[&self.cursor_pos.0] .settings .account @@ -1061,11 +1060,7 @@ impl CompactListing { tags.insert(t); } } - highlight_self |= envelope - .to() - .iter() - .chain(envelope.cc().iter()) - .any(|a| a == &my_address); + highlight_self |= should_highlight_self && envelope.recipient_any(&my_address); for addr in envelope.from().iter() { if from_address_set.contains(addr.address_spec_raw()) { continue; @@ -1074,15 +1069,6 @@ impl CompactListing { from_address_list.push(addr.clone()); } } - if !mailbox_settings!( - context[self.cursor_pos.0][&self.cursor_pos.1] - .listing - .highlight_self - ) - .is_true() - { - highlight_self = false; - } let strings = self.make_entry_string( &envelope, @@ -1372,7 +1358,6 @@ impl CompactListing { let x = { let mut area = columns[3].area().nth_row(idx).skip_cols(x); if strings.highlight_self { - // [ref:hardcoded_color_value]: add highlight_self theme attr let x = columns[3] .grid_mut() .write_string( @@ -1384,7 +1369,7 @@ impl CompactListing { .as_ref() .map(|s| s.as_str()) .unwrap_or(super::DEFAULT_HIGHLIGHT_SELF_FLAG), - Color::BLUE, + self.color_cache.highlight_self.fg, row_attr.bg, row_attr.attrs | Attr::FORCE_TEXT, area, diff --git a/meli/src/mail/listing/thread.rs b/meli/src/mail/listing/thread.rs index dcd9feb6..b33eaf04 100644 --- a/meli/src/mail/listing/thread.rs +++ b/meli/src/mail/listing/thread.rs @@ -300,6 +300,16 @@ impl MailListingTrait for ThreadListing { .listing .threaded_repeat_identical_from_values ); + let should_highlight_self = mailbox_settings!( + context[self.cursor_pos.0][&self.cursor_pos.1] + .listing + .highlight_self + ) + .is_true(); + let my_address: Address = context.accounts[&self.cursor_pos.0] + .settings + .account + .make_display_name(); while let Some((indentation, thread_node_hash, has_sibling)) = iter.next() { let thread_node = &thread_nodes[&thread_node_hash]; @@ -321,6 +331,8 @@ impl MailListingTrait for ThreadListing { prev_group = threads.find_group(thread_node.group); let mut entry_strings = self.make_entry_string(&envelope, context); + entry_strings.highlight_self = + should_highlight_self && envelope.recipient_any(&my_address); entry_strings.subject = SubjectString(Self::make_thread_entry( &envelope, indentation, @@ -516,6 +528,8 @@ impl ListingTrait for ThreadListing { let page_no = (self.new_cursor_pos.2).wrapping_div(rows); let top_idx = page_no * rows; + let end_idx = self.length.saturating_sub(1).min(top_idx + rows - 1); + self.draw_rows(context, top_idx, end_idx); // If cursor position has changed, remove the highlight from the previous // position and apply it in the new one. @@ -993,7 +1007,36 @@ impl ThreadListing { } } { - let area = self.data_columns.columns[4].area(); + let mut area = self.data_columns.columns[4].area(); + if strings.highlight_self { + let x = self.data_columns.columns[4] + .grid_mut() + .write_string( + mailbox_settings!( + context[self.cursor_pos.0][&self.cursor_pos.1] + .listing + .highlight_self_flag + ) + .as_ref() + .map(|s| s.as_str()) + .unwrap_or(super::DEFAULT_HIGHLIGHT_SELF_FLAG), + self.color_cache.highlight_self.fg, + row_attr.bg, + row_attr.attrs | Attr::FORCE_TEXT, + area, + None, + ) + .0; + for row in self.data_columns.columns[4] + .grid() + .bounds_iter(area.nth_row(0).take_cols(x)) + { + for c in row { + self.data_columns.columns[4].grid_mut()[c].set_keep_fg(true); + } + } + area = area.skip_cols(x + 1); + } let (x, _) = self.data_columns.columns[4].grid_mut().write_string( &strings.subject, row_attr.fg, @@ -1081,11 +1124,24 @@ impl ThreadListing { ); self.seen_cache.insert(env_hash, envelope.is_seen()); - let mut strings = self.make_entry_string(&envelope, context); + let should_highlight_self = mailbox_settings!( + context[self.cursor_pos.0][&self.cursor_pos.1] + .listing + .highlight_self + ) + .is_true(); + let mut entry_strings = self.make_entry_string(&envelope, context); + entry_strings.highlight_self = should_highlight_self && { + let my_address: Address = context.accounts[&self.cursor_pos.0] + .settings + .account + .make_display_name(); + envelope.recipient_any(&my_address) + }; drop(envelope); std::mem::swap( &mut self.rows.entries.get_mut(idx).unwrap().1.subject, - &mut strings.subject, + &mut entry_strings.subject, ); let columns = &mut self.data_columns.columns; for n in 0..=4 { @@ -1093,7 +1149,7 @@ impl ThreadListing { columns[n].grid_mut().clear_area(area, row_attr); } - *self.rows.entries.get_mut(idx).unwrap() = ((thread_hash, env_hash), strings); + *self.rows.entries.get_mut(idx).unwrap() = ((thread_hash, env_hash), entry_strings); } fn draw_relative_numbers(&mut self, grid: &mut CellBuffer, area: Area, top_idx: usize) {