aboutsummaryrefslogtreecommitdiff
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/helpers.rs65
-rw-r--r--src/widgets/mod.rs3
-rw-r--r--src/widgets/package_metadata.rs75
-rw-r--r--src/widgets/use_flags.rs43
4 files changed, 186 insertions, 0 deletions
diff --git a/src/widgets/helpers.rs b/src/widgets/helpers.rs
new file mode 100644
index 0000000..0bde326
--- /dev/null
+++ b/src/widgets/helpers.rs
@@ -0,0 +1,65 @@
+use ratatui::{
+ layout::{Constraint, Direction, Layout, Rect},
+ style::{Color, Modifier, Style},
+ text::{Line, Span},
+};
+
+use crate::gentoo::InstalledPackage;
+
+pub fn search_popup_rect(percent_x: u16, r: Rect) -> Rect {
+ // Cut the given rectangle into three vertical pieces
+ let popup_layout = Layout::default()
+ .direction(Direction::Vertical)
+ .constraints([Constraint::Length(10), Constraint::Length(3)])
+ .split(r);
+
+ // Then cut the middle vertical piece into three width-wise pieces
+ Layout::default()
+ .direction(Direction::Horizontal)
+ .constraints([
+ Constraint::Percentage((100 - percent_x) / 2),
+ Constraint::Percentage(percent_x),
+ Constraint::Percentage((100 - percent_x) / 2),
+ ])
+ .split(popup_layout[1])[1] // Return the middle chunk
+}
+
+pub fn homepage_lines(pkg: &InstalledPackage, bold_style: Style) -> Vec<Line<'_>> {
+ let mut lines = Vec::new();
+ lines.push(Line::from(vec![
+ Span::styled("Homepage: ", bold_style),
+ Span::raw(""),
+ ]));
+
+ for url in pkg.metadata.homepage.iter().filter(|s| !s.is_empty()) {
+ lines.push(Line::from(vec![
+ Span::raw(" - "), // indentation
+ Span::styled(
+ url,
+ Style::default()
+ .fg(Color::LightBlue)
+ .add_modifier(Modifier::UNDERLINED),
+ ),
+ ]));
+ }
+
+ lines
+}
+
+pub fn human_size(bytes: usize) -> String {
+ const UNITS: [&str; 5] = ["B", "KB", "MB", "GB", "TB"];
+
+ let mut size = bytes as f64;
+ let mut unit = 0;
+
+ while size >= 1024.0 && unit < UNITS.len() - 1 {
+ size /= 1024.0;
+ unit += 1;
+ }
+
+ if unit == 0 {
+ format!("{} {}", bytes, UNITS[unit])
+ } else {
+ format!("{:.1} {}", size, UNITS[unit])
+ }
+}
diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs
new file mode 100644
index 0000000..66f4b70
--- /dev/null
+++ b/src/widgets/mod.rs
@@ -0,0 +1,3 @@
+pub mod helpers;
+pub mod package_metadata;
+pub mod use_flags;
diff --git a/src/widgets/package_metadata.rs b/src/widgets/package_metadata.rs
new file mode 100644
index 0000000..e4f83bb
--- /dev/null
+++ b/src/widgets/package_metadata.rs
@@ -0,0 +1,75 @@
+use ratatui::{
+ Frame,
+ layout::Rect,
+ text::{Line, Span},
+ widgets::{Block, Borders, Paragraph, Wrap},
+};
+
+use crate::{
+ app::App,
+ gentoo::InstalledPackage,
+ theme::Theme,
+ widgets::helpers::{homepage_lines, human_size},
+};
+
+pub fn render_package_metadata(frame: &mut Frame, area: Rect, pkg: &InstalledPackage) {
+ let bold_style = Theme::title(); //Style::default().add_modifier(Modifier::BOLD);
+ let maintainer = Line::from_iter([
+ Span::styled("Maintainer: ", bold_style),
+ Span::raw(pkg.metadata.maintainer.as_deref().unwrap_or("Unknown")),
+ ]);
+
+ let version = Line::from_iter([
+ Span::styled("Version: ", bold_style),
+ Span::raw(&pkg.version),
+ ]);
+
+ let repository = Line::from_iter([
+ Span::styled("Repository: ", bold_style),
+ Span::raw(&pkg.metadata.repository),
+ ]);
+
+ let license = Line::from_iter([
+ Span::styled("License: ", bold_style),
+ Span::raw(pkg.metadata.license.as_deref().unwrap_or("Unknown")),
+ ]);
+
+ let description = Line::from_iter([
+ Span::styled("Description: ", bold_style),
+ Span::raw(pkg.metadata.description.as_deref().unwrap_or("Unknown")),
+ ]);
+
+ let size = Line::from_iter([
+ Span::styled("Size: ", bold_style),
+ Span::raw(human_size(pkg.size)),
+ ]);
+
+ let build_time = Line::from_iter([
+ Span::styled("Build time: ", bold_style),
+ Span::raw(pkg.build_time.to_string()),
+ ]);
+
+ let mut lines = vec![
+ maintainer,
+ version,
+ repository,
+ build_time,
+ license,
+ description,
+ size,
+ ];
+
+ let mut homepage = homepage_lines(pkg, bold_style);
+ lines.append(&mut homepage);
+
+ let paragraph = Paragraph::new(lines)
+ .block(
+ Block::default()
+ .title("Metadata")
+ .borders(Borders::ALL)
+ .border_style(Theme::block()),
+ )
+ .wrap(Wrap { trim: false });
+
+ frame.render_widget(paragraph, area);
+}
diff --git a/src/widgets/use_flags.rs b/src/widgets/use_flags.rs
new file mode 100644
index 0000000..8e2ecf4
--- /dev/null
+++ b/src/widgets/use_flags.rs
@@ -0,0 +1,43 @@
+use ratatui::{
+ Frame,
+ layout::Rect,
+ style::{Color, Modifier},
+ widgets::{Block, Borders, List, ListItem, ListState},
+};
+
+use crate::{app::App, gentoo::InstalledPackage, theme::Theme};
+
+pub fn render_use_flags(frame: &mut Frame, area: Rect, package: &InstalledPackage) {
+ let items = package.iuse.iter().map(|x| {
+ let text_style = if package.enabled_use_flags.contains(&x.name) {
+ Theme::success()
+ } else if x.default {
+ Theme::info()
+ } else {
+ Theme::error()
+ };
+
+ let text_style = if x.default {
+ text_style.add_modifier(Modifier::ITALIC)
+ } else {
+ text_style
+ };
+
+ ListItem::new(x.name.clone()).style(text_style)
+ });
+ let list = List::new(items)
+ .style(Color::White)
+ .scroll_padding(1)
+ .direction(ratatui::widgets::ListDirection::TopToBottom)
+ .block(
+ Block::default()
+ .borders(Borders::ALL)
+ .title("USE Flags")
+ .border_style(Theme::block()),
+ );
+
+ let mut list_state = ListState::default();
+ list_state.select_first();
+
+ frame.render_stateful_widget(list, area, &mut list_state);
+}