From 64b7b2cc83b611965c34bb2bad6111803f495a8d Mon Sep 17 00:00:00 2001 From: wallentx Date: Sun, 8 Feb 2026 02:00:56 -0600 Subject: [PATCH 1/2] feat(ui): Improve mailing list filtering and display --- src/app/screens/mail_list.rs | 11 +++++++- src/ui/edit_config.rs | 4 +-- src/ui/latest.rs | 2 +- src/ui/mail_list.rs | 52 ++++++++++++++++-------------------- 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/app/screens/mail_list.rs b/src/app/screens/mail_list.rs index 52d49f7f..26037d2d 100644 --- a/src/app/screens/mail_list.rs +++ b/src/app/screens/mail_list.rs @@ -48,10 +48,19 @@ impl MailingListSelection { } fn process_possible_mailing_lists(&mut self) { + if self.target_list.is_empty() { + self.possible_mailing_lists = self.mailing_lists.clone(); + self.highlighted_list_index = 0; + return; + } + + let query = self.target_list.to_lowercase(); let mut possible_mailing_lists: Vec = Vec::new(); for mailing_list in &self.mailing_lists { - if mailing_list.name().starts_with(&self.target_list) { + if mailing_list.name().to_lowercase().contains(&query) + || mailing_list.description().to_lowercase().contains(&query) + { possible_mailing_lists.push(mailing_list.clone()); } } diff --git a/src/ui/edit_config.rs b/src/ui/edit_config.rs index 88b5a57d..ca14fa6a 100644 --- a/src/ui/edit_config.rs +++ b/src/ui/edit_config.rs @@ -64,7 +64,7 @@ pub fn render_main(f: &mut Frame, app: &App, chunk: Rect) { } } -pub fn mode_footer_text(app: &App) -> Vec { +pub fn mode_footer_text(app: &App) -> Vec> { let edit_config_state = app.edit_config.as_ref().unwrap(); vec![if edit_config_state.is_editing() { Span::styled("Editing...", Style::default().fg(Color::LightYellow)) @@ -73,7 +73,7 @@ pub fn mode_footer_text(app: &App) -> Vec { }] } -pub fn keys_hint(app: &App) -> Span { +pub fn keys_hint(app: &App) -> Span<'_> { let edit_config_state = app.edit_config.as_ref().unwrap(); match edit_config_state.is_editing() { true => Span::styled( diff --git a/src/ui/latest.rs b/src/ui/latest.rs index 4288543c..6cb7ee6b 100644 --- a/src/ui/latest.rs +++ b/src/ui/latest.rs @@ -67,7 +67,7 @@ pub fn render_main(f: &mut Frame, app: &App, chunk: Rect) { f.render_stateful_widget(list, chunk, &mut list_state); } -pub fn mode_footer_text(app: &App) -> Vec { +pub fn mode_footer_text(app: &App) -> Vec> { vec![Span::styled( format!( "Latest Patchsets from {} (page {})", diff --git a/src/ui/mail_list.rs b/src/ui/mail_list.rs index 16686db1..bd81c84b 100644 --- a/src/ui/mail_list.rs +++ b/src/ui/mail_list.rs @@ -50,39 +50,33 @@ pub fn render_main(f: &mut Frame, app: &App, chunk: Rect) { f.render_stateful_widget(list, chunk, &mut list_state); } -pub fn mode_footer_text(app: &App) -> Vec { - let mut text_area = Span::default(); - - if app.mailing_list_selection.target_list.is_empty() { - text_area = Span::styled("type the target list", Style::default().fg(Color::DarkGray)) +pub fn mode_footer_text(app: &App) -> Vec> { + let text_area = if app.mailing_list_selection.target_list.is_empty() { + Span::styled("type the target list", Style::default().fg(Color::DarkGray)) } else { - for mailing_list in &app.mailing_list_selection.mailing_lists { - if mailing_list - .name() - .eq(&app.mailing_list_selection.target_list) - { - text_area = Span::styled( - &app.mailing_list_selection.target_list, - Style::default().fg(Color::Green), - ); - break; - } else if mailing_list - .name() - .starts_with(&app.mailing_list_selection.target_list) - { - text_area = Span::styled( - &app.mailing_list_selection.target_list, - Style::default().fg(Color::LightCyan), - ); - } - } - if text_area.content.is_empty() { - text_area = Span::styled( + let exact_match = app + .mailing_list_selection + .mailing_lists + .iter() + .any(|ml| ml.name() == &app.mailing_list_selection.target_list); + + if exact_match { + Span::styled( + &app.mailing_list_selection.target_list, + Style::default().fg(Color::Green), + ) + } else if !app.mailing_list_selection.possible_mailing_lists.is_empty() { + Span::styled( + &app.mailing_list_selection.target_list, + Style::default().fg(Color::LightCyan), + ) + } else { + Span::styled( &app.mailing_list_selection.target_list, Style::default().fg(Color::Red), - ); + ) } - } + }; vec![ Span::styled("Target List: ", Style::default().fg(Color::Green)), From e7df90761b40da84caaf5eac834f7a3ba45552e9 Mon Sep 17 00:00:00 2001 From: wallentx Date: Sun, 8 Feb 2026 02:45:09 -0600 Subject: [PATCH 2/2] feat: Prioritize exact matches in mailing list selection --- src/app/screens/mail_list.rs | 20 ++++++++++++++------ src/ui/mail_list.rs | 9 ++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/app/screens/mail_list.rs b/src/app/screens/mail_list.rs index 26037d2d..645fb345 100644 --- a/src/app/screens/mail_list.rs +++ b/src/app/screens/mail_list.rs @@ -55,17 +55,25 @@ impl MailingListSelection { } let query = self.target_list.to_lowercase(); - let mut possible_mailing_lists: Vec = Vec::new(); + let mut exact_matches: Vec = Vec::new(); + let mut partial_matches: Vec = Vec::new(); for mailing_list in &self.mailing_lists { - if mailing_list.name().to_lowercase().contains(&query) - || mailing_list.description().to_lowercase().contains(&query) - { - possible_mailing_lists.push(mailing_list.clone()); + let name_lower = mailing_list.name().to_lowercase(); + let desc_lower = mailing_list.description().to_lowercase(); + + // Check for exact match first (case-insensitive) + if name_lower == query { + exact_matches.push(mailing_list.clone()); + } else if name_lower.contains(&query) || desc_lower.contains(&query) { + partial_matches.push(mailing_list.clone()); } } - self.possible_mailing_lists = possible_mailing_lists; + // Prioritize exact matches by placing them first + let mut all_matches = exact_matches; + all_matches.append(&mut partial_matches); + self.possible_mailing_lists = all_matches; self.highlighted_list_index = 0; } diff --git a/src/ui/mail_list.rs b/src/ui/mail_list.rs index bd81c84b..429c56e6 100644 --- a/src/ui/mail_list.rs +++ b/src/ui/mail_list.rs @@ -54,11 +54,10 @@ pub fn mode_footer_text(app: &App) -> Vec> { let text_area = if app.mailing_list_selection.target_list.is_empty() { Span::styled("type the target list", Style::default().fg(Color::DarkGray)) } else { - let exact_match = app - .mailing_list_selection - .mailing_lists - .iter() - .any(|ml| ml.name() == &app.mailing_list_selection.target_list); + let exact_match = app.mailing_list_selection.mailing_lists.iter().any(|ml| { + ml.name() + .eq_ignore_ascii_case(&app.mailing_list_selection.target_list) + }); if exact_match { Span::styled(