Refactor filter() method in Listing trait
parent
10497952f7
commit
bde87af387
|
@ -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,
|
||||
) {
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue