aboutsummaryrefslogtreecommitdiff
path: root/src/screens/installed_packages.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/installed_packages.rs')
-rw-r--r--src/screens/installed_packages.rs148
1 files changed, 115 insertions, 33 deletions
diff --git a/src/screens/installed_packages.rs b/src/screens/installed_packages.rs
index 7e65fd5..48b0513 100644
--- a/src/screens/installed_packages.rs
+++ b/src/screens/installed_packages.rs
@@ -6,11 +6,11 @@ use ratatui::{
text::{Line, Span},
widgets::{Block, Borders, Clear, List, ListState, Paragraph},
};
-use ratatui_textarea::{Key, TextArea};
+use ratatui_textarea::TextArea;
use crate::{
actions::Signal,
- gentoo::Portage,
+ gentoo::{InstalledPackage, Portage},
screens::screen::Screen,
theme::Theme,
widgets::{
@@ -19,13 +19,61 @@ use crate::{
},
};
-#[derive(Debug, Default)]
+#[derive(Debug)]
struct SearchPopup {
pub(crate) visible: bool,
pub(crate) textarea: TextArea<'static>,
+ pub(crate) result: Option<usize>,
}
-#[derive(Debug, Default)]
+impl Default for SearchPopup {
+ fn default() -> Self {
+ let mut search_popup = Self {
+ visible: bool::default(),
+ textarea: TextArea::default(),
+ result: Option::default(),
+ };
+
+ search_popup.textarea.set_style(Theme::muted());
+ search_popup
+ .textarea
+ .set_cursor_line_style(Style::default());
+
+ return search_popup;
+ }
+}
+
+impl SearchPopup {
+ pub fn toggle(&mut self) {
+ self.visible = !self.visible;
+ self.textarea.clear();
+ }
+
+ pub fn search(&mut self, repo: &Portage) -> Option<usize> {
+ let indexes: Vec<usize> = repo
+ .installed_packages
+ .iter()
+ .enumerate()
+ .filter(|(_, s)| {
+ s.atom
+ .qualified_name()
+ .to_lowercase()
+ .contains(&self.textarea.lines()[0].to_lowercase())
+ })
+ .map(|(i, _)| i)
+ .collect();
+
+ if indexes.len() >= 1 {
+ self.result = Some(indexes[0]);
+ return Some(indexes[0]);
+ } else {
+ self.result = None;
+ return None;
+ }
+ }
+}
+
+#[derive(Debug)]
pub struct InstalledPackagesScreen {
list_state: ListState,
@@ -34,12 +82,12 @@ pub struct InstalledPackagesScreen {
impl InstalledPackagesScreen {
fn render_packages(&mut self, frame: &mut Frame, area: Rect, repo: &Portage) {
- // let items: Vec<String> = repo
- // .installed_packages()
- // .iter()
- // .map(|x| x.atom.qualified_name())
- // .collect();
- let items: Vec<String> = vec![];
+ // TODO: Put this into portage method
+ let items: Vec<String> = repo
+ .installed_packages
+ .iter()
+ .map(|x| x.atom.qualified_name())
+ .collect();
let list = List::new(items)
.style(Color::White)
@@ -56,6 +104,17 @@ impl InstalledPackagesScreen {
}
}
+impl Default for InstalledPackagesScreen {
+ fn default() -> Self {
+ let mut list_state = ListState::default();
+ list_state.select(Some(0));
+ Self {
+ list_state: list_state,
+ search_popup: Default::default(),
+ }
+ }
+}
+
impl Screen for InstalledPackagesScreen {
fn draw(&mut self, frame: &mut Frame, area: Rect, repo: &Portage) {
let constraints = [Constraint::Fill(1), Constraint::Length(3)];
@@ -69,9 +128,16 @@ impl Screen for InstalledPackagesScreen {
let split_vert = Layout::vertical([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(split[1]);
+ // TODO: Atleast this doesnt crash but its still weird, it should show some Info that this
+ // package is completly unkown or placeholder data, or at best a warning
+ let mut pkg: Option<&InstalledPackage> = None;
+ if repo.installed_packages.len() > self.list_state.selected().unwrap_or(0) {
+ pkg = Some(&repo.installed_packages[self.list_state.selected().unwrap_or(0)]);
+ }
+
self.render_packages(frame, split[0], repo);
- render_use_flags(frame, split_vert[0], &repo.installed_packages[0]);
- render_package_metadata(frame, split_vert[1], &repo.installed_packages[0]);
+ render_use_flags(frame, split_vert[0], pkg);
+ render_package_metadata(frame, split_vert[1], pkg);
let text = if self.search_popup.visible {
"(esc) to quit search | (enter) to search".to_string()
@@ -107,20 +173,13 @@ impl Screen for InstalledPackagesScreen {
.border_style(Theme::block())
.style(Style::default().bg(Theme::BG));
- // if let Some(found) = app.search_found {
- // if found {
- // popup_block = popup_block.border_style(Theme::success());
- // } else {
- // popup_block = popup_block.border_style(Theme::error());
- // }
- // }
+ if let Some(_) = self.search_popup.result {
+ popup_block = popup_block.border_style(Theme::success());
+ } else {
+ popup_block = popup_block.border_style(Theme::error());
+ }
- // TODO: Only do this in init, not every time
self.search_popup.textarea.set_block(popup_block);
- self.search_popup.textarea.set_style(Theme::muted());
- self.search_popup
- .textarea
- .set_cursor_line_style(Style::default());
let area = search_popup_rect(70, area);
@@ -134,20 +193,43 @@ impl Screen for InstalledPackagesScreen {
}
}
- fn update(&mut self, key: KeyEvent) -> Option<Signal> {
+ fn update(&mut self, key: KeyEvent, repo: &Portage) -> Option<Signal> {
if self.search_popup.visible {
match key.code {
- KeyCode::Esc => todo!("Toggle search window"),
- KeyCode::Enter => todo!("Send search, get back matches"),
- _ => self.search_popup.textarea.input_without_shortcuts(key), //TODO: Run "search
- //logic" to get
- //jumping while typing,
+ KeyCode::Esc => self.search_popup.toggle(),
+ KeyCode::Enter => {
+ let result = self.search_popup.search(repo);
+ self.search_popup.toggle();
+
+ if let Some(index) = result {
+ self.list_state.select(Some(index));
+ }
+ }
+ _ => {
+ self.search_popup.textarea.input_without_shortcuts(key);
+ let result = self.search_popup.search(repo);
+
+ if let Some(index) = result {
+ self.list_state.select(Some(index));
+ }
+ }
};
} else {
match key.modifiers {
KeyModifiers::CONTROL => match key.code {
- KeyCode::Char('d') => todo!("next page"),
- KeyCode::Char('u') => todo!("prev page"),
+ KeyCode::Char('d') => self
+ .list_state
+ .select(Some(self.list_state.selected().unwrap_or(0) + 30)),
+ KeyCode::Char('u') => {
+ if let Some(selected) = self.list_state.selected() {
+ if selected < 30 {
+ self.list_state.select(Some(0));
+ } else {
+ self.list_state.select(Some(selected - 30));
+ }
+ }
+ }
+
_ => {}
},
@@ -156,7 +238,7 @@ impl Screen for InstalledPackagesScreen {
KeyCode::Tab => return Some(Signal::CycleTab),
KeyCode::Char('j') => self.list_state.select_next(),
KeyCode::Char('k') => self.list_state.select_previous(),
- KeyCode::Char('/') => todo!("Toggle search window"),
+ KeyCode::Char('/') => self.search_popup.toggle(),
KeyCode::Char('n') => todo!("Next search"),
KeyCode::Char('N') => todo!("prev search"),