ui: user-configured colors for tags in mail listings

This commit is contained in:
Manos Pitsidianakis 2019-12-01 12:10:31 +02:00
parent bca33370cc
commit 3ae43817a1
No known key found for this signature in database
GPG Key ID: 73627C2F690DF710
3 changed files with 57 additions and 25 deletions

View File

@ -542,7 +542,7 @@ impl CompactListing {
if is_snoozed { "💤" } else { "" } if is_snoozed { "💤" } else { "" }
)), )),
from: FromString(address_list!((e.from()) as comma_sep_list)), from: FromString(address_list!((e.from()) as comma_sep_list)),
tags: TagString(tags), tags: TagString(tags, colors),
} }
} else { } else {
EntryStrings { EntryStrings {
@ -554,7 +554,7 @@ impl CompactListing {
if is_snoozed { "💤" } else { "" } if is_snoozed { "💤" } else { "" }
)), )),
from: FromString(address_list!((e.from()) as comma_sep_list)), from: FromString(address_list!((e.from()) as comma_sep_list)),
tags: TagString(tags), tags: TagString(tags, colors),
} }
} }
} }
@ -810,21 +810,19 @@ impl CompactListing {
); );
let x = { let x = {
let mut x = x + 1; let mut x = x + 1;
use std::convert::TryInto; for (t, &color) in strings.tags.split_whitespace().zip(strings.tags.1.iter()) {
for (m, t) in strings.tags.split_whitespace().enumerate() {
let m = 2 * m.try_into().unwrap_or(0);
let (_x, _) = write_string_to_grid( let (_x, _) = write_string_to_grid(
t, t,
&mut self.data_columns.columns[4], &mut self.data_columns.columns[4],
Color::White, Color::White,
Color::Byte(103 + m), Color::Byte(color),
Attr::Bold, Attr::Bold,
((x + 1, idx), (min_width.4, idx)), ((x + 1, idx), (min_width.4, idx)),
None, None,
); );
self.data_columns.columns[4][(x, idx)].set_bg(Color::Byte(103 + m)); self.data_columns.columns[4][(x, idx)].set_bg(Color::Byte(color));
if _x < min_width.4 { if _x < min_width.4 {
self.data_columns.columns[4][(_x, idx)].set_bg(Color::Byte(103 + m)); self.data_columns.columns[4][(_x, idx)].set_bg(Color::Byte(color));
self.data_columns.columns[4][(_x, idx)].set_keep_bg(true); self.data_columns.columns[4][(_x, idx)].set_keep_bg(true);
} }
for x in (x + 1).._x { for x in (x + 1).._x {

View File

@ -51,9 +51,9 @@ macro_rules! address_list {
macro_rules! column_str { macro_rules! column_str {
( (
struct $name:ident(String)) => { struct $name:ident($($t:ty),+)) => {
#[derive(Debug)] #[derive(Debug)]
pub(super) struct $name(pub String); pub(super) struct $name($(pub $t),+);
impl Deref for $name { impl Deref for $name {
type Target = String; type Target = String;
@ -73,7 +73,7 @@ column_str!(struct DateString(String));
column_str!(struct FromString(String)); column_str!(struct FromString(String));
column_str!(struct SubjectString(String)); column_str!(struct SubjectString(String));
column_str!(struct FlagString(String)); column_str!(struct FlagString(String));
column_str!(struct TagString(String)); column_str!(struct TagString(String, StackVec<u8>));
/// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a /// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a
/// `ThreadView`. /// `ThreadView`.
@ -520,7 +520,7 @@ impl ConversationsListing {
if is_snoozed { "💤" } else { "" } if is_snoozed { "💤" } else { "" }
)), )),
from: FromString(address_list!((from) as comma_sep_list)), from: FromString(address_list!((from) as comma_sep_list)),
tags: TagString(tags), tags: TagString(tags, colors),
} }
} else { } else {
EntryStrings { EntryStrings {
@ -532,7 +532,7 @@ impl ConversationsListing {
if is_snoozed { "💤" } else { "" } if is_snoozed { "💤" } else { "" }
)), )),
from: FromString(address_list!((from) as comma_sep_list)), from: FromString(address_list!((from) as comma_sep_list)),
tags: TagString(tags), tags: TagString(tags, colors),
} }
} }
} }
@ -768,21 +768,19 @@ impl ConversationsListing {
); );
let x = { let x = {
let mut x = x + 1; let mut x = x + 1;
use std::convert::TryInto; for (t, &color) in strings.tags.split_whitespace().zip(strings.tags.1.iter()) {
for (m, t) in strings.tags.split_whitespace().enumerate() {
let m = 2 * m.try_into().unwrap_or(0);
let (_x, _) = write_string_to_grid( let (_x, _) = write_string_to_grid(
t, t,
&mut self.content, &mut self.content,
Color::White, Color::White,
Color::Byte(103 + m), Color::Byte(color),
Attr::Bold, Attr::Bold,
((x + 1, 3 * idx), (width - 1, 3 * idx)), ((x + 1, 3 * idx), (width - 1, 3 * idx)),
None, None,
); );
self.content[(x, 3 * idx)].set_bg(Color::Byte(103 + m)); self.content[(x, 3 * idx)].set_bg(Color::Byte(color));
if _x < width { if _x < width {
self.content[(_x, 3 * idx)].set_bg(Color::Byte(103 + m)); self.content[(_x, 3 * idx)].set_bg(Color::Byte(color));
self.content[(_x, 3 * idx)].set_keep_bg(true); self.content[(_x, 3 * idx)].set_keep_bg(true);
} }
for x in (x + 1).._x { for x in (x + 1).._x {

View File

@ -468,13 +468,52 @@ impl PlainListing {
id: ComponentId::new_v4(), id: ComponentId::new_v4(),
} }
} }
fn make_entry_string(e: EnvelopeRef, tags: String) -> EntryStrings { fn make_entry_string(&self, e: EnvelopeRef, context: &Context) -> EntryStrings {
let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1]
.unwrap()
.folder
.hash();
let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash];
let mut tags = String::new();
let mut colors = StackVec::new();
let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap();
if let Some(t) = backend_lck.tags() {
let tags_lck = t.read().unwrap();
for t in e.labels().iter() {
if folder
.conf_override
.tags
.as_ref()
.map(|s| s.ignore_tags.contains(t))
.unwrap_or(false)
{
continue;
}
tags.push(' ');
tags.push_str(tags_lck.get(t).as_ref().unwrap());
tags.push(' ');
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);
}
}
if !tags.is_empty() {
tags.pop();
}
}
EntryStrings { EntryStrings {
date: DateString(PlainListing::format_date(&e)), date: DateString(PlainListing::format_date(&e)),
subject: SubjectString(format!("{}", e.subject())), subject: SubjectString(format!("{}", e.subject())),
flag: FlagString(format!("{}", if e.has_attachments() { "📎" } else { "" },)), flag: FlagString(format!("{}", if e.has_attachments() { "📎" } else { "" },)),
from: FromString(address_list!((e.from()) as comma_sep_list)), from: FromString(address_list!((e.from()) as comma_sep_list)),
tags: TagString(tags), tags: TagString(tags, colors),
} }
} }
@ -545,8 +584,6 @@ impl PlainListing {
fn redraw_list(&mut self, context: &Context) { fn redraw_list(&mut self, context: &Context) {
let account = &context.accounts[self.cursor_pos.0]; let account = &context.accounts[self.cursor_pos.0];
let mailbox = &account[self.cursor_pos.1].unwrap(); let mailbox = &account[self.cursor_pos.1].unwrap();
let folder_hash = &account[self.cursor_pos.1].unwrap().folder.hash();
let folder = &account.folder_confs[&folder_hash];
self.order.clear(); self.order.clear();
self.selection.clear(); self.selection.clear();
@ -602,9 +639,8 @@ impl PlainListing {
panic!(); panic!();
} }
let envelope: EnvelopeRef = context.accounts[self.cursor_pos.0].collection.get_env(i); let envelope: EnvelopeRef = context.accounts[self.cursor_pos.0].collection.get_env(i);
let mut tags = String::new();
let entry_strings = PlainListing::make_entry_string(envelope, tags); let entry_strings = self.make_entry_string(envelope, context);
min_width.1 = cmp::max(min_width.1, entry_strings.date.grapheme_width()); /* date */ min_width.1 = cmp::max(min_width.1, entry_strings.date.grapheme_width()); /* date */
min_width.2 = cmp::max(min_width.2, entry_strings.from.grapheme_width()); /* from */ min_width.2 = cmp::max(min_width.2, entry_strings.from.grapheme_width()); /* from */
min_width.3 = cmp::max(min_width.3, entry_strings.flag.grapheme_width()); /* flags */ min_width.3 = cmp::max(min_width.3, entry_strings.flag.grapheme_width()); /* flags */