Refactor filter() method in Listing trait
parent
10497952f7
commit
bde87af387
|
@ -505,7 +505,7 @@ pub trait ListingTrait: Component {
|
||||||
fn filter(
|
fn filter(
|
||||||
&mut self,
|
&mut self,
|
||||||
_filter_term: String,
|
_filter_term: String,
|
||||||
_results: Result<SmallVec<[EnvelopeHash; 512]>>,
|
_results: SmallVec<[EnvelopeHash; 512]>,
|
||||||
_context: &Context,
|
_context: &Context,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -768,7 +768,7 @@ impl ListingTrait for CompactListing {
|
||||||
fn filter(
|
fn filter(
|
||||||
&mut self,
|
&mut self,
|
||||||
filter_term: String,
|
filter_term: String,
|
||||||
results: Result<SmallVec<[EnvelopeHash; 512]>>,
|
results: SmallVec<[EnvelopeHash; 512]>,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
) {
|
) {
|
||||||
self.order.clear();
|
self.order.clear();
|
||||||
|
@ -780,70 +780,41 @@ impl ListingTrait for CompactListing {
|
||||||
self.row_updates.clear();
|
self.row_updates.clear();
|
||||||
|
|
||||||
let account = &context.accounts[&self.cursor_pos.0];
|
let account = &context.accounts[&self.cursor_pos.0];
|
||||||
match results {
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
Ok(results) => {
|
for env_hash in results {
|
||||||
let threads = account.collection.get_threads(self.cursor_pos.1);
|
if !account.collection.contains_key(&env_hash) {
|
||||||
for env_hash in results {
|
continue;
|
||||||
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>>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
let env_thread_node_hash = account.collection.get_env(env_hash).thread();
|
||||||
self.cursor_pos.2 = 0;
|
if !threads.thread_nodes.contains_key(&env_thread_node_hash) {
|
||||||
self.new_cursor_pos.2 = 0;
|
continue;
|
||||||
let message = format!(
|
}
|
||||||
"Encountered an error while searching for `{}`: {}.",
|
let thread = threads.find_group(threads.thread_nodes[&env_thread_node_hash].group);
|
||||||
&self.filter_term, e
|
if self.filtered_order.contains_key(&thread) {
|
||||||
);
|
continue;
|
||||||
log(
|
}
|
||||||
format!("Failed to search for term {}: {}", &self.filter_term, e),
|
if self.all_threads.contains(&thread) {
|
||||||
ERROR,
|
self.filtered_selection.push(thread);
|
||||||
);
|
self.filtered_order
|
||||||
self.data_columns.columns[0] =
|
.insert(thread, self.filtered_selection.len() - 1);
|
||||||
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_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 {
|
fn unfocused(&self) -> bool {
|
||||||
|
@ -2020,7 +1991,14 @@ impl Component for CompactListing {
|
||||||
match handle.chan.try_recv() {
|
match handle.chan.try_recv() {
|
||||||
Err(_) => { /* search was canceled */ }
|
Err(_) => { /* search was canceled */ }
|
||||||
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
|
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);
|
self.set_dirty(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,7 +480,7 @@ impl ListingTrait for ConversationsListing {
|
||||||
fn filter(
|
fn filter(
|
||||||
&mut self,
|
&mut self,
|
||||||
filter_term: String,
|
filter_term: String,
|
||||||
results: Result<SmallVec<[EnvelopeHash; 512]>>,
|
results: SmallVec<[EnvelopeHash; 512]>,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
) {
|
) {
|
||||||
if filter_term.is_empty() {
|
if filter_term.is_empty() {
|
||||||
|
@ -499,59 +499,41 @@ impl ListingTrait for ConversationsListing {
|
||||||
}
|
}
|
||||||
|
|
||||||
let account = &context.accounts[&self.cursor_pos.0];
|
let account = &context.accounts[&self.cursor_pos.0];
|
||||||
match results {
|
let threads = account.collection.get_threads(self.cursor_pos.1);
|
||||||
Ok(results) => {
|
for env_hash in results {
|
||||||
let threads = account.collection.get_threads(self.cursor_pos.1);
|
if !account.collection.contains_key(&env_hash) {
|
||||||
for env_hash in results {
|
continue;
|
||||||
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>>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
let env_thread_node_hash = account.collection.get_env(env_hash).thread();
|
||||||
self.cursor_pos.2 = 0;
|
if !threads.thread_nodes.contains_key(&env_thread_node_hash) {
|
||||||
self.new_cursor_pos.2 = 0;
|
continue;
|
||||||
let message = format!(
|
}
|
||||||
"Encountered an error while searching for `{}`: {}.",
|
let thread = threads.find_group(threads.thread_nodes[&env_thread_node_hash].group);
|
||||||
self.filter_term, e
|
if self.filtered_order.contains_key(&thread) {
|
||||||
);
|
continue;
|
||||||
log(
|
}
|
||||||
format!("Failed to search for term {}: {}", self.filter_term, e),
|
if self.all_threads.contains(&thread) {
|
||||||
ERROR,
|
self.filtered_selection.push(thread);
|
||||||
);
|
self.filtered_order
|
||||||
self.rows = Err(message);
|
.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 {
|
fn unfocused(&self) -> bool {
|
||||||
|
@ -1438,7 +1420,14 @@ impl Component for ConversationsListing {
|
||||||
match handle.chan.try_recv() {
|
match handle.chan.try_recv() {
|
||||||
Err(_) => { /* search was canceled */ }
|
Err(_) => { /* search was canceled */ }
|
||||||
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
|
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);
|
self.set_dirty(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,7 +595,7 @@ impl ListingTrait for PlainListing {
|
||||||
fn filter(
|
fn filter(
|
||||||
&mut self,
|
&mut self,
|
||||||
filter_term: String,
|
filter_term: String,
|
||||||
results: Result<SmallVec<[EnvelopeHash; 512]>>,
|
results: SmallVec<[EnvelopeHash; 512]>,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
) {
|
) {
|
||||||
if filter_term.is_empty() {
|
if filter_term.is_empty() {
|
||||||
|
@ -614,58 +614,30 @@ impl ListingTrait for PlainListing {
|
||||||
}
|
}
|
||||||
|
|
||||||
let account = &context.accounts[&self.cursor_pos.0];
|
let account = &context.accounts[&self.cursor_pos.0];
|
||||||
match results {
|
for env_hash in results {
|
||||||
Ok(results) => {
|
if !account.collection.contains_key(&env_hash) {
|
||||||
for env_hash in results {
|
continue;
|
||||||
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>>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
if self.filtered_order.contains_key(&env_hash) {
|
||||||
self.cursor_pos.2 = 0;
|
continue;
|
||||||
self.new_cursor_pos.2 = 0;
|
}
|
||||||
let message = format!(
|
if self.all_envelopes.contains(&env_hash) {
|
||||||
"Encountered an error while searching for `{}`: {}.",
|
self.filtered_selection.push(env_hash);
|
||||||
&self.filter_term, e
|
self.filtered_order
|
||||||
);
|
.insert(env_hash, self.filtered_selection.len() - 1);
|
||||||
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_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 {
|
fn unfocused(&self) -> bool {
|
||||||
|
@ -1402,7 +1374,14 @@ impl Component for PlainListing {
|
||||||
match handle.chan.try_recv() {
|
match handle.chan.try_recv() {
|
||||||
Err(_) => { /* search was canceled */ }
|
Err(_) => { /* search was canceled */ }
|
||||||
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
|
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);
|
self.set_dirty(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,12 @@ pub struct ThreadListing {
|
||||||
/// Cache current view.
|
/// Cache current view.
|
||||||
color_cache: ColorCache,
|
color_cache: ColorCache,
|
||||||
|
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
search_job: Option<(
|
||||||
|
String,
|
||||||
|
crate::jobs::JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>,
|
||||||
|
)>,
|
||||||
|
|
||||||
data_columns: DataColumns,
|
data_columns: DataColumns,
|
||||||
rows_drawn: SegmentTree,
|
rows_drawn: SegmentTree,
|
||||||
rows: Vec<((usize, bool, bool, EnvelopeHash), EntryStrings)>,
|
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 {
|
fn unfocused(&self) -> bool {
|
||||||
self.unfocused
|
self.unfocused
|
||||||
}
|
}
|
||||||
|
@ -758,6 +777,7 @@ impl ThreadListing {
|
||||||
initialised: false,
|
initialised: false,
|
||||||
movement: None,
|
movement: None,
|
||||||
id: ComponentId::new_v4(),
|
id: ComponentId::new_v4(),
|
||||||
|
search_job: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1308,8 +1328,53 @@ impl Component for ThreadListing {
|
||||||
self.refresh_mailbox(context, false);
|
self.refresh_mailbox(context, false);
|
||||||
return true;
|
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
|
false
|
||||||
|
|
Loading…
Reference in New Issue