ui/themes: add theming to ConversationsListing, sidebar
parent
a9842cacee
commit
a1c449e585
|
@ -22,6 +22,7 @@
|
|||
use super::*;
|
||||
use crate::types::segment_tree::SegmentTree;
|
||||
use smallvec::SmallVec;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
mod conversations;
|
||||
pub use self::conversations::*;
|
||||
|
@ -42,6 +43,86 @@ pub struct DataColumns {
|
|||
pub segment_tree: [SegmentTree; 12],
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
/// Save theme colors to avoid looking them up again and again from settings
|
||||
struct ColorCache {
|
||||
unseen_fg: Color,
|
||||
unseen_bg: Color,
|
||||
highlighted_fg: Color,
|
||||
highlighted_bg: Color,
|
||||
even_fg: Color,
|
||||
even_bg: Color,
|
||||
odd_fg: Color,
|
||||
odd_bg: Color,
|
||||
selected_bg: Color,
|
||||
attachment_flag_fg: Color,
|
||||
thread_snooze_flag_fg: Color,
|
||||
|
||||
/* Conversations */
|
||||
fg: Color,
|
||||
bg: Color,
|
||||
subject_fg: Color,
|
||||
subject_bg: Color,
|
||||
from_fg: Color,
|
||||
from_bg: Color,
|
||||
date_fg: Color,
|
||||
date_bg: Color,
|
||||
padding: Color,
|
||||
unseen_padding: Color,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct EntryStrings {
|
||||
pub(super) date: DateString,
|
||||
pub(super) subject: SubjectString,
|
||||
pub(super) flag: FlagString,
|
||||
pub(super) from: FromString,
|
||||
pub(super) tags: TagString,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! address_list {
|
||||
(($name:expr) as comma_sep_list) => {{
|
||||
let mut ret: String =
|
||||
$name
|
||||
.into_iter()
|
||||
.fold(String::new(), |mut s: String, n: &Address| {
|
||||
s.extend(n.to_string().chars());
|
||||
s.push_str(", ");
|
||||
s
|
||||
});
|
||||
ret.pop();
|
||||
ret.pop();
|
||||
ret
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! column_str {
|
||||
(
|
||||
struct $name:ident($($t:ty),+)) => {
|
||||
#[derive(Debug)]
|
||||
pub(super) struct $name($(pub $t),+);
|
||||
|
||||
impl Deref for $name {
|
||||
type Target = String;
|
||||
fn deref(&self) -> &String {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
impl DerefMut for $name {
|
||||
fn deref_mut(&mut self) -> &mut String {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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, SmallVec<[Color; 8]>));
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AccountMenuEntry {
|
||||
name: String,
|
||||
|
@ -976,14 +1057,48 @@ impl Listing {
|
|||
if idx == lines_len {
|
||||
break;
|
||||
}
|
||||
let (fg_color, bg_color) = if must_highlight_account {
|
||||
let (
|
||||
fg_color,
|
||||
bg_color,
|
||||
index_fg_color,
|
||||
index_bg_color,
|
||||
unread_count_fg,
|
||||
unread_count_bg,
|
||||
) = if must_highlight_account {
|
||||
if self.cursor_pos.1 == idx {
|
||||
(Color::Byte(233), Color::Byte(15))
|
||||
(
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_fg"),
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_bg"),
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_index_fg"),
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_index_bg"),
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_unread_count_fg"),
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_unread_count_bg"),
|
||||
)
|
||||
} else {
|
||||
(Color::Byte(15), Color::Byte(233))
|
||||
(
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_account_fg"),
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_account_bg"),
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_account_index_fg"),
|
||||
crate::conf::color(context, "mail.sidebar_highlighted_account_index_bg"),
|
||||
crate::conf::color(
|
||||
context,
|
||||
"mail.sidebar_highlighted_account_unread_count_fg",
|
||||
),
|
||||
crate::conf::color(
|
||||
context,
|
||||
"mail.sidebar_highlighted_account_unread_count_bg",
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
(Color::Default, Color::Default)
|
||||
(
|
||||
crate::conf::color(context, "mail.sidebar_fg"),
|
||||
crate::conf::color(context, "mail.sidebar_bg"),
|
||||
crate::conf::color(context, "mail.sidebar_index_fg"),
|
||||
crate::conf::color(context, "mail.sidebar_index_bg"),
|
||||
crate::conf::color(context, "mail.sidebar_unread_count_fg"),
|
||||
crate::conf::color(context, "mail.sidebar_unread_count_bg"),
|
||||
)
|
||||
};
|
||||
|
||||
let (depth, inc, folder_idx, count) = lines[idx];
|
||||
|
@ -1007,8 +1122,8 @@ impl Listing {
|
|||
let (x, _) = write_string_to_grid(
|
||||
&format!("{:>width$}", inc, width = total_folder_no_digits),
|
||||
grid,
|
||||
Color::Byte(243),
|
||||
bg_color,
|
||||
index_fg_color,
|
||||
index_bg_color,
|
||||
Attr::Default,
|
||||
(set_y(upper_left, y), bottom_right),
|
||||
None,
|
||||
|
@ -1046,8 +1161,8 @@ impl Listing {
|
|||
let (x, _) = write_string_to_grid(
|
||||
&count_string,
|
||||
grid,
|
||||
fg_color,
|
||||
bg_color,
|
||||
unread_count_fg,
|
||||
unread_count_bg,
|
||||
if count.unwrap_or(0) > 0 {
|
||||
Attr::Bold
|
||||
} else {
|
||||
|
|
|
@ -71,6 +71,7 @@ pub struct CompactListing {
|
|||
unfocused: bool,
|
||||
view: ThreadView,
|
||||
row_updates: SmallVec<[ThreadHash; 8]>,
|
||||
color_cache: ColorCache,
|
||||
|
||||
movement: Option<PageMovement>,
|
||||
id: ComponentId,
|
||||
|
@ -126,24 +127,24 @@ impl ListingTrait for CompactListing {
|
|||
let thread = threads.thread_ref(thread_hash);
|
||||
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
crate::conf::color(context, "mail.listing.compact.unseen_fg")
|
||||
self.color_cache.unseen_fg
|
||||
} else if self.cursor_pos.2 == idx {
|
||||
crate::conf::color(context, "mail.listing.compact.highlighted_fg")
|
||||
self.color_cache.highlighted_fg
|
||||
} else if idx % 2 == 0 {
|
||||
crate::conf::color(context, "mail.listing.compact.even_fg")
|
||||
self.color_cache.even_fg
|
||||
} else {
|
||||
crate::conf::color(context, "mail.listing.compact.odd_fg")
|
||||
self.color_cache.odd_fg
|
||||
};
|
||||
let bg_color = if self.cursor_pos.2 == idx {
|
||||
crate::conf::color(context, "mail.listing.compact.highlighted_bg")
|
||||
self.color_cache.highlighted_bg
|
||||
} else if self.selection[&thread_hash] {
|
||||
crate::conf::color(context, "mail.listing.compact.selected_bg")
|
||||
self.color_cache.selected_bg
|
||||
} else if thread.unseen() > 0 {
|
||||
crate::conf::color(context, "mail.listing.compact.unseen_bg")
|
||||
self.color_cache.unseen_bg
|
||||
} else if idx % 2 == 0 {
|
||||
crate::conf::color(context, "mail.listing.compact.even_bg")
|
||||
self.color_cache.even_bg
|
||||
} else {
|
||||
crate::conf::color(context, "mail.listing.compact.odd_bg")
|
||||
self.color_cache.odd_bg
|
||||
};
|
||||
|
||||
let (upper_left, bottom_right) = area;
|
||||
|
@ -340,16 +341,14 @@ impl ListingTrait for CompactListing {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for r in 0..cmp::min(self.length - top_idx, rows) {
|
||||
let (fg_color, bg_color) = {
|
||||
let thread_hash = self.get_thread_under_cursor(r + top_idx, context);
|
||||
|
||||
let c = &self.data_columns.columns[0][(0, r + top_idx)];
|
||||
if self.selection[&thread_hash] {
|
||||
(
|
||||
c.fg(),
|
||||
crate::conf::color(context, "mail.listing.compact.selected_bg"),
|
||||
)
|
||||
(c.fg(), self.color_cache.selected_bg)
|
||||
} else {
|
||||
(c.fg(), c.bg())
|
||||
}
|
||||
|
@ -531,7 +530,7 @@ impl CompactListing {
|
|||
force_draw: true,
|
||||
unfocused: false,
|
||||
view: ThreadView::default(),
|
||||
|
||||
color_cache: ColorCache::default(),
|
||||
movement: None,
|
||||
id: ComponentId::new_v4(),
|
||||
}
|
||||
|
@ -632,6 +631,24 @@ impl CompactListing {
|
|||
return;
|
||||
};
|
||||
|
||||
self.color_cache = ColorCache {
|
||||
unseen_fg: crate::conf::color(context, "mail.listing.compact.unseen_fg"),
|
||||
unseen_bg: crate::conf::color(context, "mail.listing.compact.unseen_bg"),
|
||||
highlighted_fg: crate::conf::color(context, "mail.listing.compact.highlighted_fg"),
|
||||
highlighted_bg: crate::conf::color(context, "mail.listing.compact.highlighted_bg"),
|
||||
even_fg: crate::conf::color(context, "mail.listing.compact.even_fg"),
|
||||
even_bg: crate::conf::color(context, "mail.listing.compact.even_bg"),
|
||||
odd_fg: crate::conf::color(context, "mail.listing.compact.odd_fg"),
|
||||
odd_bg: crate::conf::color(context, "mail.listing.compact.odd_bg"),
|
||||
selected_bg: crate::conf::color(context, "mail.listing.compact.selected_bg"),
|
||||
attachment_flag_fg: crate::conf::color(context, "mail.listing.attachment_flag_fg"),
|
||||
thread_snooze_flag_fg: crate::conf::color(
|
||||
context,
|
||||
"mail.listing.thread_snooze_flag_fg",
|
||||
),
|
||||
..self.color_cache
|
||||
};
|
||||
|
||||
// Get mailbox as a reference.
|
||||
//
|
||||
match context.accounts[self.cursor_pos.0].status(self.folder_hash) {
|
||||
|
@ -804,20 +821,11 @@ impl CompactListing {
|
|||
}
|
||||
let thread = threads.thread_ref(thread);
|
||||
let (fg_color, bg_color) = if thread.unseen() > 0 {
|
||||
(
|
||||
crate::conf::color(context, "mail.listing.compact.unseen_fg"),
|
||||
crate::conf::color(context, "mail.listing.compact.unseen_bg"),
|
||||
)
|
||||
(self.color_cache.unseen_fg, self.color_cache.unseen_bg)
|
||||
} else if idx % 2 == 0 {
|
||||
(
|
||||
crate::conf::color(context, "mail.listing.compact.even_fg"),
|
||||
crate::conf::color(context, "mail.listing.compact.even_bg"),
|
||||
)
|
||||
(self.color_cache.even_fg, self.color_cache.even_bg)
|
||||
} else {
|
||||
(
|
||||
crate::conf::color(context, "mail.listing.compact.odd_fg"),
|
||||
crate::conf::color(context, "mail.listing.compact.odd_bg"),
|
||||
)
|
||||
(self.color_cache.odd_fg, self.color_cache.odd_bg)
|
||||
};
|
||||
let (x, _) = write_string_to_grid(
|
||||
&idx.to_string(),
|
||||
|
@ -908,26 +916,18 @@ impl CompactListing {
|
|||
}
|
||||
match (thread.snoozed(), thread.has_attachments()) {
|
||||
(true, true) => {
|
||||
self.data_columns.columns[3][(0, idx)].set_fg(crate::conf::color(
|
||||
context,
|
||||
"mail.listing.attachment_flag_fg",
|
||||
));
|
||||
self.data_columns.columns[3][(2, idx)].set_fg(crate::conf::color(
|
||||
context,
|
||||
"mail.listing.thread_snooze_flag_fg",
|
||||
));
|
||||
self.data_columns.columns[3][(0, idx)]
|
||||
.set_fg(self.color_cache.attachment_flag_fg);
|
||||
self.data_columns.columns[3][(2, idx)]
|
||||
.set_fg(self.color_cache.thread_snooze_flag_fg);
|
||||
}
|
||||
(true, false) => {
|
||||
self.data_columns.columns[3][(0, idx)].set_fg(crate::conf::color(
|
||||
context,
|
||||
"mail.listing.thread_snooze_flag_fg",
|
||||
));
|
||||
self.data_columns.columns[3][(0, idx)]
|
||||
.set_fg(self.color_cache.thread_snooze_flag_fg);
|
||||
}
|
||||
(false, true) => {
|
||||
self.data_columns.columns[3][(0, idx)].set_fg(crate::conf::color(
|
||||
context,
|
||||
"mail.listing.attachment_flag_fg",
|
||||
));
|
||||
self.data_columns.columns[3][(0, idx)]
|
||||
.set_fg(self.color_cache.attachment_flag_fg);
|
||||
}
|
||||
(false, false) => {}
|
||||
}
|
||||
|
@ -982,20 +982,11 @@ impl CompactListing {
|
|||
}
|
||||
let idx = self.order[&thread_hash];
|
||||
let (fg_color, bg_color) = if thread.unseen() > 0 {
|
||||
(
|
||||
crate::conf::color(context, "mail.listing.compact.unseen_fg"),
|
||||
crate::conf::color(context, "mail.listing.compact.unseen_bg"),
|
||||
)
|
||||
(self.color_cache.unseen_fg, self.color_cache.unseen_bg)
|
||||
} else if idx % 2 == 0 {
|
||||
(
|
||||
crate::conf::color(context, "mail.listing.compact.even_fg"),
|
||||
crate::conf::color(context, "mail.listing.compact.even_bg"),
|
||||
)
|
||||
(self.color_cache.even_fg, self.color_cache.even_bg)
|
||||
} else {
|
||||
(
|
||||
crate::conf::color(context, "mail.listing.compact.odd_fg"),
|
||||
crate::conf::color(context, "mail.listing.compact.odd_bg"),
|
||||
)
|
||||
(self.color_cache.odd_fg, self.color_cache.odd_bg)
|
||||
};
|
||||
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
||||
let strings = self.make_entry_string(&envelope, context, threads, thread_hash);
|
||||
|
@ -1101,26 +1092,14 @@ impl CompactListing {
|
|||
}
|
||||
match (thread.snoozed(), thread.has_attachments()) {
|
||||
(true, true) => {
|
||||
columns[3][(0, idx)].set_fg(crate::conf::color(
|
||||
context,
|
||||
"mail.listing.attachment_flag_fg",
|
||||
));
|
||||
columns[3][(2, idx)].set_fg(crate::conf::color(
|
||||
context,
|
||||
"mail.listing.thread_snooze_flag_fg",
|
||||
));
|
||||
columns[3][(0, idx)].set_fg(self.color_cache.attachment_flag_fg);
|
||||
columns[3][(2, idx)].set_fg(self.color_cache.thread_snooze_flag_fg);
|
||||
}
|
||||
(true, false) => {
|
||||
columns[3][(0, idx)].set_fg(crate::conf::color(
|
||||
context,
|
||||
"mail.listing.thread_snooze_flag_fg",
|
||||
));
|
||||
columns[3][(0, idx)].set_fg(self.color_cache.thread_snooze_flag_fg);
|
||||
}
|
||||
(false, true) => {
|
||||
columns[3][(0, idx)].set_fg(crate::conf::color(
|
||||
context,
|
||||
"mail.listing.attachment_flag_fg",
|
||||
));
|
||||
columns[3][(0, idx)].set_fg(self.color_cache.attachment_flag_fg);
|
||||
}
|
||||
(false, false) => {}
|
||||
}
|
||||
|
|
|
@ -22,58 +22,6 @@
|
|||
use super::*;
|
||||
use crate::components::utilities::PageMovement;
|
||||
use std::iter::FromIterator;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct EntryStrings {
|
||||
pub(super) date: DateString,
|
||||
pub(super) subject: SubjectString,
|
||||
pub(super) flag: FlagString,
|
||||
pub(super) from: FromString,
|
||||
pub(super) tags: TagString,
|
||||
}
|
||||
|
||||
macro_rules! address_list {
|
||||
(($name:expr) as comma_sep_list) => {{
|
||||
let mut ret: String =
|
||||
$name
|
||||
.into_iter()
|
||||
.fold(String::new(), |mut s: String, n: &Address| {
|
||||
s.extend(n.to_string().chars());
|
||||
s.push_str(", ");
|
||||
s
|
||||
});
|
||||
ret.pop();
|
||||
ret.pop();
|
||||
ret
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! column_str {
|
||||
(
|
||||
struct $name:ident($($t:ty),+)) => {
|
||||
#[derive(Debug)]
|
||||
pub(super) struct $name($(pub $t),+);
|
||||
|
||||
impl Deref for $name {
|
||||
type Target = String;
|
||||
fn deref(&self) -> &String {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
impl DerefMut for $name {
|
||||
fn deref_mut(&mut self) -> &mut String {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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, SmallVec<[Color; 8]>));
|
||||
|
||||
/// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a
|
||||
/// `ThreadView`.
|
||||
|
@ -102,6 +50,7 @@ pub struct ConversationsListing {
|
|||
unfocused: bool,
|
||||
view: ThreadView,
|
||||
row_updates: SmallVec<[ThreadHash; 8]>,
|
||||
color_cache: ColorCache,
|
||||
|
||||
movement: Option<PageMovement>,
|
||||
id: ComponentId,
|
||||
|
@ -157,18 +106,18 @@ impl ListingTrait for ConversationsListing {
|
|||
let thread = threads.thread_ref(thread_hash);
|
||||
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
self.color_cache.unseen_fg
|
||||
} else {
|
||||
Color::Default
|
||||
self.color_cache.fg
|
||||
};
|
||||
let bg_color = if self.cursor_pos.2 == idx {
|
||||
Color::Byte(246)
|
||||
self.color_cache.highlighted_bg
|
||||
} else if self.selection[&thread_hash] {
|
||||
Color::Byte(210)
|
||||
self.color_cache.selected_bg
|
||||
} else if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
self.color_cache.unseen_bg
|
||||
} else {
|
||||
Color::Default
|
||||
self.color_cache.bg
|
||||
};
|
||||
|
||||
copy_area(
|
||||
|
@ -178,11 +127,7 @@ impl ListingTrait for ConversationsListing {
|
|||
((0, 3 * idx), pos_dec(self.content.size(), (1, 1))),
|
||||
);
|
||||
|
||||
let padding_fg = if context.settings.terminal.theme == "light" {
|
||||
Color::Byte(254)
|
||||
} else {
|
||||
Color::Byte(235)
|
||||
};
|
||||
let padding_fg = self.color_cache.padding;
|
||||
|
||||
let (upper_left, bottom_right) = area;
|
||||
let width = self.content.size().0;
|
||||
|
@ -347,11 +292,7 @@ impl ListingTrait for ConversationsListing {
|
|||
|
||||
/* fill any remaining columns, if our view is wider than self.content */
|
||||
let width = self.content.size().0;
|
||||
let padding_fg = if context.settings.terminal.theme == "light" {
|
||||
Color::Byte(254)
|
||||
} else {
|
||||
Color::Byte(235)
|
||||
};
|
||||
let padding_fg = self.color_cache.padding;
|
||||
|
||||
if width < width!(area) {
|
||||
let y_offset = get_y(upper_left);
|
||||
|
@ -510,7 +451,7 @@ impl ConversationsListing {
|
|||
force_draw: true,
|
||||
unfocused: false,
|
||||
view: ThreadView::default(),
|
||||
|
||||
color_cache: ColorCache::default(),
|
||||
movement: None,
|
||||
id: ComponentId::new_v4(),
|
||||
}
|
||||
|
@ -612,6 +553,38 @@ impl ConversationsListing {
|
|||
return;
|
||||
};
|
||||
|
||||
self.color_cache = ColorCache {
|
||||
fg: crate::conf::color(context, "mail.listing.conversations.fg"),
|
||||
bg: crate::conf::color(context, "mail.listing.conversations.bg"),
|
||||
subject_fg: crate::conf::color(context, "mail.listing.conversations.subject_fg"),
|
||||
subject_bg: crate::conf::color(context, "mail.listing.conversations.subject_bg"),
|
||||
from_fg: crate::conf::color(context, "mail.listing.conversations.from_fg"),
|
||||
from_bg: crate::conf::color(context, "mail.listing.conversations.from_bg"),
|
||||
date_fg: crate::conf::color(context, "mail.listing.conversations.date_fg"),
|
||||
date_bg: crate::conf::color(context, "mail.listing.conversations.date_bg"),
|
||||
padding: crate::conf::color(context, "mail.listing.conversations.padding"),
|
||||
unseen_fg: crate::conf::color(context, "mail.listing.conversations.unseen_fg"),
|
||||
unseen_bg: crate::conf::color(context, "mail.listing.conversations.unseen_bg"),
|
||||
unseen_padding: crate::conf::color(
|
||||
context,
|
||||
"mail.listing.conversations.unseen_padding",
|
||||
),
|
||||
highlighted_fg: crate::conf::color(
|
||||
context,
|
||||
"mail.listing.conversations.highlighted_fg",
|
||||
),
|
||||
highlighted_bg: crate::conf::color(
|
||||
context,
|
||||
"mail.listing.conversations.highlighted_bg",
|
||||
),
|
||||
attachment_flag_fg: crate::conf::color(context, "mail.listing.attachment_flag_fg"),
|
||||
thread_snooze_flag_fg: crate::conf::color(
|
||||
context,
|
||||
"mail.listing.thread_snooze_flag_fg",
|
||||
),
|
||||
..self.color_cache
|
||||
};
|
||||
|
||||
// Get mailbox as a reference.
|
||||
//
|
||||
match context.accounts[self.cursor_pos.0].status(self.folder_hash) {
|
||||
|
@ -738,11 +711,7 @@ impl ConversationsListing {
|
|||
self.content =
|
||||
CellBuffer::new_with_context(width, 4 * rows.len(), Cell::with_char(' '), context);
|
||||
|
||||
let padding_fg = if context.settings.terminal.theme == "light" {
|
||||
Color::Byte(254)
|
||||
} else {
|
||||
Color::Byte(235)
|
||||
};
|
||||
let padding_fg = self.color_cache.padding;
|
||||
|
||||
for ((idx, (thread, root_env_hash)), strings) in rows {
|
||||
if !context.accounts[self.cursor_pos.0].contains_key(root_env_hash) {
|
||||
|
@ -750,14 +719,14 @@ impl ConversationsListing {
|
|||
}
|
||||
let thread = threads.thread_ref(thread);
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
self.color_cache.unseen_fg
|
||||
} else {
|
||||
Color::Default
|
||||
self.color_cache.fg
|
||||
};
|
||||
let bg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
self.color_cache.unseen_bg
|
||||
} else {
|
||||
Color::Default
|
||||
self.color_cache.bg
|
||||
};
|
||||
/* draw flags */
|
||||
let (x, _) = write_string_to_grid(
|
||||
|
@ -922,20 +891,16 @@ impl ConversationsListing {
|
|||
let env_hash = threads.thread_nodes()[&thread_node_hash].message().unwrap();
|
||||
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
self.color_cache.unseen_fg
|
||||
} else {
|
||||
Color::Default
|
||||
self.color_cache.fg
|
||||
};
|
||||
let bg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
self.color_cache.unseen_bg
|
||||
} else {
|
||||
Color::Default
|
||||
};
|
||||
let padding_fg = if context.settings.terminal.theme == "light" {
|
||||
Color::Byte(254)
|
||||
} else {
|
||||
Color::Byte(235)
|
||||
self.color_cache.bg
|
||||
};
|
||||
let padding_fg = self.color_cache.padding;
|
||||
let mut from_address_list = Vec::new();
|
||||
let mut from_address_set: std::collections::HashSet<Vec<u8>> =
|
||||
std::collections::HashSet::new();
|
||||
|
|
|
@ -352,6 +352,7 @@ impl FileSettings {
|
|||
s.terminal.themes.dark.insert(k, v);
|
||||
}
|
||||
}
|
||||
s.terminal.themes.validate()?;
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
use crate::terminal::Color;
|
||||
use crate::Context;
|
||||
use melib::Result;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
|
@ -54,20 +55,30 @@ const DEFAULT_KEYS: &'static [&'static str] = &[
|
|||
"mail.sidebar_highlighted_unread_count_bg",
|
||||
"mail.sidebar_highlighted_index_fg",
|
||||
"mail.sidebar_highlighted_index_bg",
|
||||
"mail.sidebar_highlighted_account_fg",
|
||||
"mail.sidebar_highlighted_account_bg",
|
||||
"mail.sidebar_highlighted_account_unread_count_fg",
|
||||
"mail.sidebar_highlighted_account_unread_count_bg",
|
||||
"mail.sidebar_highlighted_account_index_fg",
|
||||
"mail.sidebar_highlighted_account_index_bg",
|
||||
"mail.listing.compact.even_fg",
|
||||
"mail.listing.compact.even_bg",
|
||||
"mail.listing.compact.odd_fg",
|
||||
"mail.listing.compact.odd_bg",
|
||||
"mail.listing.compact.unseen_fg",
|
||||
"mail.listing.compact.unseen_fg",
|
||||
"mail.listing.compact.unseen_bg",
|
||||
"mail.listing.compact.selected_fg",
|
||||
"mail.listing.compact.selected_bg",
|
||||
"mail.listing.compact.highlighted_fg",
|
||||
"mail.listing.compact.highlighted_bg",
|
||||
"mail.listing.plain.even_fg",
|
||||
"mail.listing.plain.even_bg",
|
||||
"mail.listing.plain.odd_fg",
|
||||
"mail.listing.plain.odd_bg",
|
||||
"mail.listing.plain.unseen_fg",
|
||||
"mail.listing.plain.unseen_bg",
|
||||
"mail.listing.conversations.fg",
|
||||
"mail.listing.conversations.bg",
|
||||
"mail.listing.conversations.subject_fg",
|
||||
"mail.listing.conversations.subject_bg",
|
||||
"mail.listing.conversations.from_fg",
|
||||
|
@ -78,6 +89,10 @@ const DEFAULT_KEYS: &'static [&'static str] = &[
|
|||
"mail.listing.conversations.unseen_fg",
|
||||
"mail.listing.conversations.unseen_bg",
|
||||
"mail.listing.conversations.unseen_padding",
|
||||
"mail.listing.conversations.highlighted_fg",
|
||||
"mail.listing.conversations.highlighted_bg",
|
||||
"mail.listing.conversations.selected_fg",
|
||||
"mail.listing.conversations.selected_bg",
|
||||
"mail.view.headers_fg",
|
||||
"mail.view.headers_bg",
|
||||
"mail.view.body_fg",
|
||||
|
@ -96,7 +111,7 @@ pub struct Theme {
|
|||
}
|
||||
|
||||
impl Theme {
|
||||
pub fn validate(&self) -> Option<String> {
|
||||
pub fn validate(&self) -> Result<()> {
|
||||
let hash_set: HashSet<&'static str> = DEFAULT_KEYS.into_iter().map(|k| *k).collect();
|
||||
let keys: Vec<&'_ str> = self
|
||||
.light
|
||||
|
@ -111,9 +126,9 @@ impl Theme {
|
|||
})
|
||||
.collect();
|
||||
if keys.is_empty() {
|
||||
None
|
||||
Ok(())
|
||||
} else {
|
||||
Some(format!("Unrecognized theme keywords: {}", keys.join(", ")))
|
||||
Err(format!("Unrecognized theme keywords: {}", keys.join(", ")).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +138,29 @@ impl Default for Theme {
|
|||
let mut light = HashMap::default();
|
||||
let mut dark = HashMap::default();
|
||||
|
||||
macro_rules! add {
|
||||
($key:literal, light=$light:expr, dark=$dark:expr) => {
|
||||
light.insert($key.into(), $light);
|
||||
dark.insert($key.into(), $dark);
|
||||
};
|
||||
($key:literal, dark=$dark:expr, light=$light:expr) => {
|
||||
light.insert($key.into(), $light);
|
||||
dark.insert($key.into(), $dark);
|
||||
};
|
||||
($key:literal, light=$light:expr) => {
|
||||
light.insert($key.into(), $light);
|
||||
dark.insert($key.into(), Color::Default);
|
||||
};
|
||||
($key:literal, dark=$dark:expr) => {
|
||||
light.insert($key.into(), Color::Default);
|
||||
dark.insert($key.into(), $dark);
|
||||
};
|
||||
($key:literal) => {
|
||||
light.insert($key.into(), Color::Default);
|
||||
dark.insert($key.into(), Color::Default);
|
||||
};
|
||||
}
|
||||
|
||||
light.insert("general.background".into(), Color::Default);
|
||||
light.insert("general.foreground".into(), Color::Default);
|
||||
|
||||
|
@ -136,46 +174,134 @@ impl Default for Theme {
|
|||
"general.tab_unfocused_fg",
|
||||
"general.tab_unfocused_bg",
|
||||
"general.tab_bar_bg",
|
||||
"mail.sidebar_fg",
|
||||
"mail.sidebar_bg",
|
||||
"mail.sidebar_unread_count_fg",
|
||||
"mail.sidebar_unread_count_bg",
|
||||
"mail.sidebar_index_fg",
|
||||
"mail.sidebar_index_bg",
|
||||
"mail.sidebar_highlighted_fg",
|
||||
"mail.sidebar_highlighted_bg",
|
||||
"mail.sidebar_highlighted_unread_count_fg",
|
||||
"mail.sidebar_highlighted_unread_count_bg",
|
||||
"mail.sidebar_highlighted_index_fg",
|
||||
"mail.sidebar_highlighted_index_bg",
|
||||
*/
|
||||
light.insert("mail.listing.compact.even_fg".into(), Color::Default);
|
||||
light.insert("mail.listing.compact.even_bg".into(), Color::Byte(252));
|
||||
light.insert("mail.listing.compact.odd_fg".into(), Color::Default);
|
||||
light.insert("mail.listing.compact.odd_bg".into(), Color::Default);
|
||||
light.insert("mail.listing.compact.unseen_fg".into(), Color::Byte(0));
|
||||
light.insert("mail.listing.compact.unseen_bg".into(), Color::Byte(251));
|
||||
light.insert("mail.listing.compact.selected_fg".into(), Color::Default);
|
||||
light.insert("mail.listing.compact.selected_bg".into(), Color::Byte(210));
|
||||
light.insert("mail.listing.compact.highlighted_fg".into(), Color::Default);
|
||||
light.insert(
|
||||
"mail.listing.compact.highlighted_bg".into(),
|
||||
Color::Byte(244),
|
||||
*/
|
||||
|
||||
/* Mail Sidebar */
|
||||
|
||||
add!("mail.sidebar_fg");
|
||||
add!("mail.sidebar_bg");
|
||||
add!("mail.sidebar_unread_count_fg", dark = Color::Byte(243));
|
||||
add!("mail.sidebar_unread_count_bg");
|
||||
add!("mail.sidebar_index_fg", dark = Color::Byte(243));
|
||||
add!("mail.sidebar_index_bg");
|
||||
add!("mail.sidebar_highlighted_fg", dark = Color::Byte(233));
|
||||
add!("mail.sidebar_highlighted_bg", dark = Color::Byte(15));
|
||||
add!(
|
||||
"mail.sidebar_highlighted_unread_count_fg",
|
||||
dark = dark["mail.sidebar_highlighted_fg"]
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_unread_count_bg",
|
||||
dark = dark["mail.sidebar_highlighted_bg"]
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_index_fg",
|
||||
dark = dark["mail.sidebar_index_fg"]
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_index_bg",
|
||||
dark = dark["mail.sidebar_highlighted_bg"]
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_account_fg",
|
||||
dark = Color::Byte(15)
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_account_bg",
|
||||
dark = Color::Byte(233)
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_account_unread_count_fg",
|
||||
dark = dark["mail.sidebar_unread_count_fg"]
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_account_unread_count_bg",
|
||||
dark = dark["mail.sidebar_highlighted_fg"]
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_account_index_fg",
|
||||
dark = dark["mail.sidebar_index_fg"]
|
||||
);
|
||||
add!(
|
||||
"mail.sidebar_highlighted_account_index_bg",
|
||||
dark = dark["mail.sidebar_highlighted_bg"]
|
||||
);
|
||||
|
||||
dark.insert("mail.listing.compact.even_fg".into(), Color::Default);
|
||||
dark.insert("mail.listing.compact.even_bg".into(), Color::Byte(236));
|
||||
dark.insert("mail.listing.compact.odd_fg".into(), Color::Default);
|
||||
dark.insert("mail.listing.compact.odd_bg".into(), Color::Default);
|
||||
dark.insert("mail.listing.compact.unseen_fg".into(), Color::Byte(0));
|
||||
dark.insert("mail.listing.compact.unseen_bg".into(), Color::Byte(251));
|
||||
dark.insert("mail.listing.compact.selected_fg".into(), Color::Default);
|
||||
dark.insert("mail.listing.compact.selected_bg".into(), Color::Byte(210));
|
||||
dark.insert("mail.listing.compact.highlighted_fg".into(), Color::Default);
|
||||
dark.insert(
|
||||
"mail.listing.compact.highlighted_bg".into(),
|
||||
Color::Byte(246),
|
||||
/* CompactListing */
|
||||
add!("mail.listing.compact.even_fg");
|
||||
add!(
|
||||
"mail.listing.compact.even_bg",
|
||||
dark = Color::Byte(236),
|
||||
light = Color::Byte(252)
|
||||
);
|
||||
add!("mail.listing.compact.odd_fg");
|
||||
add!("mail.listing.compact.odd_bg");
|
||||
add!(
|
||||
"mail.listing.compact.unseen_fg",
|
||||
dark = Color::Byte(0),
|
||||
light = Color::Byte(0)
|
||||
);
|
||||
add!(
|
||||
"mail.listing.compact.unseen_bg",
|
||||
dark = Color::Byte(251),
|
||||
light = Color::Byte(251)
|
||||
);
|
||||
add!("mail.listing.compact.selected_fg");
|
||||
add!(
|
||||
"mail.listing.compact.selected_bg",
|
||||
dark = Color::Byte(210),
|
||||
light = Color::Byte(210)
|
||||
);
|
||||
add!("mail.listing.compact.highlighted_fg");
|
||||
add!(
|
||||
"mail.listing.compact.highlighted_bg",
|
||||
dark = Color::Byte(246),
|
||||
light = Color::Byte(244)
|
||||
);
|
||||
|
||||
/* ConversationsListing */
|
||||
|
||||
add!("mail.listing.conversations.fg");
|
||||
add!("mail.listing.conversations.bg");
|
||||
add!("mail.listing.conversations.subject_fg");
|
||||
add!("mail.listing.conversations.subject_bg");
|
||||
add!("mail.listing.conversations.from_fg");
|
||||
add!("mail.listing.conversations.from_bg");
|
||||
add!("mail.listing.conversations.date_fg");
|
||||
add!("mail.listing.conversations.date_bg");
|
||||
add!(
|
||||
"mail.listing.conversations.padding",
|
||||
dark = Color::Byte(235),
|
||||
light = Color::Byte(254)
|
||||
);
|
||||
add!(
|
||||
"mail.listing.conversations.unseen_padding",
|
||||
dark = Color::Byte(235),
|
||||
light = Color::Byte(254)
|
||||
);
|
||||
add!(
|
||||
"mail.listing.conversations.unseen_fg",
|
||||
dark = Color::Byte(0),
|
||||
light = Color::Byte(0)
|
||||
);
|
||||
add!(
|
||||
"mail.listing.conversations.unseen_bg",
|
||||
dark = Color::Byte(251),
|
||||
light = Color::Byte(251)
|
||||
);
|
||||
add!("mail.listing.conversations.highlighted_fg");
|
||||
add!(
|
||||
"mail.listing.conversations.highlighted_bg",
|
||||
dark = Color::Byte(246),
|
||||
light = Color::Byte(246)
|
||||
);
|
||||
add!("mail.listing.conversations.selected_fg");
|
||||
add!(
|
||||
"mail.listing.conversations.selected_bg",
|
||||
dark = Color::Byte(210),
|
||||
light = Color::Byte(210)
|
||||
);
|
||||
|
||||
/*
|
||||
"mail.listing.plain.even_fg",
|
||||
"mail.listing.plain.even_bg",
|
||||
|
@ -189,9 +315,6 @@ impl Default for Theme {
|
|||
"mail.listing.conversations.from_bg",
|
||||
"mail.listing.conversations.date_fg",
|
||||
"mail.listing.conversations.date_bg",
|
||||
"mail.listing.conversations.padding",
|
||||
"mail.listing.conversations.unseen_fg",
|
||||
"mail.listing.conversations.unseen_bg",
|
||||
"mail.listing.conversations.unseen_padding",
|
||||
"mail.view.headers_fg",
|
||||
"mail.view.headers_bg",
|
||||
|
|
Loading…
Reference in New Issue