Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
patch: Adjust to single widget trait
Erik Kundt committed 2 years ago
commit 7bcd739d6d9c24c520914de7aaf6f7447e9abed6
parent eab2c8bd05e331861f7962f7c33854048bf41313
2 files changed +121 -129
modified bin/commands/patch/select.rs
@@ -17,7 +17,7 @@ use tui::task;
use tui::task::Interrupted;
use tui::ui::items::{Filter, PatchItem, PatchItemFilter};
use tui::ui::widget::Properties;
-
use tui::ui::widget::View;
+
use tui::ui::widget::Widget;
use tui::ui::widget::Window;
use tui::ui::widget::WindowProps;
use tui::ui::Frontend;
modified bin/commands/patch/select/ui.rs
@@ -25,9 +25,7 @@ use tui::ui::widget::input::{TextField, TextFieldProps, TextFieldState};
use tui::ui::widget::text::{Paragraph, ParagraphProps, ParagraphState};
use tui::ui::widget::TableUtils;
use tui::ui::widget::{self, BaseView};
-
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_patch::common::Mode;
@@ -133,7 +131,94 @@ 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<usize>) -> Vec<Column<'a>> {
+
        let filter = PatchItemFilter::from_str(&props.search).unwrap_or_default();
+

+
        let search = Line::from(vec![
+
            span::default(" Search ").cyan().dim().reversed(),
+
            span::default(" "),
+
            span::default(&props.search.to_string()).gray().dim(),
+
        ]);
+

+
        let draft = Line::from(vec![
+
            span::default(&props.stats.get("Draft").unwrap_or(&0).to_string()).dim(),
+
            span::default(" Draft").dim(),
+
        ]);
+

+
        let open = Line::from(vec![
+
            span::positive(&props.stats.get("Open").unwrap_or(&0).to_string()).dim(),
+
            span::default(" Open").dim(),
+
        ]);
+

+
        let merged = Line::from(vec![
+
            span::default(&props.stats.get("Merged").unwrap_or(&0).to_string())
+
                .magenta()
+
                .dim(),
+
            span::default(" Merged").dim(),
+
        ]);
+

+
        let archived = Line::from(vec![
+
            span::default(&props.stats.get("Archived").unwrap_or(&0).to_string())
+
                .yellow()
+
                .dim(),
+
            span::default(" Archived").dim(),
+
        ]);
+

+
        let sum = Line::from(vec![
+
            span::default("Σ ").dim(),
+
            span::default(&props.patches.len().to_string()).dim(),
+
        ]);
+

+
        let progress = selected
+
            .map(|selected| TableUtils::progress(selected, props.patches.len(), props.page_size))
+
            .unwrap_or_default();
+
        let progress = span::default(&format!("{}%", progress)).dim();
+

+
        match filter.status() {
+
            Some(state) => {
+
                let block = match state {
+
                    Status::Draft => draft,
+
                    Status::Open => open,
+
                    Status::Merged => merged,
+
                    Status::Archived => archived,
+
                };
+

+
                vec![
+
                    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)),
+
                ]
+
            }
+
            None => vec![
+
                Column::new(Text::from(search), Constraint::Fill(1)),
+
                Column::new(
+
                    Text::from(draft.clone()),
+
                    Constraint::Min(draft.width() as u16),
+
                ),
+
                Column::new(
+
                    Text::from(open.clone()),
+
                    Constraint::Min(open.width() as u16),
+
                ),
+
                Column::new(
+
                    Text::from(merged.clone()),
+
                    Constraint::Min(merged.width() as u16),
+
                ),
+
                Column::new(
+
                    Text::from(archived.clone()),
+
                    Constraint::Min(archived.width() as u16),
+
                ),
+
                Column::new(Text::from(sum.clone()), Constraint::Min(sum.width() as u16)),
+
                Column::new(Text::from(progress), Constraint::Min(4)),
+
            ],
+
        }
+
    }
+
}
+

+
impl<'a: 'static> Widget for BrowsePage<'a> {
    type Action = Action;
    type State = State;

@@ -195,19 +280,6 @@ impl<'a: 'static> View for BrowsePage<'a> {
        }
    }

-
    fn base_mut(&mut self) -> &mut BaseView<State, Action> {
-
        &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.patches.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);
@@ -284,96 +356,16 @@ impl<'a: 'static> View for BrowsePage<'a> {
            }
        }
    }
-
}
-

