summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-04-01 07:33:48 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-06-10 19:40:41 +0300
commitf36cb111b5b16614eb0b7930cb342d60bdec6f31 (patch)
treee9f652cbd98f7da4e724e60e884085756c31a6e0
parent5d9af8e32b3b54753211f8ee50979ec035baec78 (diff)
ui: add reverse order option in ThreadView
closes #70
-rw-r--r--ui/src/components/mail/view/thread.rs176
1 files changed, 118 insertions, 58 deletions
diff --git a/ui/src/components/mail/view/thread.rs b/ui/src/components/mail/view/thread.rs
index 654c66c0..62775e83 100644
--- a/ui/src/components/mail/view/thread.rs
+++ b/ui/src/components/mail/view/thread.rs
@@ -36,6 +36,7 @@ pub struct ThreadView {
cursor_pos: usize,
expanded_pos: usize,
new_expanded_pos: usize,
+ reversed: bool,
dirty: bool,
coordinates: (usize, usize, usize),
mailview: MailView,
@@ -57,14 +58,8 @@ impl ThreadView {
expanded_idx: Option<usize>,
context: &Context,
) -> Self {
- /* stack to push thread messages in order in order to pop and print them later */
- let mailbox = &context.accounts[coordinates.0][coordinates.1]
- .as_ref()
- .unwrap();
- let threads = &mailbox.collection.threads;
-
- let thread_iter = threads.thread_iter(coordinates.2);
let mut view = ThreadView {
+ reversed: false,
dirty: true,
initiated: false,
coordinates,
@@ -75,34 +70,47 @@ impl ThreadView {
new_cursor_pos: 0,
..Default::default()
};
+ view.initiate(expanded_idx, context);
+ view.new_cursor_pos = view.new_expanded_pos;
+ view
+ }
+ fn initiate(&mut self, expanded_idx: Option<usize>, context: &Context) {
+ /* stack to push thread messages in order in order to pop and print them later */
+ let mailbox = &context.accounts[self.coordinates.0][self.coordinates.1]
+ .as_ref()
+ .unwrap();
+ let threads = &mailbox.collection.threads;
+
+ let thread_iter = threads.thread_iter(self.coordinates.2);
+ self.entries.clear();
for (line, (ind, idx)) in thread_iter.enumerate() {
let entry = if let Some(msg_idx) = threads.thread_nodes()[idx].message() {
- view.make_entry((ind, idx, line), msg_idx)
+ self.make_entry((ind, idx, line), msg_idx)
} else {
continue;
};
- view.entries.push(entry);
+ self.entries.push(entry);
match expanded_idx {
Some(expanded_idx) if expanded_idx == idx => {
- view.new_expanded_pos = view.entries.len().saturating_sub(1);
- view.expanded_pos = view.new_expanded_pos + 1;
+ self.new_expanded_pos = self.entries.len().saturating_sub(1);
+ self.expanded_pos = self.new_expanded_pos + 1;
}
_ => {}
}
}
if expanded_idx.is_none() {
- view.new_expanded_pos = view.entries.len().saturating_sub(1);
- view.expanded_pos = view.new_expanded_pos + 1;
+ self.new_expanded_pos = self.entries.len().saturating_sub(1);
+ self.expanded_pos = self.new_expanded_pos + 1;
}
- let height = 2 * view.entries.len() + 1;
+ let height = 2 * self.entries.len() + 1;
let mut width = 0;
- let mut strings: Vec<String> = Vec::with_capacity(view.entries.len());
+ let mut strings: Vec<String> = Vec::with_capacity(self.entries.len());
let mut highlight_reply_subjects: Vec<Option<usize>> =
- Vec::with_capacity(view.entries.len());
- for e in &view.entries {
+ Vec::with_capacity(self.entries.len());
+ for e in &self.entries {
let envelope: &Envelope = &mailbox.collection[&e.msg_idx];
let thread_node = &threads.thread_nodes()[e.index.1];
let string = if thread_node.show_subject() {
@@ -131,53 +139,96 @@ impl ThreadView {
);
}
let mut content = CellBuffer::new(width, height, Cell::default());
- for (y, e) in view.entries.iter().enumerate() {
- /* Box character drawing stuff */
- if y > 0 && content.get_mut(e.index.0 * 4, 2 * y - 1).is_some() {
- let index = (e.index.0 * 4, 2 * y - 1);
- if content[index].ch() == ' ' {
- let mut ctr = 1;
- while content[(e.index.0 * 4 + ctr, 2 * y - 1)].ch() == ' ' {
- set_and_join_box(
- &mut content,
- (e.index.0 * 4 + ctr, 2 * y - 1),
- HORZ_BOUNDARY,
- );
- ctr += 1;
+ if self.reversed {
+ for (y, e) in self.entries.iter().rev().enumerate() {
+ /* Box character drawing stuff */
+ if y > 0 && content.get_mut(e.index.0 * 4, 2 * y - 1).is_some() {
+ let index = (e.index.0 * 4, 2 * y - 1);
+ if content[index].ch() == ' ' {
+ let mut ctr = 1;
+ while content.get(e.index.0 * 4 + ctr, 2 * y - 1).is_some() {
+ if content[(e.index.0 * 4 + ctr, 2 * y - 1)].ch() != ' ' { break; }
+ set_and_join_box(
+ &mut content,
+ (e.index.0 * 4 + ctr, 2 * y - 1),
+ HORZ_BOUNDARY,
+ );
+ ctr += 1;
+ }
+ set_and_join_box(&mut content, index, HORZ_BOUNDARY);
}
- set_and_join_box(&mut content, index, HORZ_BOUNDARY);
}
+ write_string_to_grid(
+ &strings[y],
+ &mut content,
+ Color::Default,
+ Color::Default,
+ ((e.index.0 * 4 + 1, 2 * y), (width - 1, height - 1)),
+ true,
+ );
+ if let Some(len) = highlight_reply_subjects[y] {
+ let index = e.index.0 * 4 + 1 + strings[y].len() - len;
+ let area = ((index, 2 * y), (width - 2, 2 * y));
+ let fg_color = Color::Byte(33);
+ let bg_color = Color::Default;
+ change_colors(&mut content, area, fg_color, bg_color);
+ }
+ set_and_join_box(&mut content, (e.index.0 * 4, 2 * y), VERT_BOUNDARY);
+ set_and_join_box(&mut content, (e.index.0 * 4, 2 * y + 1), VERT_BOUNDARY);
+ for i in ((e.index.0 * 4) + 1)..width - 1 {
+ set_and_join_box(&mut content, (i, 2 * y + 1), HORZ_BOUNDARY);
+ }
+ set_and_join_box(&mut content, (width - 1, 2 * y), VERT_BOUNDARY);
+ set_and_join_box(&mut content, (width - 1, 2 * y + 1), VERT_BOUNDARY);
}
- write_string_to_grid(
- &strings[y],
- &mut content,
- Color::Default,
- Color::Default,
- ((e.index.0 * 4 + 1, 2 * y), (width - 1, height - 1)),
- true,
- );
- if let Some(len) = highlight_reply_subjects[y] {
- let index = e.index.0 * 4 + 1 + strings[y].len() - len;
- let area = ((index, 2 * y), (width - 2, 2 * y));
- let fg_color = Color::Byte(33);
- let bg_color = Color::Default;
- change_colors(&mut content, area, fg_color, bg_color);
- }
- set_and_join_box(&mut content, (e.index.0 * 4, 2 * y), VERT_BOUNDARY);
- set_and_join_box(&mut content, (e.index.0 * 4, 2 * y + 1), VERT_BOUNDARY);
- for i in ((e.index.0 * 4) + 1)..width - 1 {
- set_and_join_box(&mut content, (i, 2 * y + 1), HORZ_BOUNDARY);
+ } else {
+ for (y, e) in self.entries.iter().enumerate() {
+ /* Box character drawing stuff */
+ if y > 0 && content.get_mut(e.index.0 * 4, 2 * y - 1).is_some() {
+ let index = (e.index.0 * 4, 2 * y - 1);
+ if content[index].ch() == ' ' {
+ let mut ctr = 1;
+ while content.get(e.index.0 * 4 + ctr, 2 * y - 1).is_some() {
+ if content[(e.index.0 * 4 + ctr, 2 * y - 1)].ch() != ' ' { break; }
+ set_and_join_box(
+ &mut content,
+ (e.index.0 * 4 + ctr, 2 * y - 1),
+ HORZ_BOUNDARY,
+ );
+ ctr += 1;
+ }
+ set_and_join_box(&mut content, index, HORZ_BOUNDARY);
+ }
+ }
+ write_string_to_grid(
+ &strings[y],
+ &mut content,
+ Color::Default,
+ Color::Default,
+ ((e.index.0 * 4 + 1, 2 * y), (width - 1, height - 1)),
+ true,
+ );
+ if let Some(len) = highlight_reply_subjects[y] {
+ let index = e.index.0 * 4 + 1 + strings[y].len() - len;
+ let area = ((index, 2 * y), (width - 2, 2 * y));
+ let fg_color = Color::Byte(33);
+ let bg_color = Color::Default;
+ change_colors(&mut content, area, fg_color, bg_color);
+ }
+ set_and_join_box(&mut content, (e.index.0 * 4, 2 * y), VERT_BOUNDARY);
+ set_and_join_box(&mut content, (e.index.0 * 4, 2 * y + 1), VERT_BOUNDARY);
+ for i in ((e.index.0 * 4) + 1)..width - 1 {
+ set_and_join_box(&mut content, (i, 2 * y + 1), HORZ_BOUNDARY);
+ }
+ set_and_join_box(&mut content, (width - 1, 2 * y), VERT_BOUNDARY);
+ set_and_join_box(&mut content, (width - 1, 2 * y + 1), VERT_BOUNDARY);
}
- set_and_join_box(&mut content, (width - 1, 2 * y), VERT_BOUNDARY);
- set_and_join_box(&mut content, (width - 1, 2 * y + 1), VERT_BOUNDARY);
- }
- for y in 0..height - 1 {
- set_and_join_box(&mut content, (width - 1, y), VERT_BOUNDARY);
+ for y in 0..height - 1 {
+ set_and_join_box(&mut content, (width - 1, y), VERT_BOUNDARY);
+ }
}
- view.content = content;
- view.new_cursor_pos = view.new_expanded_pos;
- view
+ self.content = content;
}
fn make_entry(&mut self, i: (usize, usize, usize), msg_idx: EnvelopeHash) -> ThreadEntry {
@@ -629,6 +680,14 @@ impl Component for ThreadView {
self.set_dirty();
return true;
}
+ UIEventType::Input(Key::Ctrl('r')) => {
+ self.reversed = !self.reversed;
+ let expanded_pos = self.expanded_pos;
+ self.initiate(Some(expanded_pos), context);
+ self.initiated = false;
+ self.set_dirty();
+ return true;
+ }
UIEventType::Resize => {
self.set_dirty();
}
@@ -648,6 +707,7 @@ impl Component for ThreadView {
let mut map = self.mailview.get_shortcuts(context);
map.insert("reply", Key::Char('R'));
+ map.insert("reverse thread order", Key::Char('r'));
map.insert("toggle_mailview", Key::Char('p'));
map