summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2022-08-28 17:29:30 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2022-08-28 17:29:30 +0300
commitbde87af3877d4a0b071e331c93a07e0acf51bf7a (patch)
tree7864dc71c0eda03045b9ce6f7d54114b9b488b4b
parent10497952f718b49f3a247741a64361f855b2d4f7 (diff)
downloadmeli-bde87af3877d4a0b071e331c93a07e0acf51bf7a.zip
Refactor filter() method in Listing trait
-rw-r--r--src/components/mail/listing.rs2
-rw-r--r--src/components/mail/listing/compact.rs104
-rw-r--r--src/components/mail/listing/conversations.rs93
-rw-r--r--src/components/mail/listing/plain.rs81
-rw-r--r--src/components/mail/listing/thread.rs65
5 files changed, 178 insertions, 167 deletions
diff --git a/src/components/mail/listing.rs b/src/components/mail/listing.rs
index c9f894d1..3bdf9113 100644
--- a/src/components/mail/listing.rs
+++ b/src/components/mail/listing.rs
@@ -505,7 +505,7 @@ pub trait ListingTrait: Component {
fn filter(
&mut self,
_filter_term: String,
- _results: Result<SmallVec<[EnvelopeHash; 512]>>,
+ _results: SmallVec<[EnvelopeHash; 512]>,
_context: &Context,
) {
}
diff --git a/src/components/mail/listing/compact.rs b/src/components/mail/listing/compact.rs
index ab55248f..b2980727 100644
--- a/src/components/mail/listing/compact.rs
+++ b/src/components/mail/listing/compact.rs
@@ -768,7 +768,7 @@ impl ListingTrait for CompactListing {
fn filter(
&mut self,
filter_term: String,
- results: Result<SmallVec<[EnvelopeHash; 512]>>,
+ results: SmallVec<[EnvelopeHash; 512]>,
context: &Context,
) {
self.order.clear();
@@ -780,70 +780,41 @@ impl ListingTrait for CompactListing {
self.row_updates.clear();
let account = &context.accounts[&self.cursor_pos.0];
- match results {
- Ok(results) => {
- let threads = account.collection.get_threads(self.cursor_pos.1);
- for env_hash in results {
- if !account.collection.contains_key(&env_hash) {
- continue;
- }
- let env_thread_node_hash = account.collection.get_env(env_hash).thread();
- if !threads.thread_nodes.contains_key(&env_thread_node_hash) {
- continue;
- }
- let thread =
- threads.find_group(threads.thread_nodes[&env_thread_node_hash].group);
- if self.filtered_order.contains_key(&thread) {
- continue;
- }
- if self.all_threads.contains(&thread) {
- self.filtered_selection.push(thread);
- self.filtered_order
- .insert(thread, self.filtered_selection.len() - 1);
- }
- }
- if !self.filtered_selection.is_empty() {
- threads.group_inner_sort_by(
- &mut self.filtered_selection,
- self.sort,
- &context.accounts[&self.cursor_pos.0].collection.envelopes,
- );
- self.new_cursor_pos.2 =
- std::cmp::min(self.filtered_selection.len() - 1, self.cursor_pos.2);
- } else {
- self.data_columns.columns[0] =
- CellBuffer::new_with_context(0, 0, None, context);
- }
- self.redraw_threads_list(
- context,
- Box::new(self.filtered_selection.clone().into_iter())
- as Box<dyn Iterator<Item = ThreadHash>>,
- );
+ let threads = account.collection.get_threads(self.cursor_pos.1);
+ for env_hash in results {
+ if !account.collection.contains_key(&env_hash) {
+ continue;
}
- Err(e) => {
- self.cursor_pos.2 = 0;
- self.new_cursor_pos.2 = 0;
- let message = format!(
- "Encountered an error while searching for `{}`: {}.",
- &self.filter_term, e
- );
- log(
- format!("Failed to search for term {}: {}", &self.filter_term, e),
- ERROR,
- );
- self.data_columns.columns[0] =
- CellBuffer::new_with_context(message.len(), 1, None, context);
- write_string_to_grid(
- &message,
- &mut self.data_columns.columns[0],
- self.color_cache.theme_default.fg,
- self.color_cache.theme_default.bg,
- self.color_cache.theme_default.attrs,
- ((0, 0), (message.len() - 1, 0)),
- None,
- );
+ let env_thread_node_hash = account.collection.get_env(env_hash).thread();
+ if !threads.thread_nodes.contains_key(&env_thread_node_hash) {
+ continue;
+ }
+ let thread = threads.find_group(threads.thread_nodes[&env_thread_node_hash].group);
+ if self.filtered_order.contains_key(&thread) {
+ continue;
+ }
+ if self.all_threads.contains(&thread) {
+ self.filtered_selection.push(thread);
+ self.filtered_order
+ .insert(thread, self.filtered_selection.len() - 1);
}
}
+ if !self.filtered_selection.is_empty() {
+ threads.group_inner_sort_by(
+ &mut self.filtered_selection,
+ self.sort,
+ &context.accounts[&self.cursor_pos.0].collection.envelopes,
+ );
+ self.new_cursor_pos.2 =
+ std::cmp::min(self.filtered_selection.len() - 1, self.cursor_pos.2);
+ } else {
+ self.data_columns.columns[0] = CellBuffer::new_with_context(0, 0, None, context);
+ }
+ self.redraw_threads_list(
+ context,
+ Box::new(self.filtered_selection.clone().into_iter())
+ as Box<dyn Iterator<Item = ThreadHash>>,
+ );
}
fn unfocused(&self) -> bool {
@@ -2020,7 +1991,14 @@ impl Component for CompactListing {
match handle.chan.try_recv() {
Err(_) => { /* search was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
- Ok(Some(results)) => self.filter(filter_term, results, context),
+ Ok(Some(Ok(results))) => self.filter(filter_term, results, context),
+ Ok(Some(Err(err))) => {
+ context.replies.push_back(UIEvent::Notification(
+ Some("Could not perform search".to_string()),
+ err.to_string(),
+ Some(crate::types::NotificationType::Error(err.kind)),
+ ));
+ }
}
self.set_dirty(true);
}
diff --git a/src/components/mail/listing/conversations.rs b/src/components/mail/listing/conversations.rs
index b29b4324..51ce76e8 100644
--- a/src/components/mail/listing/conversations.rs
+++ b/src/components/mail/listing/conversations.rs
@@ -480,7 +480,7 @@ impl ListingTrait for ConversationsListing {
fn filter(
&mut self,
filter_term: String,
- results: Result<SmallVec<[EnvelopeHash; 512]>>,
+ results: SmallVec<[EnvelopeHash; 512]>,
context: &Context,
) {
if filter_term.is_empty() {
@@ -499,59 +499,41 @@ impl ListingTrait for ConversationsListing {
}
let account = &context.accounts[&self.cursor_pos.0];
- match results {
- Ok(results) => {
- let threads = account.collection.get_threads(self.cursor_pos.1);
- for env_hash in results {
- if !account.collection.contains_key(&env_hash) {
- continue;
- }
- let env_thread_node_hash = account.collection.get_env(env_hash).thread();
- if !threads.thread_nodes.contains_key(&env_thread_node_hash) {
- continue;
- }
- let thread =
- threads.find_group(threads.thread_nodes[&env_thread_node_hash].group);
- if self.filtered_order.contains_key(&thread) {
- continue;
- }
- if self.all_threads.contains(&thread) {
- self.filtered_selection.push(thread);
- self.filtered_order
- .insert(thread, self.filtered_selection.len().saturating_sub(1));
- }
- }
- if !self.filtered_selection.is_empty() {
- threads.group_inner_sort_by(
- &mut self.filtered_selection,
- self.sort,
- &context.accounts[&self.cursor_pos.0].collection.envelopes,
- );
- self.new_cursor_pos.2 = std::cmp::min(
- self.filtered_selection.len().saturating_sub(1),
- self.cursor_pos.2,
- );
- }
- self.redraw_threads_list(
- context,
- Box::new(self.filtered_selection.clone().into_iter())
- as Box<dyn Iterator<Item = ThreadHash>>,
- );
+ let threads = account.collection.get_threads(self.cursor_pos.1);
+ for env_hash in results {
+ if !account.collection.contains_key(&env_hash) {
+ continue;
}
- Err(e) => {
- self.cursor_pos.2 = 0;
- self.new_cursor_pos.2 = 0;
- let message = format!(
- "Encountered an error while searching for `{}`: {}.",
- self.filter_term, e
- );
- log(
- format!("Failed to search for term {}: {}", self.filter_term, e),
- ERROR,
- );
- self.rows = Err(message);
+ let env_thread_node_hash = account.collection.get_env(env_hash).thread();
+ if !threads.thread_nodes.contains_key(&env_thread_node_hash) {
+ continue;
}
+ let thread = threads.find_group(threads.thread_nodes[&env_thread_node_hash].group);
+ if self.filtered_order.contains_key(&thread) {
+ continue;
+ }
+ if self.all_threads.contains(&thread) {
+ self.filtered_selection.push(thread);
+ self.filtered_order
+ .insert(thread, self.filtered_selection.len().saturating_sub(1));
+ }
+ }
+ if !self.filtered_selection.is_empty() {
+ threads.group_inner_sort_by(
+ &mut self.filtered_selection,
+ self.sort,
+ &context.accounts[&self.cursor_pos.0].collection.envelopes,
+ );
+ self.new_cursor_pos.2 = std::cmp::min(
+ self.filtered_selection.len().saturating_sub(1),
+ self.cursor_pos.2,
+ );
}
+ self.redraw_threads_list(
+ context,
+ Box::new(self.filtered_selection.clone().into_iter())
+ as Box<dyn Iterator<Item = ThreadHash>>,
+ );
}
fn unfocused(&self) -> bool {
@@ -1438,7 +1420,14 @@ impl Component for ConversationsListing {
match handle.chan.try_recv() {
Err(_) => { /* search was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
- Ok(Some(results)) => self.filter(filter_term, results, context),
+ Ok(Some(Ok(results))) => self.filter(filter_term, results, context),
+ Ok(Some(Err(err))) => {
+ context.replies.push_back(UIEvent::Notification(
+ Some("Could not perform search".to_string()),
+ err.to_string(),
+ Some(crate::types::NotificationType::Error(err.kind)),
+ ));
+ }
}
self.set_dirty(true);
}
diff --git a/src/components/mail/listing/plain.rs b/src/components/mail/listing/plain.rs
index 8b5f38a5..84a41f38 100644
--- a/src/components/mail/listing/plain.rs
+++ b/src/components/mail/listing/plain.rs
@@ -595,7 +595,7 @@ impl ListingTrait for PlainListing {
fn filter(
&mut self,
filter_term: String,
- results: Result<SmallVec<[EnvelopeHash; 512]>>,
+ results: SmallVec<[EnvelopeHash; 512]>,
context: &Context,
) {
if filter_term.is_empty() {
@@ -614,58 +614,30 @@ impl ListingTrait for PlainListing {
}
let account = &context.accounts[&self.cursor_pos.0];
- match results {
- Ok(results) => {
- for env_hash in results {
- if !account.collection.contains_key(&env_hash) {
- continue;
- }
- if self.filtered_order.contains_key(&env_hash) {
- continue;
- }
- if self.all_envelopes.contains(&env_hash) {
- self.filtered_selection.push(env_hash);
- self.filtered_order
- .insert(env_hash, self.filtered_selection.len() - 1);
- }
- }
- if !self.filtered_selection.is_empty() {
- self.new_cursor_pos.2 =
- std::cmp::min(self.filtered_selection.len() - 1, self.cursor_pos.2);
- } else {
- self.data_columns.columns[0] =
- CellBuffer::new_with_context(0, 0, None, context);
- }
- self.redraw_list(
- context,
- Box::new(self.filtered_selection.clone().into_iter())
- as Box<dyn Iterator<Item = EnvelopeHash>>,
- );
+ for env_hash in results {
+ if !account.collection.contains_key(&env_hash) {
+ continue;
}
- Err(e) => {
- self.cursor_pos.2 = 0;
- self.new_cursor_pos.2 = 0;
- let message = format!(
- "Encountered an error while searching for `{}`: {}.",
- &self.filter_term, e
- );
- log(
- format!("Failed to search for term {}: {}", &self.filter_term, e),
- ERROR,
- );
- self.data_columns.columns[0] =
- CellBuffer::new_with_context(message.len(), 1, None, context);
- write_string_to_grid(
- &message,
- &mut self.data_columns.columns[0],
- self.color_cache.theme_default.fg,
- self.color_cache.theme_default.bg,
- self.color_cache.theme_default.attrs,
- ((0, 0), (message.len() - 1, 0)),
- None,
- );
+ if self.filtered_order.contains_key(&env_hash) {
+ continue;
+ }
+ if self.all_envelopes.contains(&env_hash) {
+ self.filtered_selection.push(env_hash);
+ self.filtered_order
+ .insert(env_hash, self.filtered_selection.len() - 1);
}
}
+ if !self.filtered_selection.is_empty() {
+ self.new_cursor_pos.2 =
+ std::cmp::min(self.filtered_selection.len() - 1, self.cursor_pos.2);
+ } else {
+ self.data_columns.columns[0] = CellBuffer::new_with_context(0, 0, None, context);
+ }
+ self.redraw_list(
+ context,
+ Box::new(self.filtered_selection.clone().into_iter())
+ as Box<dyn Iterator<Item = EnvelopeHash>>,
+ );
}
fn unfocused(&self) -> bool {
@@ -1402,7 +1374,14 @@ impl Component for PlainListing {
match handle.chan.try_recv() {
Err(_) => { /* search was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
- Ok(Some(results)) => self.filter(filter_term, results, context),
+ Ok(Some(Ok(results))) => self.filter(filter_term, results, context),
+ Ok(Some(Err(err))) => {
+ context.replies.push_back(UIEvent::Notification(
+ Some("Could not perform search".to_string()),
+ err.to_string(),
+ Some(crate::types::NotificationType::Error(err.kind)),
+ ));
+ }
}
self.set_dirty(true);
}
diff --git a/src/components/mail/listing/thread.rs b/src/components/mail/listing/thread.rs
index 44fe2b63..029a0408 100644
--- a/src/components/mail/listing/thread.rs
+++ b/src/components/mail/listing/thread.rs
@@ -113,6 +113,12 @@ pub struct ThreadListing {
/// Cache current view.
color_cache: ColorCache,
+ #[allow(clippy::type_complexity)]
+ search_job: Option<(
+ String,
+ crate::jobs::JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>,
+ )>,
+
data_columns: DataColumns,
rows_drawn: SegmentTree,
rows: Vec<((usize, bool, bool, EnvelopeHash), EntryStrings)>,
@@ -721,6 +727,19 @@ impl ListingTrait for ThreadListing {
}
}
+ fn filter(
+ &mut self,
+ filter_term: String,
+ _results: SmallVec<[EnvelopeHash; 512]>,
+ context: &Context,
+ ) {
+ if filter_term.is_empty() {
+ return;
+ }
+
+ let _account = &context.accounts[&self.cursor_pos.0];
+ }
+
fn unfocused(&self) -> bool {
self.unfocused
}
@@ -758,6 +777,7 @@ impl ThreadListing {
initialised: false,
movement: None,
id: ComponentId::new_v4(),
+ search_job: None,
})
}
@@ -1308,8 +1328,53 @@ impl Component for ThreadListing {
self.refresh_mailbox(context, false);
return true;
}
+ Action::Listing(Search(ref filter_term)) if !self.unfocused => {
+ match context.accounts[&self.cursor_pos.0].search(
+ filter_term,
+ self.sort,
+ self.cursor_pos.1,
+ ) {
+ Ok(job) => {
+ let handle = context.accounts[&self.cursor_pos.0]
+ .job_executor
+ .spawn_specialized(job);
+ self.search_job = Some((filter_term.to_string(), handle));
+ }
+ Err(err) => {
+ context.replies.push_back(UIEvent::Notification(
+ Some("Could not perform search".to_string()),
+ err.to_string(),
+ Some(crate::types::NotificationType::Error(err.kind)),
+ ));
+ }
+ };
+ self.set_dirty(true);
+ return true;
+ }
_ => {}
},
+ UIEvent::StatusEvent(StatusEvent::JobFinished(ref job_id))
+ if self
+ .search_job
+ .as_ref()
+ .map(|(_, j)| j == job_id)
+ .unwrap_or(false) =>
+ {
+ let (filter_term, mut handle) = self.search_job.take().unwrap();
+ match handle.chan.try_recv() {
+ Err(_) => { /* search was canceled */ }
+ Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
+ Ok(Some(Ok(results))) => self.filter(filter_term, results, context),
+ Ok(Some(Err(err))) => {
+ context.replies.push_back(UIEvent::Notification(
+ Some("Could not perform search".to_string()),
+ err.to_string(),
+ Some(crate::types::NotificationType::Error(err.kind)),
+ ));
+ }
+ }
+ self.set_dirty(true);
+ }
_ => {}
}
false