-
impl<'a> BrowsePage<'a> {
-
    fn build_footer(props: &BrowsePageProps<'a>, selected: Option<usize>) -> Vec<Column<'a>> {
-
        let filter = PatchItemFilter::from_str(&props.search).unwrap_or_default();
-

-
        let search = Line::from(vec![
-
            span::default(" Search ").cyan().dim().reversed(),
-
            span::default(" "),
-
            span::default(&props.search.to_string()).gray().dim(),
-
        ]);
-

-
        let draft = Line::from(vec![
-
            span::default(&props.stats.get("Draft").unwrap_or(&0).to_string()).dim(),
-
            span::default(" Draft").dim(),
-
        ]);
-

-
        let open = Line::from(vec![
-
            span::positive(&props.stats.get("Open").unwrap_or(&0).to_string()).dim(),
-
            span::default(" Open").dim(),
-
        ]);
-

-
        let merged = Line::from(vec![
-
            span::default(&props.stats.get("Merged").unwrap_or(&0).to_string())
-
                .magenta()
-
                .dim(),
-
            span::default(" Merged").dim(),
-
        ]);
-

-
        let archived = Line::from(vec![
-
            span::default(&props.stats.get("Archived").unwrap_or(&0).to_string())
-
                .yellow()
-
                .dim(),
-
            span::default(" Archived").dim(),
-
        ]);

-
        let sum = Line::from(vec![
-
            span::default("Σ ").dim(),
-
            span::default(&props.patches.len().to_string()).dim(),
-
        ]);
-

-
        let progress = selected
-
            .map(|selected| TableUtils::progress(selected, props.patches.len(), props.page_size))
-
            .unwrap_or_default();
-
        let progress = span::default(&format!("{}%", progress)).dim();
-

-
        match filter.status() {
-
            Some(state) => {
-
                let block = match state {
-
                    Status::Draft => draft,
-
                    Status::Open => open,
-
                    Status::Merged => merged,
-
                    Status::Archived => archived,
-
                };
+
    fn update(&mut self, state: &State) {
+
        self.props = BrowsePageProps::from_callback(self.base.on_update, state)
+
            .unwrap_or(BrowsePageProps::from(state));

-
                vec![
-
                    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)),
-
                ]
-
            }
-
            None => vec![
-
                Column::new(Text::from(search), Constraint::Fill(1)),
-
                Column::new(
-
                    Text::from(draft.clone()),
-
                    Constraint::Min(draft.width() as u16),
-
                ),
-
                Column::new(
-
                    Text::from(open.clone()),
-
                    Constraint::Min(open.width() as u16),
-
                ),
-
                Column::new(
-
                    Text::from(merged.clone()),
-
                    Constraint::Min(merged.width() as u16),
-
                ),
-
                Column::new(
-
                    Text::from(archived.clone()),
-
                    Constraint::Min(archived.width() as u16),
-
                ),
-
                Column::new(Text::from(sum.clone()), Constraint::Min(sum.width() as u16)),
-
                Column::new(Text::from(progress), Constraint::Min(4)),
-
            ],
-
        }
+
        self.patches.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<Box<dyn Any>>) {
        let props = props
            .and_then(BrowsePageProps::from_boxed_any)
@@ -424,6 +416,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<State, Action> {
+
        &mut self.base
+
    }
}

pub struct SearchProps {}
@@ -439,7 +435,7 @@ pub struct Search {
    input: BoxedWidget,
}

-
impl View for Search {
+
impl Widget for Search {
    type Action = Action;
    type State = State;

@@ -476,14 +472,6 @@ impl View for Search {
        }
    }

-
    fn base_mut(&mut self) -> &mut BaseView<State, Action> {
-
        &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 => {
@@ -497,9 +485,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<Box<dyn Any>>) {
        let layout = Layout::horizontal(Constraint::from_mins([0]))
            .horizontal_margin(1)
@@ -507,6 +497,10 @@ impl Widget for Search {

        self.input.render(frame, layout[0], None);
    }
+

+
    fn base_mut(&mut self) -> &mut BaseView<State, Action> {
+
        &mut self.base
+
    }
}

#[derive(Clone)]
@@ -541,7 +535,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;

@@ -618,17 +612,6 @@ impl<'a: 'static> View for HelpPage<'a> {
        }
    }

-
    fn base_mut(&mut self) -> &mut BaseView<State, Action> {
-
        &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') => {
@@ -642,9 +625,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<Box<dyn Any>>) {
        let props = props
            .and_then(HelpPageProps::from_boxed_any)
@@ -670,6 +658,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<State, Action> {
+
        &mut self.base
+
    }
}

fn help_text() -> Text<'static> {