From 5e71e1d7a4f0324cab51cd3fe1bc936b2464d85f Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 24 Apr 2024 14:31:23 +0200 Subject: [PATCH] inbox: Adjust to single widget trait --- bin/commands/inbox/select.rs | 2 +- bin/commands/inbox/select/ui.rs | 200 +++++++++++++++----------------- 2 files changed, 97 insertions(+), 105 deletions(-) diff --git a/bin/commands/inbox/select.rs b/bin/commands/inbox/select.rs index 0f0babf4..e3b2f7eb 100644 --- a/bin/commands/inbox/select.rs +++ b/bin/commands/inbox/select.rs @@ -19,7 +19,7 @@ use tui::store; use tui::store::StateValue; use tui::task::{self, Interrupted}; use tui::ui::items::{Filter, NotificationItem, NotificationItemFilter}; -use tui::ui::widget::{Properties, View, Window, WindowProps}; +use tui::ui::widget::{Properties, Widget, Window, WindowProps}; use tui::ui::Frontend; use tui::Exit; diff --git a/bin/commands/inbox/select/ui.rs b/bin/commands/inbox/select/ui.rs index cede4bde..02f1e2a4 100644 --- a/bin/commands/inbox/select/ui.rs +++ b/bin/commands/inbox/select/ui.rs @@ -21,9 +21,7 @@ use tui::ui::widget::container::{ use tui::ui::widget::input::{TextField, TextFieldProps, TextFieldState}; use tui::ui::widget::text::{Paragraph, ParagraphProps, ParagraphState}; use tui::ui::widget::{self, BaseView, TableUtils}; -use tui::ui::widget::{ - Column, Properties, Shortcuts, ShortcutsProps, Table, TableProps, View, Widget, -}; +use tui::ui::widget::{Column, Properties, Shortcuts, ShortcutsProps, Table, TableProps, Widget}; use tui::Selection; use crate::tui_inbox::common::{InboxOperation, Mode, RepositoryMode, SelectionMode}; @@ -118,7 +116,70 @@ pub struct BrowsePage<'a> { shortcuts: BoxedWidget, } -impl<'a: 'static> View for BrowsePage<'a> { +impl<'a> BrowsePage<'a> { + fn build_footer(props: &BrowsePageProps<'a>, selected: Option) -> Vec> { + let search = Line::from(vec![ + span::default(" Search ").cyan().dim().reversed(), + span::default(" "), + span::default(&props.search.to_string()).gray().dim(), + ]); + + let seen = Line::from(vec![ + span::positive(&props.stats.get("Seen").unwrap_or(&0).to_string()).dim(), + span::default(" Seen").dim(), + ]); + let unseen = Line::from(vec![ + span::positive(&props.stats.get("Unseen").unwrap_or(&0).to_string()) + .magenta() + .dim(), + span::default(" Unseen").dim(), + ]); + + let progress = selected + .map(|selected| { + TableUtils::progress(selected, props.notifications.len(), props.page_size) + }) + .unwrap_or_default(); + let progress = span::default(&format!("{}%", progress)).dim(); + + match NotificationItemFilter::from_str(&props.search) + .unwrap_or_default() + .state() + { + Some(state) => { + let block = match state { + NotificationState::Seen => seen, + NotificationState::Unseen => unseen, + }; + + [ + Column::new(Text::from(search), Constraint::Fill(1)), + Column::new( + Text::from(block.clone()), + Constraint::Min(block.width() as u16), + ), + Column::new(Text::from(progress), Constraint::Min(4)), + ] + .to_vec() + } + None => [ + Column::new(Text::from(search), Constraint::Fill(1)), + Column::new( + Text::from(seen.clone()), + Constraint::Min(seen.width() as u16), + ), + Column::new( + Text::from(unseen.clone()), + Constraint::Min(unseen.width() as u16), + ), + Column::new(Text::from(progress), Constraint::Min(4)), + ] + .to_vec(), + } + } +} + +impl<'a: 'static> Widget for BrowsePage<'a> { type Action = Action; type State = State; @@ -191,19 +252,6 @@ impl<'a: 'static> View for BrowsePage<'a> { } } - fn base_mut(&mut self) -> &mut BaseView { - &mut self.base - } - - fn update(&mut self, state: &State) { - self.props = BrowsePageProps::from_callback(self.base.on_update, state) - .unwrap_or(BrowsePageProps::from(state)); - - self.notifications.update(state); - self.search.update(state); - self.shortcuts.update(state); - } - fn handle_event(&mut self, key: Key) { if self.props.show_search { self.search.handle_event(key); @@ -261,72 +309,16 @@ impl<'a: 'static> View for BrowsePage<'a> { } } } -} -impl<'a> BrowsePage<'a> { - fn build_footer(props: &BrowsePageProps<'a>, selected: Option) -> Vec> { - let search = Line::from(vec![ - span::default(" Search ").cyan().dim().reversed(), - span::default(" "), - span::default(&props.search.to_string()).gray().dim(), - ]); + fn update(&mut self, state: &State) { + self.props = BrowsePageProps::from_callback(self.base.on_update, state) + .unwrap_or(BrowsePageProps::from(state)); - let seen = Line::from(vec![ - span::positive(&props.stats.get("Seen").unwrap_or(&0).to_string()).dim(), - span::default(" Seen").dim(), - ]); - let unseen = Line::from(vec![ - span::positive(&props.stats.get("Unseen").unwrap_or(&0).to_string()) - .magenta() - .dim(), - span::default(" Unseen").dim(), - ]); - - let progress = selected - .map(|selected| { - TableUtils::progress(selected, props.notifications.len(), props.page_size) - }) - .unwrap_or_default(); - let progress = span::default(&format!("{}%", progress)).dim(); - - match NotificationItemFilter::from_str(&props.search) - .unwrap_or_default() - .state() - { - Some(state) => { - let block = match state { - NotificationState::Seen => seen, - NotificationState::Unseen => unseen, - }; - - [ - Column::new(Text::from(search), Constraint::Fill(1)), - Column::new( - Text::from(block.clone()), - Constraint::Min(block.width() as u16), - ), - Column::new(Text::from(progress), Constraint::Min(4)), - ] - .to_vec() - } - None => [ - Column::new(Text::from(search), Constraint::Fill(1)), - Column::new( - Text::from(seen.clone()), - Constraint::Min(seen.width() as u16), - ), - Column::new( - Text::from(unseen.clone()), - Constraint::Min(unseen.width() as u16), - ), - Column::new(Text::from(progress), Constraint::Min(4)), - ] - .to_vec(), - } + self.notifications.update(state); + self.search.update(state); + self.shortcuts.update(state); } -} -impl<'a: 'static> Widget for BrowsePage<'a> { fn render(&self, frame: &mut ratatui::Frame, area: Rect, props: Option>) { let props = props .and_then(BrowsePageProps::from_boxed_any) @@ -377,6 +369,10 @@ impl<'a: 'static> Widget for BrowsePage<'a> { let _ = self.base.action_tx.send(Action::BrowserPageSize(page_size)); } } + + fn base_mut(&mut self) -> &mut BaseView { + &mut self.base + } } pub struct SearchProps {} @@ -392,7 +388,7 @@ pub struct Search { input: BoxedWidget, } -impl View for Search { +impl Widget for Search { type Action = Action; type State = State; @@ -429,14 +425,6 @@ impl View for Search { } } - fn base_mut(&mut self) -> &mut BaseView { - &mut self.base - } - - fn update(&mut self, state: &State) { - self.input.update(state); - } - fn handle_event(&mut self, key: termion::event::Key) { match key { Key::Esc => { @@ -450,9 +438,11 @@ impl View for Search { } } } -} -impl Widget for Search { + fn update(&mut self, state: &State) { + self.input.update(state); + } + fn render(&self, frame: &mut ratatui::Frame, area: Rect, _props: Option>) { let layout = Layout::horizontal(Constraint::from_mins([0])) .horizontal_margin(1) @@ -460,6 +450,10 @@ impl Widget for Search { self.input.render(frame, layout[0], None); } + + fn base_mut(&mut self) -> &mut BaseView { + &mut self.base + } } #[derive(Clone)] @@ -494,7 +488,7 @@ pub struct HelpPage<'a> { shortcuts: BoxedWidget, } -impl<'a: 'static> View for HelpPage<'a> { +impl<'a: 'static> Widget for HelpPage<'a> { type Action = Action; type State = State; @@ -571,17 +565,6 @@ impl<'a: 'static> View for HelpPage<'a> { } } - fn base_mut(&mut self) -> &mut BaseView { - &mut self.base - } - - fn update(&mut self, state: &State) { - self.props = HelpPageProps::from_callback(self.base.on_update, state) - .unwrap_or(HelpPageProps::from(state)); - - self.content.update(state); - } - fn handle_event(&mut self, key: termion::event::Key) { match key { Key::Esc | Key::Ctrl('c') => { @@ -595,9 +578,14 @@ impl<'a: 'static> View for HelpPage<'a> { } } } -} -impl<'a: 'static> Widget for HelpPage<'a> { + fn update(&mut self, state: &State) { + self.props = HelpPageProps::from_callback(self.base.on_update, state) + .unwrap_or(HelpPageProps::from(state)); + + self.content.update(state); + } + fn render(&self, frame: &mut ratatui::Frame, area: Rect, props: Option>) { let props = props .and_then(HelpPageProps::from_boxed_any) @@ -623,6 +611,10 @@ impl<'a: 'static> Widget for HelpPage<'a> { let _ = self.base.action_tx.send(Action::HelpPageSize(page_size)); } } + + fn base_mut(&mut self) -> &mut BaseView { + &mut self.base + } } fn help_text() -> Text<'static> {