From 62f784fdb9cc617c81a90138e4a8c84e960f5648 Mon Sep 17 00:00:00 2001 From: Thomas Eppers Date: Wed, 24 Nov 2021 16:27:47 +0100 Subject: [PATCH] creating a widget for displaying tag details --- src/repository/dockerhub.rs | 9 +++++- src/repository/mod.rs | 9 ++++-- src/ui/default.rs | 16 +++++++++-- src/widget/details.rs | 56 +++++++++++++++++++++++++++++++++++++ src/widget/mod.rs | 1 + src/widget/tag_list.rs | 12 ++++++++ 6 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 src/widget/details.rs diff --git a/src/repository/dockerhub.rs b/src/repository/dockerhub.rs index b2f58dd..5dc91dd 100644 --- a/src/repository/dockerhub.rs +++ b/src/repository/dockerhub.rs @@ -5,6 +5,8 @@ use crate::repository::Error; #[derive(Deserialize, Debug, Clone)] struct ImageDetails { architecture: String, + os: String, + variant: Option, size: usize, } @@ -25,7 +27,12 @@ impl Images { .images .iter() .map(|d| super::TagDetails { - arch: Some(d.architecture.clone()), + arch: Some(format!( + "{}{}", + d.architecture.clone(), + d.variant.clone().unwrap_or_default() + )), + os: Some(d.os.clone()), size: Some(d.size), }) .collect(), diff --git a/src/repository/mod.rs b/src/repository/mod.rs index 86cd6a6..b730ea7 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -29,8 +29,9 @@ impl fmt::Display for Error { #[derive(Clone)] pub struct TagDetails { - arch: Option, - size: Option, + pub arch: Option, + pub os: Option, + pub size: Option, } impl fmt::Display for TagDetails { @@ -88,6 +89,10 @@ impl Tag { if dif.is_empty() {} format!("{}{}{}", self.name, dif, arch) } + + pub fn get_details(&self) -> &Vec { + &self.details + } } pub struct Repo { diff --git a/src/ui/default.rs b/src/ui/default.rs index c027081..f522a8b 100644 --- a/src/ui/default.rs +++ b/src/ui/default.rs @@ -18,6 +18,7 @@ pub struct Ui { repo: crate::widget::repo_entry::RepoEntry, tags: crate::widget::tag_list::TagList, services: crate::widget::service_switcher::ServiceSwitcher, + details: crate::widget::details::Details, info: crate::widget::info::Info, } @@ -66,6 +67,7 @@ impl Ui { repo: repo_entry::RepoEntry::new(repo_id), tags: tag_list::TagList::with_status("Tags are empty"), services: service_switcher::ServiceSwitcher::new(&opt.file).unwrap(), + details: crate::widget::details::Details::new(), info: info::Info::new("Select image of edit Repository"), }; @@ -93,6 +95,7 @@ impl Ui { Constraint::Min(9), Constraint::Length(3), Constraint::Min(7), + Constraint::Min(7), Constraint::Length(2), ] .as_ref(), @@ -104,7 +107,8 @@ impl Ui { rect.render_widget(ui.repo.render(ui.state == State::EditRepo), chunks[1]); let (list, state) = ui.tags.render(ui.state == State::SelectTag); rect.render_stateful_widget(list, chunks[2], state); - rect.render_widget(ui.info.render(), chunks[3]); + rect.render_widget(ui.details.render(), chunks[3]); + rect.render_widget(ui.info.render(), chunks[4]); }) .unwrap(); @@ -182,7 +186,10 @@ impl Ui { } State::SelectService => (), State::EditRepo => (), - State::SelectTag => ui.tags.handle_input(Key::Up), + State::SelectTag => { + ui.tags.handle_input(Key::Up); + ui.details = ui.tags.create_detail_widget(); + } }, Ok(Key::Down) => match ui.state { State::SelectService if ui.services.find_next_match() => { @@ -203,7 +210,10 @@ impl Ui { } State::SelectService => (), State::EditRepo => (), - State::SelectTag => ui.tags.handle_input(Key::Down), + State::SelectTag => { + ui.tags.handle_input(Key::Down); + ui.details = ui.tags.create_detail_widget(); + } }, _ => (), } diff --git a/src/widget/details.rs b/src/widget/details.rs new file mode 100644 index 0000000..f4aa704 --- /dev/null +++ b/src/widget/details.rs @@ -0,0 +1,56 @@ +use tui::style::{Color, Style}; +use tui::widgets::{Block, Borders, List}; + +use crate::repository; + +pub struct Details { + details: Vec, +} + +impl Details { + pub fn new() -> Self { + Self { details: vec![] } + } + + pub fn with_list(details: &Vec) -> Self { + let mut detail = Self { + details: details.clone(), + }; + + detail.details.sort_by(|a, b| a.arch.cmp(&b.arch)); + detail + } + + pub fn get_details(&self) -> Vec { + let mut lines = vec![format!("{:^10}|{:^6}|{:^6}", "ARCH", "OS", "SIZE")]; + for d in &self.details { + lines.push(format!( + "{:^10}|{:^6}|{:^6}", + d.arch.clone().unwrap_or_default(), + d.os.clone().unwrap_or_default(), + format!("{}MB", d.size.unwrap_or_default() / 1024 / 1024) + )); + } + lines + } + + pub fn render(&self) -> List { + let items: Vec = self + .get_details() + .iter() + .map(|l| { + tui::widgets::ListItem::new(format!("{}", l)) + .style(Style::default().fg(Color::White).bg(Color::Black)) + }) + .collect(); + + List::new(items) + .block( + Block::default() + .title("Details") + .borders(Borders::ALL) + .border_style(Style::default()), + ) + .style(Style::default().fg(Color::White).bg(Color::Black)) + } +} diff --git a/src/widget/mod.rs b/src/widget/mod.rs index b722798..802872b 100644 --- a/src/widget/mod.rs +++ b/src/widget/mod.rs @@ -1,3 +1,4 @@ +pub mod details; pub mod info; pub mod repo_entry; pub mod service_switcher; diff --git a/src/widget/tag_list.rs b/src/widget/tag_list.rs index 789aac4..9019300 100644 --- a/src/widget/tag_list.rs +++ b/src/widget/tag_list.rs @@ -116,6 +116,18 @@ impl TagList { (items, &mut self.state) } + pub fn create_detail_widget(&self) -> crate::widget::details::Details { + use crate::widget::details::Details; + + match self.state.selected() { + None => Details::new(), + Some(i) => match &self.lines[i] { + Line::Image(t) => Details::with_list(t.get_details()), + _ => Details::new(), + }, + } + } + pub fn handle_input(&mut self, key: termion::event::Key) { match key { Key::Down => self.next(),