diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2018-08-14 17:36:45 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2019-06-10 19:40:28 +0300 |
commit | daa28ae18856b5b818c1d67ab6af9fa54373b7a5 (patch) | |
tree | a67e7cf0322b9ccb1799e005bafec4b0af473b74 /ui | |
parent | 591946a842a806a06739e38edd9011ce8cf940b0 (diff) |
Sorting in threaded view
Concerns #7
Diffstat (limited to 'ui')
-rw-r--r-- | ui/src/components/mail/listing/compact.rs | 9 | ||||
-rw-r--r-- | ui/src/components/mail/listing/mod.rs | 117 | ||||
-rw-r--r-- | ui/src/execute/actions.rs | 35 |
3 files changed, 75 insertions, 86 deletions
diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs index 46e84d86..9c500706 100644 --- a/ui/src/components/mail/listing/compact.rs +++ b/ui/src/components/mail/listing/compact.rs @@ -94,7 +94,7 @@ impl CompactMailListing { .as_ref() .unwrap(); - self.length = mailbox.threads.len(); + self.length = mailbox.threads.containers().len(); let mut content = CellBuffer::new(MAX_COLS, self.length + 1, Cell::with_char(' ')); if self.length == 0 { write_string_to_grid( @@ -113,8 +113,8 @@ impl CompactMailListing { let mut indentations: Vec<bool> = Vec::with_capacity(6); let mut thread_idx = 0; // needed for alternate thread colors /* Draw threaded view. */ - let mut local_collection: Vec<usize> = mailbox.threaded_collection.clone(); - let threads: &Vec<Container> = &mailbox.threads; + let mut local_collection: Vec<usize> = mailbox.threads.threaded_collection().clone(); + let threads: &Vec<Container> = &mailbox.threads.containers(); local_collection.sort_by(|a, b| match self.sort { (SortField::Date, SortOrder::Desc) => { mailbox.thread(*b).date().cmp(&mailbox.thread(*a).date()) @@ -139,7 +139,8 @@ impl CompactMailListing { }); let mut iter = local_collection.iter().enumerate().peekable(); let len = mailbox - .threaded_collection + .threads + .threaded_collection() .len() .to_string() .chars() diff --git a/ui/src/components/mail/listing/mod.rs b/ui/src/components/mail/listing/mod.rs index 611de7ab..259a4c7b 100644 --- a/ui/src/components/mail/listing/mod.rs +++ b/ui/src/components/mail/listing/mod.rs @@ -34,8 +34,9 @@ pub struct MailListing { cursor_pos: (usize, usize, usize), new_cursor_pos: (usize, usize, usize), length: usize, + local_collection: Vec<usize>, sort: (SortField, SortOrder), - //subsort: (SortField, SortOrder), + subsort: (SortField, SortOrder), /// Cache current view. content: CellBuffer, /// If we must redraw on next redraw event @@ -75,8 +76,9 @@ 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), + local_collection: Vec::new(), + sort: (Default::default(), Default::default()), + subsort: (Default::default(), Default::default()), content: content, dirty: true, unfocused: false, @@ -113,7 +115,7 @@ impl MailListing { .unwrap(); self.length = if threaded { - mailbox.threaded_collection.len() + mailbox.threads.threaded_collection().len() } else { mailbox.len() }; @@ -136,57 +138,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 local_collection: Vec<usize> = mailbox.threaded_collection.clone(); - let threads: &Vec<Container> = &mailbox.threads; - local_collection.sort_by(|a, b| match self.sort { - (SortField::Date, 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()]; - mb.date().cmp(&ma.date()) - } - (SortField::Date, 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()]; - ma.date().cmp(&mb.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 + let threads = &mailbox.threads; + threads.sort_by(self.sort, self.subsort, &mailbox.collection); + let containers: &Vec<Container> = &threads.containers(); + let mut iter = threads.into_iter().peekable(); + let len = threads + .threaded_collection() .len() .to_string() .chars() .count(); /* This is just a desugared for loop so that we can use .peek() */ - while let Some((idx, i)) = iter.next() { - let container = &threads[*i]; + let mut idx = 0; + while let Some(i) = iter.next() { + let container = &containers[i]; let indentation = container.indentation(); if indentation == 0 { thread_idx += 1; } - assert!(container.has_message()); + if !container.has_message() { + continue; + } + + match iter.peek() { - Some(&(_, x)) if threads[*x].indentation() == indentation => { + Some(&x) if threads[x].indentation() == indentation => { indentations.pop(); indentations.push(true); } @@ -234,16 +212,17 @@ impl MailListing { } match iter.peek() { - Some(&(_, x)) if threads[*x].indentation() > indentation => { + Some(&x) if containers[x].indentation() > indentation => { indentations.push(false); } - Some(&(_, x)) if threads[*x].indentation() < indentation => { - for _ in 0..(indentation - threads[*x].indentation()) { + Some(&x) if containers[x].indentation() < indentation => { + for _ in 0..(indentation - containers[x].indentation()) { indentations.pop(); } } _ => {} } + idx += 1; } } else { // Populate `CellBuffer` with every entry. @@ -255,6 +234,40 @@ impl MailListing { break; } /* Write an entire line for each envelope entry. */ + /* + self.local_collection = (0..mailbox.collection.len()).collect(); + let sort = self.sort; + self.local_collection.sort_by(|a, b| match sort { + (SortField::Date, 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()]; + mb.date().cmp(&ma.date()) + } + (SortField::Date, 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()]; + ma.date().cmp(&mb.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 envelope: &Envelope = &mailbox.collection[idx]; let fg_color = if !envelope.is_seen() { @@ -752,13 +765,21 @@ impl Component for MailListing { self.refresh_mailbox(context); return; } + Action::SubSort(field, order) => { + eprintln!("SubSort {:?} , {:?}", field, order); + self.subsort = (*field, *order); + self.dirty = true; + self.refresh_mailbox(context); + return; + } Action::Sort(field, order) => { - self.sort = (field.clone(), order.clone()); + eprintln!("Sort {:?} , {:?}", field, order); + self.sort = (*field, *order); self.dirty = true; self.refresh_mailbox(context); return; } - _ => {} + // _ => {} }, _ => {} } diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs index 021473ae..3fd12033 100644 --- a/ui/src/execute/actions.rs +++ b/ui/src/execute/actions.rs @@ -23,46 +23,13 @@ * User actions that need to be handled by the UI */ -use std::str::FromStr; +pub use melib::mailbox::{SortOrder, SortField}; #[derive(Debug, Clone)] pub enum MailListingAction { ToggleThreaded, } -#[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> { - 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> { - match s.trim() { - "asc" => Ok(SortOrder::Asc), - "desc" => Ok(SortOrder::Desc), - _ => Err(()), - } - } -} #[derive(Debug, Clone)] pub enum Action { |