diff options
| author | pablu <me@pablu.de> | 2026-06-02 18:49:48 +0200 |
|---|---|---|
| committer | pablu <me@pablu.de> | 2026-06-02 18:49:48 +0200 |
| commit | b547e6758c635682c94794e5c13070a73c918203 (patch) | |
| tree | 2ca030a7acbe436a304e6b87dd93deb0b2351909 /src/widgets | |
| parent | afe649e0efc31fcd33a828e54bd6313cd37f1784 (diff) | |
wip: refactor architecture
Diffstat (limited to 'src/widgets')
| -rw-r--r-- | src/widgets/helpers.rs | 65 | ||||
| -rw-r--r-- | src/widgets/mod.rs | 3 | ||||
| -rw-r--r-- | src/widgets/package_metadata.rs | 75 | ||||
| -rw-r--r-- | src/widgets/use_flags.rs | 43 |
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); +} |
