summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-12-01 16:04:57 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-12-07 17:16:00 +0200
commit8e27b86453a8c7fc31c105150b984acae921e2b6 (patch)
tree338f864cad767ef344a3130772dca3ada3d2c903 /ui
parent6cf73b4238d2952396bfe3c27bc9e7286dd2950e (diff)
Add MailListingTrait
Inheriting ListingTrait
Diffstat (limited to 'ui')
-rw-r--r--ui/src/components/mail/listing.rs71
-rw-r--r--ui/src/components/mail/listing/compact.rs238
-rw-r--r--ui/src/components/mail/listing/conversations.rs141
-rw-r--r--ui/src/terminal/cells.rs2
4 files changed, 185 insertions, 267 deletions
diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs
index 26a14753..4ee5536d 100644
--- a/ui/src/components/mail/listing.rs
+++ b/ui/src/components/mail/listing.rs
@@ -46,6 +46,77 @@ struct AccountMenuEntry {
index: usize,
}
+pub trait MailListingTrait: ListingTrait {
+ fn perform_action(
+ &mut self,
+ context: &mut Context,
+ thread_hash: ThreadHash,
+ a: &ListingAction,
+ ) {
+ let account = &mut context.accounts[self.coordinates().0];
+ let mut envs_to_set: StackVec<EnvelopeHash> = StackVec::new();
+ let folder_hash = account[self.coordinates().1].unwrap().folder.hash();
+ {
+ let mut stack = StackVec::new();
+ stack.push(thread_hash);
+ while let Some(thread_iter) = stack.pop() {
+ {
+ let threads = account.collection.threads.get_mut(&folder_hash).unwrap();
+ threads
+ .thread_nodes
+ .entry(thread_iter)
+ .and_modify(|t| t.set_has_unseen(false));
+ }
+ let threads = &account.collection.threads[&folder_hash];
+ if let Some(env_hash) = threads[&thread_iter].message() {
+ if !account.contains_key(env_hash) {
+ /* The envelope has been renamed or removed, so wait for the appropriate event to
+ * arrive */
+ continue;
+ }
+ envs_to_set.push(env_hash);
+ }
+ for c in 0..threads[&thread_iter].children().len() {
+ let c = threads[&thread_iter].children()[c];
+ stack.push(c);
+ }
+ }
+ }
+ for env_hash in envs_to_set {
+ let op = account.operation(env_hash);
+ let mut envelope: EnvelopeRefMut = account.collection.get_env_mut(env_hash);
+ match a {
+ ListingAction::SetSeen => {
+ if let Err(e) = envelope.set_seen(op) {
+ context.replies.push_back(UIEvent::StatusEvent(
+ StatusEvent::DisplayMessage(e.to_string()),
+ ));
+ }
+ self.row_updates().push(thread_hash);
+ }
+ ListingAction::SetUnseen => {
+ if let Err(e) = envelope.set_unseen(op) {
+ context.replies.push_back(UIEvent::StatusEvent(
+ StatusEvent::DisplayMessage(e.to_string()),
+ ));
+ }
+ }
+ ListingAction::Delete => {
+ /* do nothing */
+ continue;
+ }
+ _ => unreachable!(),
+ }
+ self.row_updates().push(thread_hash);
+ drop(envelope);
+ }
+ }
+
+ fn row_updates(&mut self) -> &mut StackVec<ThreadHash>;
+
+ fn update_line(&mut self, context: &Context, thread_hash: ThreadHash);
+}
+
pub trait ListingTrait: Component {
fn coordinates(&self) -> (usize, usize);
fn set_coordinates(&mut self, _: (usize, usize));
diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs
index 1bfa6855..4106c181 100644
--- a/ui/src/components/mail/listing/compact.rs
+++ b/ui/src/components/mail/listing/compact.rs
@@ -74,6 +74,76 @@ pub struct CompactListing {
id: ComponentId,
}
+impl MailListingTrait for CompactListing {
+ fn row_updates(&mut self) -> &mut StackVec<ThreadHash> {
+ &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) => {}
+ }
+ }
+ }
+}
+
impl ListingTrait for CompactListing {
fn coordinates(&self) -> (usize, usize) {
(self.new_cursor_pos.0, self.new_cursor_pos.1)
@@ -888,136 +958,6 @@ impl CompactListing {
self.filtered_selection[cursor]
}
}
-
- fn perform_action(
- &mut self,
- context: &mut Context,
- thread_hash: ThreadHash,
- a: &ListingAction,
- ) {
- let account = &mut context.accounts[self.cursor_pos.0];
- let mut envs_to_set: StackVec<EnvelopeHash> = StackVec::new();
- let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
- {
- let mut stack = StackVec::new();
- stack.push(thread_hash);
- while let Some(thread_iter) = stack.pop() {
- {
- let threads = account.collection.threads.get_mut(&folder_hash).unwrap();
- threads
- .thread_nodes
- .entry(thread_iter)
- .and_modify(|t| t.set_has_unseen(false));
- }
- let threads = &account.collection.threads[&folder_hash];
- if let Some(env_hash) = threads[&thread_iter].message() {
- if !account.contains_key(env_hash) {
- /* The envelope has been renamed or removed, so wait for the appropriate event to
- * arrive */
- continue;
- }
- envs_to_set.push(env_hash);
- }
- for c in 0..threads[&thread_iter].children().len() {
- let c = threads[&thread_iter].children()[c];
- stack.push(c);
- }
- }
- }
- for env_hash in envs_to_set {
- let op = account.operation(env_hash);
- let mut envelope: EnvelopeRefMut = account.collection.get_env_mut(env_hash);
- match a {
- ListingAction::SetSeen => {
- if let Err(e) = envelope.set_seen(op) {
- context.replies.push_back(UIEvent::StatusEvent(
- StatusEvent::DisplayMessage(e.to_string()),
- ));
- }
- self.row_updates.push(thread_hash);
- }
- ListingAction::SetUnseen => {
- if let Err(e) = envelope.set_unseen(op) {
- context.replies.push_back(UIEvent::StatusEvent(
- StatusEvent::DisplayMessage(e.to_string()),
- ));
- }
- }
- ListingAction::Delete => {
- /* do nothing */
- continue;
- }
- _ => unreachable!(),
- }
- self.row_updates.push(thread_hash);
- let has_attachments = envelope.has_attachments();
- drop(envelope);
- let threads = &account.collection.threads[&folder_hash];
- 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 min_width = (
- self.data_columns.columns[0].size().0,
- self.data_columns.columns[1].size().0,
- self.data_columns.columns[2].size().0,
- self.data_columns.columns[3].size().0,
- self.data_columns.columns[4].size().0,
- );
- for x in 0..min_width.0 {
- self.data_columns.columns[0][(x, idx)].set_fg(fg_color);
- self.data_columns.columns[0][(x, idx)].set_bg(bg_color);
- }
- for x in 0..min_width.1 {
- self.data_columns.columns[1][(x, idx)].set_fg(fg_color);
- self.data_columns.columns[1][(x, idx)].set_bg(bg_color);
- }
- for x in 0..min_width.2 {
- self.data_columns.columns[2][(x, idx)].set_fg(fg_color);
- self.data_columns.columns[2][(x, idx)].set_bg(bg_color);
- }
- for x in 0..min_width.3 {
- self.data_columns.columns[3][(x, idx)].set_fg(fg_color);
- self.data_columns.columns[3][(x, idx)].set_bg(bg_color);
- }
- for x in 0..min_width.4 {
- self.data_columns.columns[4][(x, idx)].set_fg(fg_color);
- self.data_columns.columns[4][(x, idx)].set_bg(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) => {}
- }
- }
- }
}
impl Component for CompactListing {
@@ -1053,44 +993,8 @@ impl Component for CompactListing {
if !self.row_updates.is_empty() {
let (upper_left, bottom_right) = area;
while let Some(row) = self.row_updates.pop() {
+ self.update_line(context, row);
let row: usize = self.order[&row];
- let i = self.get_thread_under_cursor(row, context);
-
- 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[&i];
-
- 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 if self.selection[&i] {
- Color::Byte(210)
- } else if row % 2 == 0 {
- if context.settings.terminal.theme == "light" {
- Color::Byte(252)
- } else {
- 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, row), (column_width - 1, row)),
- fg_color,
- bg_color,
- );
- }
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
let page_no = (self.new_cursor_pos.2).wrapping_div(rows);
diff --git a/ui/src/components/mail/listing/conversations.rs b/ui/src/components/mail/listing/conversations.rs
index d2ab594a..7de6631e 100644
--- a/ui/src/components/mail/listing/conversations.rs
+++ b/ui/src/components/mail/listing/conversations.rs
@@ -106,6 +106,48 @@ pub struct ConversationsListing {
id: ComponentId,
}
+impl MailListingTrait for ConversationsListing {
+ fn row_updates(&mut self) -> &mut StackVec<ThreadHash> {
+ &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)
+ } else {
+ Color::Default
+ };
+ let bg_color = if thread_node.has_unseen() {
+ Color::Byte(251)
+ } else {
+ Color::Default
+ };
+ 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,
+ );
+ }
+}
impl ListingTrait for ConversationsListing {
fn coordinates(&self) -> (usize, usize) {
(self.new_cursor_pos.0, self.new_cursor_pos.1)
@@ -898,70 +940,6 @@ impl ConversationsListing {
self.filtered_selection[cursor]
}
}
-
- fn perform_action(
- &mut self,
- context: &mut Context,
- thread_hash: ThreadHash,
- a: &ListingAction,
- ) {
- let account = &mut context.accounts[self.cursor_pos.0];
- let mut envs_to_set: StackVec<EnvelopeHash> = StackVec::new();
- {
- let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
- let mut stack = StackVec::new();
- stack.push(thread_hash);
- while let Some(thread_iter) = stack.pop() {
- {
- let threads = account.collection.threads.get_mut(&folder_hash).unwrap();
- threads
- .thread_nodes
- .entry(thread_iter)
- .and_modify(|t| t.set_has_unseen(false));
- }
- let threads = &account.collection.threads[&folder_hash];
- if let Some(env_hash) = threads[&thread_iter].message() {
- if !account.contains_key(env_hash) {
- /* The envelope has been renamed or removed, so wait for the appropriate event to
- * arrive */
- continue;
- }
- envs_to_set.push(env_hash);
- }
- for c in 0..threads[&thread_iter].children().len() {
- let c = threads[&thread_iter].children()[c];
- stack.push(c);
- }
- }
- }
- for env_hash in envs_to_set {
- let hash = account.collection.get_env(env_hash).hash();
- let op = account.operation(hash);
- let mut envelope: EnvelopeRefMut = account.collection.get_env_mut(env_hash);
- match a {
- ListingAction::SetSeen => {
- if let Err(e) = envelope.set_seen(op) {
- context.replies.push_back(UIEvent::StatusEvent(
- StatusEvent::DisplayMessage(e.to_string()),
- ));
- }
- }
- ListingAction::SetUnseen => {
- if let Err(e) = envelope.set_unseen(op) {
- context.replies.push_back(UIEvent::StatusEvent(
- StatusEvent::DisplayMessage(e.to_string()),
- ));
- }
- }
- ListingAction::Delete => {
- /* do nothing */
- continue;
- }
- _ => unreachable!(),
- }
- self.row_updates.push(thread_hash);
- }
- }
}
impl Component for ConversationsListing {
@@ -1016,43 +994,10 @@ impl Component for ConversationsListing {
/* certain rows need to be updated (eg an unseen message was just set seen)
* */
let (upper_left, bottom_right) = area;
- let width = self.content.size().0;
while let Some(row) = self.row_updates.pop() {
+ self.update_line(context, row);
let row: usize = self.order[&row];
- let i = self.get_thread_under_cursor(row, context);
- 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[&i];
-
- 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
- };
- 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 rows = (get_y(bottom_right) - get_y(upper_left) + 1) / 3;
let page_no = (self.cursor_pos.2).wrapping_div(rows);
diff --git a/ui/src/terminal/cells.rs b/ui/src/terminal/cells.rs
index 042a2fcc..6995d0c2 100644
--- a/ui/src/terminal/cells.rs
+++ b/ui/src/terminal/cells.rs
@@ -1005,8 +1005,6 @@ pub fn clear_area(grid: &mut CellBuffer, area: Area) {
if !is_valid_area!(area) {
return;
}
- let upper_left = upper_left!(area);
- let bottom_right = bottom_right!(area);
for row in grid.bounds_iter(area) {
for c in row {
grid[c] = Cell::default();