ui: add tags in compact, conversations

jmap
Manos Pitsidianakis 2019-11-30 21:55:40 +02:00
parent d31c629ac4
commit 19a268b8a7
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
3 changed files with 130 additions and 13 deletions

View File

@ -493,10 +493,33 @@ impl CompactListing {
} }
} }
fn make_entry_string( fn make_entry_string(
&self,
e: EnvelopeRef, e: EnvelopeRef,
context: &Context,
thread_node: &ThreadNode, thread_node: &ThreadNode,
is_snoozed: bool, is_snoozed: bool,
) -> EntryStrings { ) -> 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 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.folder_conf.ignore_tags.contains(t) {
continue;
}
tags.push(' ');
tags.push_str(tags_lck.get(t).as_ref().unwrap());
tags.push(' ');
}
if !tags.is_empty() {
tags.pop();
}
}
if thread_node.len() > 0 { if thread_node.len() > 0 {
EntryStrings { EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)), date: DateString(ConversationsListing::format_date(thread_node)),
@ -507,7 +530,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(String::new()), tags: TagString(tags),
} }
} else { } else {
EntryStrings { EntryStrings {
@ -519,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(String::new()), tags: TagString(tags),
} }
} }
} }
@ -626,15 +649,19 @@ impl CompactListing {
let root_envelope: EnvelopeRef = let root_envelope: EnvelopeRef =
context.accounts[self.cursor_pos.0].collection.get_env(i); context.accounts[self.cursor_pos.0].collection.get_env(i);
let entry_strings = CompactListing::make_entry_string( let entry_strings = self.make_entry_string(
root_envelope, root_envelope,
context,
thread_node, thread_node,
threads.is_snoozed(root_idx), threads.is_snoozed(root_idx),
); );
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 */
min_width.4 = cmp::max(min_width.4, entry_strings.subject.grapheme_width()); /* subject */ min_width.4 = cmp::max(
min_width.4,
entry_strings.subject.grapheme_width() + 1 + entry_strings.tags.grapheme_width(),
); /* subject */
rows.push(entry_strings); rows.push(entry_strings);
if refresh_mailbox { if refresh_mailbox {
self.all_threads.insert(root_idx); self.all_threads.insert(root_idx);
@ -769,6 +796,34 @@ impl CompactListing {
((0, idx), (min_width.4, idx)), ((0, idx), (min_width.4, idx)),
None, None,
); );
let x = {
let mut x = x + 1;
use std::convert::TryInto;
for (m, t) in strings.tags.split_whitespace().enumerate() {
let m = 2 * m.try_into().unwrap_or(0);
let (_x, _) = write_string_to_grid(
t,
&mut self.data_columns.columns[4],
Color::White,
Color::Byte(103 + m),
Attr::Bold,
((x + 1, idx), (min_width.4, idx)),
None,
);
self.data_columns.columns[4][(x, idx)].set_bg(Color::Byte(103 + m));
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_keep_bg(true);
}
for x in (x + 1).._x {
self.data_columns.columns[4][(x, idx)].set_keep_fg(true);
self.data_columns.columns[4][(x, idx)].set_keep_bg(true);
}
self.data_columns.columns[4][(x, idx)].set_keep_bg(true);
x = _x + 1;
}
x
};
for x in x..min_width.4 { for x in x..min_width.4 {
self.data_columns.columns[4][(x, idx)].set_bg(bg_color); self.data_columns.columns[4][(x, idx)].set_bg(bg_color);
} }

View File

@ -24,8 +24,7 @@ use crate::components::utilities::PageMovement;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
const MAX_COLS: usize = 500; #[derive(Debug)]
pub(super) struct EntryStrings { pub(super) struct EntryStrings {
pub(super) date: DateString, pub(super) date: DateString,
pub(super) subject: SubjectString, pub(super) subject: SubjectString,
@ -53,6 +52,7 @@ macro_rules! address_list {
macro_rules! column_str { macro_rules! column_str {
( (
struct $name:ident(String)) => { struct $name:ident(String)) => {
#[derive(Debug)]
pub(super) struct $name(pub String); pub(super) struct $name(pub String);
impl Deref for $name { impl Deref for $name {
@ -470,11 +470,34 @@ impl ConversationsListing {
} }
} }
pub(super) fn make_entry_string( pub(super) fn make_entry_string(
&self,
e: &Envelope, e: &Envelope,
context: &Context,
from: &Vec<Address>, from: &Vec<Address>,
thread_node: &ThreadNode, thread_node: &ThreadNode,
is_snoozed: bool, is_snoozed: bool,
) -> EntryStrings { ) -> 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 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.folder_conf.ignore_tags.contains(t) {
continue;
}
tags.push(' ');
tags.push_str(tags_lck.get(t).as_ref().unwrap());
tags.push(' ');
}
if !tags.is_empty() {
tags.pop();
}
}
if thread_node.len() > 0 { if thread_node.len() > 0 {
EntryStrings { EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)), date: DateString(ConversationsListing::format_date(thread_node)),
@ -485,7 +508,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(String::new()), tags: TagString(tags),
} }
} else { } else {
EntryStrings { EntryStrings {
@ -497,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(String::new()), tags: TagString(tags),
} }
} }
} }
@ -634,15 +657,24 @@ impl ConversationsListing {
let root_envelope: &EnvelopeRef = let root_envelope: &EnvelopeRef =
&context.accounts[self.cursor_pos.0].collection.get_env(i); &context.accounts[self.cursor_pos.0].collection.get_env(i);
let strings = ConversationsListing::make_entry_string( let strings = self.make_entry_string(
root_envelope, root_envelope,
context,
&from_address_list, &from_address_list,
thread_node, thread_node,
threads.is_snoozed(root_idx), threads.is_snoozed(root_idx),
); );
max_entry_columns = std::cmp::max( max_entry_columns = std::cmp::max(
max_entry_columns, max_entry_columns,
strings.flag.len() + 3 + strings.subject.len(), strings.flag.len()
+ 3
+ strings.subject.grapheme_width()
+ 1
+ strings.tags.grapheme_width(),
);
max_entry_columns = std::cmp::max(
max_entry_columns,
strings.date.len() + 1 + strings.from.grapheme_width(),
); );
rows.push(strings); rows.push(strings);
if refresh_mailbox { if refresh_mailbox {
@ -659,7 +691,7 @@ impl ConversationsListing {
} = self; } = self;
selection.retain(|e, _| order.contains_key(e)); selection.retain(|e, _| order.contains_key(e));
let width = std::cmp::min(MAX_COLS, max_entry_columns); let width = max_entry_columns;
self.content = self.content =
CellBuffer::new_with_context(width, 4 * rows.len(), Cell::with_char(' '), context); CellBuffer::new_with_context(width, 4 * rows.len(), Cell::with_char(' '), context);
@ -722,6 +754,34 @@ impl ConversationsListing {
((x, 3 * idx), (width - 1, 3 * idx)), ((x, 3 * idx), (width - 1, 3 * idx)),
None, None,
); );
let x = {
let mut x = x + 1;
use std::convert::TryInto;
for (m, t) in strings.tags.split_whitespace().enumerate() {
let m = 2 * m.try_into().unwrap_or(0);
let (_x, _) = write_string_to_grid(
t,
&mut self.content,
Color::White,
Color::Byte(103 + m),
Attr::Bold,
((x + 1, 3 * idx), (width - 1, 3 * idx)),
None,
);
self.content[(x, 3 * idx)].set_bg(Color::Byte(103 + m));
if _x < width {
self.content[(_x, 3 * idx)].set_bg(Color::Byte(103 + m));
self.content[(_x, 3 * idx)].set_keep_bg(true);
}
for x in (x + 1).._x {
self.content[(x, 3 * idx)].set_keep_fg(true);
self.content[(x, 3 * idx)].set_keep_bg(true);
}
self.content[(x, 3 * idx)].set_keep_bg(true);
x = _x + 1;
}
x
};
for x in x..width { for x in x..width {
self.content[(x, 3 * idx)].set_bg(bg_color); self.content[(x, 3 * idx)].set_bg(bg_color);
} }

View File

@ -771,13 +771,15 @@ impl PlainListing {
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(103 + m));
self.data_columns.columns[4][(_x, idx)].set_bg(Color::Byte(103 + m)); 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_keep_bg(true);
}
for x in (x + 1).._x { for x in (x + 1).._x {
self.data_columns.columns[4][(x, idx)].set_keep_fg(true); self.data_columns.columns[4][(x, idx)].set_keep_fg(true);
self.data_columns.columns[4][(x, idx)].set_keep_bg(true); self.data_columns.columns[4][(x, idx)].set_keep_bg(true);
} }
self.data_columns.columns[4][(x, idx)].set_keep_bg(true); self.data_columns.columns[4][(x, idx)].set_keep_bg(true);
self.data_columns.columns[4][(_x, idx)].set_keep_bg(true);
x = _x + 1; x = _x + 1;
} }
x x