summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2018-08-07 11:47:26 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-06-10 19:40:27 +0300
commit43ad31d2ab28c94fdd6b6c36d841971bad93964a (patch)
treec03e1ba80274eafd056e07fdd20a20bdabf6e145 /ui
parent8a7dfcd4eed4a154392cc272b7e7095861c63ee4 (diff)
Add sort/subsort functions, not working yet as intended
Diffstat (limited to 'ui')
-rw-r--r--ui/src/components/mail/listing.rs53
-rw-r--r--ui/src/execute/actions.rs56
-rw-r--r--ui/src/execute/mod.rs39
-rw-r--r--ui/src/state.rs3
4 files changed, 132 insertions, 19 deletions
diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs
index 80f47e4c..01cd46cf 100644
--- a/ui/src/components/mail/listing.rs
+++ b/ui/src/components/mail/listing.rs
@@ -10,7 +10,8 @@ pub struct MailListing {
cursor_pos: (usize, usize, usize),
new_cursor_pos: (usize, usize, usize),
length: usize,
- // TODO: sorting
+ sort: (SortField, SortOrder),
+ subsort: (SortField, SortOrder),
/// Cache current view.
content: CellBuffer,
/// If we must redraw on next redraw event
@@ -38,6 +39,8 @@ impl MailListing {
cursor_pos: (0, 1, 0),
new_cursor_pos: (0, 0, 0),
length: 0,
+ sort: (SortField::Date, SortOrder::Desc),
+ subsort: (SortField::Date, SortOrder::Asc),
content: content,
dirty: true,
unfocused: false,
@@ -99,7 +102,33 @@ impl MailListing {
let mut indentations: Vec<bool> = Vec::with_capacity(6);
let mut thread_idx = 0; // needed for alternate thread colors
/* Draw threaded view. */
- let mut iter = mailbox.threaded_collection.iter().enumerate().peekable();
+ let mut local_collection: Vec<usize> = mailbox.threaded_collection.clone();
+ let mut threads: Vec<&Container> = mailbox.threads.iter().map(|v| v).collect();
+ local_collection.sort_by(|a, b| {
+ match self.sort {
+ (SortField::Date, SortOrder::Desc) => {
+ mailbox.thread(*b).date().cmp(&mailbox.thread(*a).date())
+ },
+ (SortField::Date, SortOrder::Asc) => {
+ mailbox.thread(*a).date().cmp(&mailbox.thread(*b).date())
+ },
+ (SortField::Subject, SortOrder::Desc) => {
+ let a = mailbox.thread(*a);
+ let b = mailbox.thread(*b);
+ let ma = &mailbox.collection[*a.message().as_ref().unwrap()];
+ let mb = &mailbox.collection[*b.message().as_ref().unwrap()];
+ ma.subject().cmp(&mb.subject())
+ },
+ (SortField::Subject, SortOrder::Asc) => {
+ let a = mailbox.thread(*a);
+ let b = mailbox.thread(*b);
+ let ma = &mailbox.collection[*a.message().as_ref().unwrap()];
+ let mb = &mailbox.collection[*b.message().as_ref().unwrap()];
+ mb.subject().cmp(&ma.subject())
+ },
+ }
+ });
+ let mut iter = local_collection.iter().enumerate().peekable();
let len = mailbox
.threaded_collection
.len()
@@ -108,16 +137,16 @@ impl MailListing {
.count();
/* This is just a desugared for loop so that we can use .peek() */
while let Some((idx, i)) = iter.next() {
- let container = mailbox.thread(*i);
+ let container = threads[*i];
let indentation = container.indentation();
if indentation == 0 {
thread_idx += 1;
}
- assert_eq!(container.has_message(), true);
+ assert!(container.has_message() == true);
match iter.peek() {
- Some(&(_, x)) if mailbox.thread(*x).indentation() == indentation => {
+ Some(&(_, x)) if threads[*x].indentation() == indentation => {
indentations.pop();
indentations.push(true);
}
@@ -164,11 +193,11 @@ impl MailListing {
}
match iter.peek() {
- Some(&(_, x)) if mailbox.thread(*x).indentation() > indentation => {
+ Some(&(_, x)) if threads[*x].indentation() > indentation => {
indentations.push(false);
}
- Some(&(_, x)) if mailbox.thread(*x).indentation() < indentation => {
- for _ in 0..(indentation - mailbox.thread(*x).indentation()) {
+ Some(&(_, x)) if threads[*x].indentation() < indentation => {
+ for _ in 0..(indentation - threads[*x].indentation()) {
indentations.pop();
}
}
@@ -661,7 +690,13 @@ impl Component for MailListing {
self.refresh_mailbox(context);
return;
},
- //_ => {},
+ Action::Sort(field, order) => {
+ self.sort = (field.clone(), order.clone());
+ self.dirty = true;
+ self.refresh_mailbox(context);
+ return;
+ },
+ _ => {},
},
_ => {}
}
diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs
index bf556c4d..e615670b 100644
--- a/ui/src/execute/actions.rs
+++ b/ui/src/execute/actions.rs
@@ -2,13 +2,65 @@
* User actions that need to be handled by the UI
*/
-#[derive(Debug)]
+use std::str::FromStr;
+
+#[derive(Debug, Clone)]
pub enum MailListingAction {
ToggleThreaded,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
+pub enum SortOrder {
+ Asc,
+ Desc,
+}
+
+#[derive(Debug, Clone)]
+pub enum SortField {
+ Subject,
+ Date,
+}
+
+
+impl FromStr for SortField {
+ type Err = ();
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ eprintln!("sortfield from_str {}", s);
+ match s.trim() {
+ "subject" | "s" | "sub" | "sbj" | "subj" => {
+ eprintln!("parsed: subject");
+ }
+ "date" | "d" => {
+ eprintln!("parsed date");
+ }
+ _ => {
+ eprintln!("error in parse");
+ }
+ }
+ match s.trim() {
+ "subject" | "s" | "sub" | "sbj" | "subj" => Ok(SortField::Subject),
+ "date" | "d" => Ok(SortField::Date),
+ _ => Err(())
+ }
+ }
+}
+
+impl FromStr for SortOrder {
+ type Err = ();
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ eprintln!("sortoder from_str {}", s);
+ match s.trim() {
+ "asc" => Ok(SortOrder::Asc),
+ "desc" => Ok(SortOrder::Desc),
+ _ => Err(())
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
pub enum Action {
MailListing(MailListingAction),
ViewMailbox(usize),
+ Sort(SortField, SortOrder),
+ SubSort(SortField, SortOrder),
}
diff --git a/ui/src/execute/mod.rs b/ui/src/execute/mod.rs
index e8933501..d37d2351 100644
--- a/ui/src/execute/mod.rs
+++ b/ui/src/execute/mod.rs
@@ -1,6 +1,6 @@
/*! A parser module for user commands passed through the Ex mode.
*/
-use nom::{digit, };
+use nom::{digit, not_line_ending};
use std;
pub mod actions;
pub use actions::*;
@@ -14,15 +14,40 @@ named!(
)
);
+named!(sortfield<SortField>,
+ map_res!(
+ map_res!(take_until_s!(" "), std::str::from_utf8),
+ std::str::FromStr::from_str));
+
+
+named!(sortorder<SortOrder>,
+ map_res!(
+ map_res!(call!(not_line_ending), std::str::from_utf8),
+ std::str::FromStr::from_str));
+
+
+
named!(goto<Action>,
preceded!(tag!("b "),
map!(call!(usize_c), |v| Action::ViewMailbox(v))
));
-//named!(sort<&str>,
-// preceded!(tag!("sort "),
-// map_res!(call!(alpha), std::str::from_utf8))
-// );
+named!(subsort<Action>, do_parse!(
+ tag!("subsort ") >>
+ p: pair!(sortfield,sortorder) >>
+ (
+ Action::SubSort(p.0, p.1)
+
+ )
+ ));
+named!(sort<Action>, do_parse!(
+ tag!("sort ") >>
+ p: separated_pair!(sortfield,tag!(" "), sortorder) >>
+ (
+ Action::Sort(p.0, p.1)
+
+ )
+ ));
named!(threaded<Action>,
map!(ws!(tag!("threaded")), |_| Action::MailListing(MailListingAction::ToggleThreaded)));
@@ -30,6 +55,6 @@ named!(toggle<Action>,
preceded!(tag!("toggle "),
alt_complete!( threaded )));
-named!(pub parse_command<Action>,
- alt_complete!( goto | toggle)
+named!(pub parse_command<Action>,
+ alt_complete!( goto | toggle | sort | subsort)
);
diff --git a/ui/src/state.rs b/ui/src/state.rs
index 2a335ede..f910a391 100644
--- a/ui/src/state.rs
+++ b/ui/src/state.rs
@@ -313,7 +313,9 @@ impl<W: Write> State<W> {
}
/// Convert user commands to actions/method calls.
fn parse_command(&mut self, cmd: String) {
+ eprintln!("cmd is {}", cmd);
let result = parse_command(&cmd.as_bytes()).to_full_result();
+ eprintln!("rseult is {:?}", result);
if let Ok(v) = result {
self.rcv_event(UIEvent { id: 0, event_type: UIEventType::Action(v) });
@@ -399,7 +401,6 @@ impl<W: Write> State<W> {
}
}
-
pub fn try_wait_on_child(&mut self) -> Option<bool> {
if {
match self.child {