aboutsummaryrefslogtreecommitdiff
path: root/src/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/app.rs86
-rw-r--r--src/frontend/handler.rs52
-rw-r--r--src/frontend/ui.rs30
3 files changed, 112 insertions, 56 deletions
diff --git a/src/frontend/app.rs b/src/frontend/app.rs
index 1105901..ed0318f 100644
--- a/src/frontend/app.rs
+++ b/src/frontend/app.rs
@@ -15,7 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
-use crate::backend::{bib::*, search};
+use crate::backend::{bib::*, search::BibiSearch};
use std::error;
use arboard::Clipboard;
@@ -51,6 +51,8 @@ pub struct App {
pub main_biblio: BibiMain,
// bibliographic data
pub biblio_data: BibiData,
+ // search struct:
+ pub search_struct: BibiSearch,
// tag list
pub tag_list: TagList,
// table items
@@ -62,7 +64,7 @@ pub struct App {
// mode for popup window
pub former_area: Option<FormerArea>,
// search string
- pub search_string: String,
+ // pub search_string: String,
}
// Define the fundamental List
@@ -75,14 +77,14 @@ pub struct TagList {
// Structure of the list items.
#[derive(Debug)]
pub struct TagListItem {
- pub info: String,
+ pub keyword: String,
}
// Function to process inputed characters and convert them (to string, or more complex function)
impl TagListItem {
pub fn new(info: &str) -> Self {
Self {
- info: info.to_string(),
+ keyword: info.to_string(),
}
}
}
@@ -107,7 +109,7 @@ impl FromIterator<Vec<String>> for EntryTable {
let entry_table_items = iter
.into_iter()
.sorted()
- .map(|i| EntryTableItem::new(&i[0], &i[1], &i[2], &i[3], &i[4]))
+ .map(|i| EntryTableItem::new(&i[0], &i[1], &i[2], &i[3], &i[4], &i[5]))
.collect();
let entry_table_state = TableState::default().with_selected(0);
Self {
@@ -131,17 +133,26 @@ pub struct EntryTableItem {
pub title: String,
pub year: String,
pub pubtype: String,
+ pub keywords: String,
pub citekey: String,
// pub year: u16,
}
impl EntryTableItem {
- pub fn new(authors: &str, title: &str, year: &str, pubtype: &str, citekey: &str) -> Self {
+ pub fn new(
+ authors: &str,
+ title: &str,
+ year: &str,
+ pubtype: &str,
+ keywords: &str,
+ citekey: &str,
+ ) -> Self {
Self {
authors: authors.to_string(),
title: title.to_string(),
year: year.to_string(),
pubtype: pubtype.to_string(),
+ keywords: keywords.to_string(),
citekey: citekey.to_string(),
}
}
@@ -178,7 +189,8 @@ impl Default for App {
let running = true;
let main_biblio = BibiMain::new();
let biblio_data = BibiData::new(&main_biblio.bibliography, &main_biblio.citekeys);
- let tag_list = TagList::from_iter(main_biblio.citekeys.clone());
+ let tag_list = TagList::from_iter(main_biblio.keyword_list.clone());
+ let search_struct = BibiSearch::default();
let entry_table = EntryTable::from_iter(biblio_data.entry_list.bibentries.clone());
let current_area = CurrentArea::EntryArea;
Self {
@@ -186,11 +198,12 @@ impl Default for App {
main_biblio,
biblio_data,
tag_list,
+ search_struct,
entry_table,
scroll_info: 0,
current_area,
former_area: None,
- search_string: String::new(),
+ // search_string: String::new(),
}
}
}
@@ -290,8 +303,40 @@ impl App {
self.tag_list.tag_list_state.select_last();
}
+ pub fn get_selected_tag(&self) -> &str {
+ let idx = self.tag_list.tag_list_state.selected().unwrap();
+ let keyword = &self.tag_list.tag_list_items[idx].keyword;
+ keyword
+ }
+
+ pub fn search_tags(&mut self) {
+ let orig_list = &self.main_biblio.keyword_list;
+ let filtered_list =
+ BibiSearch::search_tag_list(&self.search_struct.search_string, orig_list.clone());
+ self.tag_list = TagList::from_iter(filtered_list)
+ }
+
pub fn reset_taglist(&mut self) {
- self.tag_list = TagList::from_iter(self.main_biblio.citekeys.clone())
+ self.tag_list = TagList::from_iter(self.main_biblio.keyword_list.clone())
+ }
+
+ // Filter the entry list by tags
+ // If already inside a filtered tag or entry list, apply the filtering
+ // to the already filtered list only
+ pub fn filter_for_tags(&mut self) {
+ let orig_list = {
+ if self.search_struct.inner_search {
+ let orig_list = &self.search_struct.filtered_entry_list;
+ orig_list
+ } else {
+ let orig_list = &self.biblio_data.entry_list.bibentries;
+ orig_list
+ }
+ };
+ let keyword = self.get_selected_tag();
+ let filtered_list = BibiSearch::filter_entries_by_tag(&keyword, &orig_list);
+ self.search_struct.filtered_entry_list = filtered_list;
+ self.entry_table = EntryTable::from_iter(self.search_struct.filtered_entry_list.clone());
}
// Entry Table commands
@@ -331,19 +376,18 @@ impl App {
// Search entry list
pub fn search_entries(&mut self) {
- match self.former_area {
- Some(FormerArea::EntryArea) => {
+ let orig_list = {
+ if self.search_struct.inner_search {
+ let orig_list = &self.search_struct.filtered_entry_list;
+ orig_list
+ } else {
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)
- }
- Some(FormerArea::TagArea) => {
- let orig_list = &self.main_biblio.citekeys;
- let filtered_list = search::search_tag_list(&self.search_string, orig_list.clone());
- self.tag_list = TagList::from_iter(filtered_list)
+ orig_list
}
- _ => {}
- }
+ };
+ let filtered_list =
+ BibiSearch::search_entry_list(&mut self.search_struct.search_string, orig_list.clone());
+ //search::search_entry_list(&self.search_string, orig_list.clone());
+ self.entry_table = EntryTable::from_iter(filtered_list)
}
}
diff --git a/src/frontend/handler.rs b/src/frontend/handler.rs
index c3eeed5..cdbd981 100644
--- a/src/frontend/handler.rs
+++ b/src/frontend/handler.rs
@@ -15,10 +15,13 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
-use crate::frontend::app::{App, AppResult};
+use crate::{
+ backend::search::BibiSearch,
+ frontend::app::{App, AppResult},
+};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
-use super::app::{CurrentArea, EntryTable, FormerArea};
+use super::app::{CurrentArea, FormerArea};
/// Handles the key events and updates the state of [`App`].
pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
@@ -61,14 +64,19 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
KeyCode::Char('/') => {
app.former_area = Some(FormerArea::TagArea);
app.current_area = CurrentArea::SearchArea;
+ // app.search_struct.is_search = true;
}
KeyCode::Tab | KeyCode::BackTab => {
app.toggle_area();
}
KeyCode::Esc => {
- if let Some(FormerArea::SearchArea) = app.former_area {
- app.reset_taglist();
- }
+ app.reset_taglist();
+ }
+ KeyCode::Enter => {
+ app.filter_for_tags();
+ app.toggle_area();
+ // app.reset_taglist();
+ app.former_area = Some(FormerArea::TagArea);
}
_ => {}
},
@@ -90,6 +98,9 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
App::yank_text(&app.get_selected_citekey());
}
KeyCode::Char('/') => {
+ if let Some(FormerArea::TagArea) = app.former_area {
+ app.search_struct.inner_search = true;
+ }
app.former_area = Some(FormerArea::EntryArea);
app.current_area = CurrentArea::SearchArea;
}
@@ -97,9 +108,11 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
app.toggle_area();
}
KeyCode::Esc => {
- if let Some(FormerArea::SearchArea) = app.former_area {
- app.reset_entry_table();
+ app.reset_entry_table();
+ if app.search_struct.inner_search {
+ app.reset_taglist();
}
+ app.former_area = None;
}
_ => {}
},
@@ -113,21 +126,34 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
app.reset_taglist();
}
app.former_area = None;
- app.search_string.clear();
+ // If search is canceled, reset default status of struct
+ BibiSearch::default();
+ // app.search_struct.search_string.clear();
+ // app.search_struct.is_search = false;
+ // app.search_struct.filtered_entry_list.clear();
}
KeyCode::Enter => {
// TODO: run function for filtering the list
app.toggle_area();
app.former_area = Some(FormerArea::SearchArea);
- app.search_string.clear();
+ // app.search_string.clear();
+ app.search_struct.search_string.clear();
}
KeyCode::Backspace => {
- app.search_string.pop();
- app.search_entries();
+ app.search_struct.search_string.pop();
+ if let Some(FormerArea::EntryArea) = app.former_area {
+ app.search_entries();
+ } else if let Some(FormerArea::TagArea) = app.former_area {
+ app.search_tags();
+ }
}
KeyCode::Char(search_pattern) => {
- app.search_string.push(search_pattern);
- app.search_entries();
+ app.search_struct.search_string.push(search_pattern);
+ if let Some(FormerArea::EntryArea) = app.former_area {
+ app.search_entries();
+ } else if let Some(FormerArea::TagArea) = app.former_area {
+ app.search_tags();
+ }
}
_ => {}
},
diff --git a/src/frontend/ui.rs b/src/frontend/ui.rs
index 0829227..7323917 100644
--- a/src/frontend/ui.rs
+++ b/src/frontend/ui.rs
@@ -18,15 +18,12 @@
use ratatui::{
buffer::Buffer,
layout::{Constraint, Layout, Rect},
- style::{
- palette::tailwind::{GRAY, SLATE},
- Color, Modifier, Style, Stylize,
- },
+ style::{palette::tailwind::SLATE, Color, Modifier, Style, Stylize},
symbols,
text::{Line, Span, Text},
widgets::{
- Block, Borders, Cell, HighlightSpacing, List, ListItem, Padding, Paragraph, Row,
- StatefulWidget, Table, Widget, Wrap,
+ Block, Cell, HighlightSpacing, List, ListItem, Padding, Paragraph, Row, StatefulWidget,
+ Table, Widget, Wrap,
},
};
@@ -38,7 +35,7 @@ use crate::{
use super::app::{CurrentArea, FormerArea};
const MAIN_BLUE_COLOR: Color = Color::Indexed(39);
-const MAIN_PURPLE_COLOR: Color = Color::Indexed(129);
+// const MAIN_PURPLE_COLOR: Color = Color::Indexed(129);
const BOX_BORDER_STYLE_MAIN: Style = Style::new().fg(Color::White).bg(Color::Black);
const NORMAL_ROW_BG: Color = Color::Black;
const ALT_ROW_BG_COLOR: Color = Color::Indexed(234);
@@ -47,7 +44,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);
+// const TEXT_CONFIRMED: Style = Style::new().fg(Color::Green);
pub const fn alternate_colors(i: usize) -> Color {
if i % 2 == 0 {
@@ -59,13 +56,7 @@ pub const fn alternate_colors(i: usize) -> Color {
impl From<&TagListItem> for ListItem<'_> {
fn from(value: &TagListItem) -> Self {
- let line = Line::styled(format!("{}", value.info), TEXT_FG_COLOR);
- // match value.status {
- // Status::Todo => Line::styled(format!(" ☐ {}", value.todo), TEXT_FG_COLOR),
- // Status::Completed => {
- // Line::styled(format!(" ✓ {}", value.todo), COMPLETED_TEXT_FG_COLOR)
- // }
- // };
+ let line = Line::styled(format!("{}", value.keyword), TEXT_FG_COLOR);
ListItem::new(line)
}
}
@@ -129,7 +120,7 @@ impl App {
let block = Block::bordered()
.title(search_title)
.border_set(symbols::border::ROUNDED);
- Paragraph::new(self.search_string.clone())
+ Paragraph::new(self.search_struct.search_string.clone())
.block(block)
.render(area, buf);
}
@@ -149,12 +140,7 @@ impl App {
pub fn render_entrytable(&mut self, area: Rect, buf: &mut Buffer) {
let block = Block::bordered() // can also be Block::new
- .title(
- Line::raw(" Bibliographic Entries ")
- .centered()
- .bold()
- .fg(Color::Indexed(39)),
- )
+ .title(Line::raw(" Bibliographic Entries ").centered().bold())
.border_set(symbols::border::ROUNDED)
.border_style(BOX_BORDER_STYLE_MAIN)
.bg(Color::Black); // .bg(NORMAL_ROW_BG);