From adaeba1a907dfee5f33afe832e9e9a7e9f59b1f2 Mon Sep 17 00:00:00 2001 From: lukeflo Date: Sun, 29 Sep 2024 22:46:58 +0200 Subject: implemented search mode (for entries only ATM) --- src/frontend/app.rs | 38 +++++++++++++--- src/frontend/handler.rs | 12 ++++- src/frontend/ui.rs | 113 ++++++++++++++++++++++++++++++------------------ 3 files changed, 113 insertions(+), 50 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/app.rs b/src/frontend/app.rs index 75a6ede..970a064 100644 --- a/src/frontend/app.rs +++ b/src/frontend/app.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . ///// -use crate::backend::bib::*; +use crate::backend::{bib::*, search}; use std::error; use arboard::Clipboard; @@ -39,6 +39,7 @@ pub enum CurrentArea { pub enum FormerArea { EntryArea, TagArea, + SearchArea, } // Application. @@ -211,13 +212,20 @@ impl App { // Toggle moveable list between entries and tags pub fn toggle_area(&mut self) { match self.current_area { - CurrentArea::EntryArea => self.current_area = CurrentArea::TagArea, - CurrentArea::TagArea => self.current_area = CurrentArea::EntryArea, + CurrentArea::EntryArea => { + self.current_area = CurrentArea::TagArea; + self.tag_list.tag_list_state.select(Some(0)) + } + CurrentArea::TagArea => { + self.current_area = CurrentArea::EntryArea; + self.tag_list.tag_list_state.select(None) + } CurrentArea::SearchArea => { if let Some(former_area) = &self.former_area { match former_area { FormerArea::EntryArea => self.current_area = CurrentArea::EntryArea, FormerArea::TagArea => self.current_area = CurrentArea::TagArea, + _ => {} } } } @@ -226,6 +234,7 @@ impl App { match former_area { FormerArea::EntryArea => self.current_area = CurrentArea::EntryArea, FormerArea::TagArea => self.current_area = CurrentArea::TagArea, + FormerArea::SearchArea => self.current_area = CurrentArea::SearchArea, } } } @@ -273,9 +282,11 @@ impl App { } pub fn select_first(&mut self) { - self.scroll_info = 0; match self.current_area { - CurrentArea::EntryArea => self.entry_table.entry_table_state.select_first(), + CurrentArea::EntryArea => { + self.scroll_info = 0; + self.entry_table.entry_table_state.select_first(); + } CurrentArea::TagArea => self.tag_list.tag_list_state.select_first(), _ => {} } @@ -283,9 +294,11 @@ impl App { } pub fn select_last(&mut self) { - self.scroll_info = 0; match self.current_area { - CurrentArea::EntryArea => self.entry_table.entry_table_state.select_last(), + CurrentArea::EntryArea => { + self.scroll_info = 0; + self.entry_table.entry_table_state.select_last(); + } CurrentArea::TagArea => self.tag_list.tag_list_state.select_last(), _ => {} } @@ -305,4 +318,15 @@ impl App { let yanked_text = selection.to_string(); clipboard.set_text(yanked_text).unwrap(); } + + // Search entry list + pub fn search_entries(&mut self) { + let orig_list = &self.biblio_data.entry_list.bibentries; + let filtered_list = search::search_entry_list(&self.search_string, orig_list.clone()); + self.entry_table = EntryTable::from_iter(filtered_list) + } + + pub fn reset_entry_table(&mut self) { + self.entry_table = EntryTable::from_iter(self.biblio_data.entry_list.bibentries.clone()) + } } diff --git a/src/frontend/handler.rs b/src/frontend/handler.rs index 27aa8de..573795c 100644 --- a/src/frontend/handler.rs +++ b/src/frontend/handler.rs @@ -18,7 +18,7 @@ use crate::frontend::app::{App, AppResult}; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; -use super::app::{CurrentArea, FormerArea}; +use super::app::{CurrentArea, EntryTable, FormerArea}; /// Handles the key events and updates the state of [`App`]. pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { @@ -97,6 +97,11 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { KeyCode::Tab | KeyCode::BackTab => { app.toggle_area(); } + KeyCode::Esc => { + if let Some(FormerArea::SearchArea) = app.former_area { + app.reset_entry_table(); + } + } _ => {} }, // Keycodes for the search area (popup) @@ -105,18 +110,21 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { app.toggle_area(); app.former_area = None; app.search_string.clear(); + app.reset_entry_table(); } KeyCode::Enter => { // TODO: run function for filtering the list app.toggle_area(); - app.former_area = None; + app.former_area = Some(FormerArea::SearchArea); app.search_string.clear(); } KeyCode::Backspace => { app.search_string.pop(); + app.search_entries(); } KeyCode::Char(search_pattern) => { app.search_string.push(search_pattern); + app.search_entries(); } _ => {} }, diff --git a/src/frontend/ui.rs b/src/frontend/ui.rs index 0e44e5c..5ca7100 100644 --- a/src/frontend/ui.rs +++ b/src/frontend/ui.rs @@ -15,6 +15,7 @@ // along with this program. If not, see . ///// +use futures::SinkExt; use ratatui::{ buffer::Buffer, layout::{Constraint, Layout, Rect}, @@ -35,7 +36,7 @@ use crate::{ frontend::app::{App, TagListItem}, }; -use super::app::CurrentArea; +use super::app::{CurrentArea, FormerArea}; const MAIN_BLUE_COLOR: Color = Color::Indexed(39); const MAIN_PURPLE_COLOR: Color = Color::Indexed(129); @@ -47,6 +48,7 @@ const SELECTED_STYLE: Style = Style::new() .add_modifier(Modifier::BOLD) .add_modifier(Modifier::REVERSED); const TEXT_FG_COLOR: Color = SLATE.c200; +const TEXT_CONFIRMED: Style = Style::new().fg(Color::Green); pub const fn alternate_colors(i: usize) -> Color { if i % 2 == 0 { @@ -109,8 +111,25 @@ impl App { pub fn render_footer(&mut self, area: Rect, buf: &mut Buffer) { match &self.current_area { CurrentArea::SearchArea => { + let search_title = { + match self.former_area { + Some(FormerArea::EntryArea) => { + let search_title = " Search Entries ".to_string(); + search_title + } + Some(FormerArea::TagArea) => { + let search_title = " Search Keywords ".to_string(); + search_title + } + _ => { + let search_title = " Search ".to_string(); + search_title + } + } + }; + let block = Block::bordered() - .title(" Search Entries ") + .title(search_title) .border_set(symbols::border::ROUNDED); Paragraph::new(self.search_string.clone()) .block(block) @@ -196,45 +215,57 @@ impl App { // We get the info depending on the item's state. // TODO: Implement logic showin informations for selected entry: let style_value = Style::new().bold(); - let mut lines = vec![]; - lines.push(Line::from(vec![ - Span::styled("Authors: ", style_value), - Span::styled( - String::from(BibiEntry::get_authors( - &self.get_selected_citekey(), - &self.main_biblio.bibliography, - )), - Style::new().green(), - ), - ])); - lines.push(Line::from(vec![ - Span::styled("Title: ", style_value), - Span::styled( - String::from(BibiEntry::get_title( - &self.get_selected_citekey(), - &self.main_biblio.bibliography, - )), - Style::new().magenta(), - ), - ])); - lines.push(Line::from(vec![ - Span::styled("Year: ", style_value), - Span::styled( - String::from(BibiEntry::get_year( - &self.get_selected_citekey(), - &self.main_biblio.bibliography, - )), - Style::new().light_magenta(), - ), - ])); - lines.push(Line::from("")); - lines.push(Line::from(vec![Span::styled( - String::from(BibiEntry::get_abstract( - &self.get_selected_citekey(), - &self.main_biblio.bibliography, - )), - Style::default(), - )])); + let lines = { + // if self.entry_table.entry_table_items.len() > 0 { + if self.entry_table.entry_table_state.selected().is_some() { + let mut lines = vec![]; + lines.push(Line::from(vec![ + Span::styled("Authors: ", style_value), + Span::styled( + String::from(BibiEntry::get_authors( + &self.get_selected_citekey(), + &self.main_biblio.bibliography, + )), + Style::new().green(), + ), + ])); + lines.push(Line::from(vec![ + Span::styled("Title: ", style_value), + Span::styled( + String::from(BibiEntry::get_title( + &self.get_selected_citekey(), + &self.main_biblio.bibliography, + )), + Style::new().magenta(), + ), + ])); + lines.push(Line::from(vec![ + Span::styled("Year: ", style_value), + Span::styled( + String::from(BibiEntry::get_year( + &self.get_selected_citekey(), + &self.main_biblio.bibliography, + )), + Style::new().light_magenta(), + ), + ])); + lines.push(Line::from("")); + lines.push(Line::from(vec![Span::styled( + String::from(BibiEntry::get_abstract( + &self.get_selected_citekey(), + &self.main_biblio.bibliography, + )), + Style::default(), + )])); + lines + } else { + let lines = vec![ + Line::from(" "), + Line::from("No entry selected".bold().into_centered_line().red()), + ]; + lines + } + }; let info = Text::from(lines); // We show the list item's info under the list in this paragraph -- cgit v1.2.3