Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Prepare home page for context bar
Erik Kundt committed 2 years ago
commit 1899411c0a650a5fc94efe01caf5d9b142657209
parent 9fb41c45c44aafa888267e4236ab2efa8bc424a1
4 files changed +130 -111
modified src/app.rs
@@ -28,6 +28,7 @@ pub enum HomeCid {
    Dashboard,
    IssueBrowser,
    PatchBrowser,
+
    Shortcuts,
}

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
@@ -118,7 +119,7 @@ impl App {
        app: &mut Application<Cid, Message, NoUserEvent>,
        theme: &Theme,
    ) -> Result<()> {
-
        let home = Box::<HomeView>::default();
+
        let home = Box::new(HomeView::new(theme.clone()));
        self.pages.push(home, app, &self.context, theme)?;

        Ok(())
modified src/app/page.rs
@@ -61,15 +61,75 @@ pub trait ViewPage {
/// Home
///
pub struct HomeView {
-
    active_component: Cid,
+
    active_component: HomeCid,
+
    shortcuts: HashMap<HomeCid, Widget<Shortcuts>>,
}

-
impl Default for HomeView {
-
    fn default() -> Self {
+
impl HomeView {
+
    pub fn new(theme: Theme) -> Self {
+
        let shortcuts = Self::build_shortcuts(&theme);
        HomeView {
-
            active_component: Cid::Home(HomeCid::Dashboard),
+
            active_component: HomeCid::Dashboard,
+
            shortcuts,
        }
    }
+

+
    fn build_shortcuts(theme: &Theme) -> HashMap<HomeCid, Widget<Shortcuts>> {
+
        [
+
            (
+
                HomeCid::Dashboard,
+
                widget::common::shortcuts(
+
                    theme,
+
                    vec![
+
                        widget::common::shortcut(theme, "tab", "section"),
+
                        widget::common::shortcut(theme, "q", "quit"),
+
                    ],
+
                ),
+
            ),
+
            (
+
                HomeCid::IssueBrowser,
+
                widget::common::shortcuts(
+
                    theme,
+
                    vec![
+
                        widget::common::shortcut(theme, "tab", "section"),
+
                        widget::common::shortcut(theme, "↑/↓", "navigate"),
+
                        widget::common::shortcut(theme, "enter", "show"),
+
                        widget::common::shortcut(theme, "q", "quit"),
+
                    ],
+
                ),
+
            ),
+
            (
+
                HomeCid::PatchBrowser,
+
                widget::common::shortcuts(
+
                    theme,
+
                    vec![
+
                        widget::common::shortcut(theme, "tab", "section"),
+
                        widget::common::shortcut(theme, "↑/↓", "navigate"),
+
                        widget::common::shortcut(theme, "enter", "show"),
+
                        widget::common::shortcut(theme, "q", "quit"),
+
                    ],
+
                ),
+
            ),
+
        ]
+
        .iter()
+
        .cloned()
+
        .collect()
+
    }
+

+
    fn update_shortcuts(
+
        &self,
+
        app: &mut Application<Cid, Message, NoUserEvent>,
+
        cid: HomeCid,
+
    ) -> Result<()> {
+
        if let Some(shortcuts) = self.shortcuts.get(&cid) {
+
            app.remount(
+
                Cid::Home(HomeCid::Shortcuts),
+
                shortcuts.clone().to_boxed(),
+
                vec![],
+
            )?;
+
        }
+
        Ok(())
+
    }
}

impl ViewPage for HomeView {
@@ -92,7 +152,9 @@ impl ViewPage for HomeView {
        app.remount(Cid::Home(HomeCid::IssueBrowser), issue_browser, vec![])?;
        app.remount(Cid::Home(HomeCid::PatchBrowser), patch_browser, vec![])?;

-
        app.active(&self.active_component)?;
+
        let active_component = Cid::Home(self.active_component.clone());
+
        app.active(&active_component)?;
+
        self.update_shortcuts(app, self.active_component.clone())?;

        Ok(())
    }
@@ -113,8 +175,11 @@ impl ViewPage for HomeView {
        message: Message,
    ) -> Result<Option<Message>> {
        if let Message::NavigationChanged(index) = message {
-
            self.active_component = Cid::Home(HomeCid::from(index as usize));
-
            app.active(&self.active_component)?;
+
            self.active_component = HomeCid::from(index as usize);
+

+
            let active_component = Cid::Home(self.active_component.clone());
+
            app.active(&active_component)?;
+
            self.update_shortcuts(app, self.active_component.clone())?;
        }

        Ok(None)
@@ -122,10 +187,16 @@ impl ViewPage for HomeView {

    fn view(&mut self, app: &mut Application<Cid, Message, NoUserEvent>, frame: &mut Frame) {
        let area = frame.size();
-
        let layout = layout::default_page(area);
-

-
        app.view(&Cid::Home(HomeCid::Header), frame, layout[0]);
-
        app.view(&self.active_component, frame, layout[1]);
+
        let shortcuts_h = 1u16;
+
        let layout = layout::default_page(area, shortcuts_h);
+

+
        app.view(&Cid::Home(HomeCid::Header), frame, layout.navigation);
+
        app.view(
+
            &Cid::Home(self.active_component.clone()),
+
            frame,
+
            layout.component,
+
        );
+
        app.view(&Cid::Home(HomeCid::Shortcuts), frame, layout.shortcuts);
    }

    fn subscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
@@ -362,10 +433,11 @@ impl ViewPage for PatchView {

    fn view(&mut self, app: &mut Application<Cid, Message, NoUserEvent>, frame: &mut Frame) {
        let area = frame.size();
-
        let layout = layout::default_page(area);
+
        let shortcuts_h = 1u16;
+
        let layout = layout::default_page(area, shortcuts_h);

-
        app.view(&Cid::Patch(PatchCid::Header), frame, layout[0]);
-
        app.view(&self.active_component, frame, layout[1]);
+
        app.view(&Cid::Patch(PatchCid::Header), frame, layout.navigation);
+
        app.view(&self.active_component, frame, layout.component);
    }

    fn subscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
modified src/ui/layout.rs
@@ -8,6 +8,13 @@ pub struct AppHeader {
    pub line: Rect,
}

+
pub struct DefaultPage {
+
    pub navigation: Rect,
+
    pub component: Rect,
+
    pub context: Rect,
+
    pub shortcuts: Rect,
+
}
+

pub struct IssuePage {
    pub header: Rect,
    pub left: Rect,
@@ -83,16 +90,34 @@ pub fn app_header(area: Rect, info_w: u16) -> AppHeader {
    }
}

-
pub fn default_page(area: Rect) -> Vec<Rect> {
+
pub fn default_page(area: Rect, shortcuts_h: u16) -> DefaultPage {
    let nav_h = 3u16;
+
    let context_h = 1u16;
    let margin_h = 1u16;
-
    let content_h = area.height.saturating_sub(nav_h.saturating_add(margin_h));
+
    let component_h = area
+
        .height
+
        .saturating_sub(nav_h.saturating_add(context_h).saturating_add(shortcuts_h));

-
    Layout::default()
+
    let layout = Layout::default()
        .direction(Direction::Vertical)
        .horizontal_margin(margin_h)
-
        .constraints([Constraint::Length(nav_h), Constraint::Length(content_h)].as_ref())
-
        .split(area)
+
        .constraints(
+
            [
+
                Constraint::Length(nav_h),
+
                Constraint::Length(component_h),
+
                Constraint::Length(context_h),
+
                Constraint::Length(shortcuts_h),
+
            ]
+
            .as_ref(),
+
        )
+
        .split(area);
+

+
    DefaultPage {
+
        navigation: layout[0],
+
        component: layout[1],
+
        context: layout[2],
+
        shortcuts: layout[3],
+
    }
}

pub fn headerless_page(area: Rect) -> Vec<Rect> {
@@ -106,21 +131,6 @@ pub fn headerless_page(area: Rect) -> Vec<Rect> {
        .split(area)
}

-
pub fn root_component(area: Rect, shortcuts_h: u16) -> Vec<Rect> {
-
    let content_h = area.height.saturating_sub(shortcuts_h);
-

-
    Layout::default()
-
        .direction(Direction::Vertical)
-
        .constraints(
-
            [
-
                Constraint::Length(content_h),
-
                Constraint::Length(shortcuts_h),
-
            ]
-
            .as_ref(),
-
        )
-
        .split(area)
-
}
-

pub fn root_component_with_context(area: Rect, context_h: u16, shortcuts_h: u16) -> Vec<Rect> {
    let content_h = area
        .height
modified src/ui/widget/home.rs
@@ -4,7 +4,6 @@ use tuirealm::{AttrValue, Attribute, Frame, MockComponent, Props, State};

use super::common;
use super::common::container::{LabeledContainer, Tabs};
-
use super::common::context::Shortcuts;
use super::common::list::{ColumnWidth, Table};

use super::{Widget, WidgetComponent};
@@ -12,31 +11,21 @@ use super::{Widget, WidgetComponent};
use crate::cob;
use crate::ui::cob::{IssueItem, PatchItem};
use crate::ui::context::Context;
-
use crate::ui::layout;
use crate::ui::theme::Theme;

pub struct Dashboard {
    about: Widget<LabeledContainer>,
-
    shortcuts: Widget<Shortcuts>,
}

impl Dashboard {
-
    pub fn new(about: Widget<LabeledContainer>, shortcuts: Widget<Shortcuts>) -> Self {
-
        Self { about, shortcuts }
+
    pub fn new(about: Widget<LabeledContainer>) -> Self {
+
        Self { about }
    }
}

impl WidgetComponent for Dashboard {
    fn view(&mut self, _properties: &Props, frame: &mut Frame, area: Rect) {
-
        let shortcuts_h = self
-
            .shortcuts
-
            .query(Attribute::Height)
-
            .unwrap_or(AttrValue::Size(0))
-
            .unwrap_size();
-
        let layout = layout::root_component(area, shortcuts_h);
-

-
        self.about.view(frame, layout[0]);
-
        self.shortcuts.view(frame, layout[1]);
+
        self.about.view(frame, area);
    }

    fn state(&self) -> State {
@@ -51,11 +40,10 @@ impl WidgetComponent for Dashboard {
pub struct IssueBrowser {
    items: Vec<IssueItem>,
    table: Widget<Table<IssueItem, 7>>,
-
    shortcuts: Widget<Shortcuts>,
}

impl IssueBrowser {
-
    pub fn new(context: &Context, theme: &Theme, shortcuts: Widget<Shortcuts>) -> Self {
+
    pub fn new(context: &Context, theme: &Theme) -> Self {
        let header = [
            common::label(" ● "),
            common::label("ID"),
@@ -93,11 +81,7 @@ impl IssueBrowser {
        let table = Widget::new(Table::new(&items, header, widths, theme.clone()))
            .highlight(theme.colors.item_list_highlighted_bg);

-
        Self {
-
            items,
-
            table,
-
            shortcuts,
-
        }
+
        Self { items, table }
    }

    pub fn items(&self) -> &Vec<IssueItem> {
@@ -107,20 +91,12 @@ impl IssueBrowser {

impl WidgetComponent for IssueBrowser {
    fn view(&mut self, properties: &Props, frame: &mut Frame, area: Rect) {
-
        let shortcuts_h = self
-
            .shortcuts
-
            .query(Attribute::Height)
-
            .unwrap_or(AttrValue::Size(0))
-
            .unwrap_size();
        let focus = properties
            .get_or(Attribute::Focus, AttrValue::Flag(false))
            .unwrap_flag();

-
        let layout = layout::root_component(area, shortcuts_h);
-

        self.table.attr(Attribute::Focus, AttrValue::Flag(focus));
-
        self.table.view(frame, layout[0]);
-
        self.shortcuts.view(frame, layout[1])
+
        self.table.view(frame, area);
    }

    fn state(&self) -> State {
@@ -135,11 +111,10 @@ impl WidgetComponent for IssueBrowser {
pub struct PatchBrowser {
    items: Vec<PatchItem>,
    table: Widget<Table<PatchItem, 8>>,
-
    shortcuts: Widget<Shortcuts>,
}

impl PatchBrowser {
-
    pub fn new(context: &Context, theme: &Theme, shortcuts: Widget<Shortcuts>) -> Self {
+
    pub fn new(context: &Context, theme: &Theme) -> Self {
        let header = [
            common::label(" ● "),
            common::label("ID"),
@@ -179,11 +154,7 @@ impl PatchBrowser {
        let table = Widget::new(Table::new(&items, header, widths, theme.clone()))
            .highlight(theme.colors.item_list_highlighted_bg);

-
        Self {
-
            items,
-
            table,
-
            shortcuts,
-
        }
+
        Self { items, table }
    }

    pub fn items(&self) -> &Vec<PatchItem> {
@@ -193,20 +164,12 @@ impl PatchBrowser {

impl WidgetComponent for PatchBrowser {
    fn view(&mut self, properties: &Props, frame: &mut Frame, area: Rect) {
-
        let shortcuts_h = self
-
            .shortcuts
-
            .query(Attribute::Height)
-
            .unwrap_or(AttrValue::Size(0))
-
            .unwrap_size();
        let focus = properties
            .get_or(Attribute::Focus, AttrValue::Flag(false))
            .unwrap_flag();

-
        let layout = layout::root_component(area, shortcuts_h);
-

        self.table.attr(Attribute::Focus, AttrValue::Flag(focus));
-
        self.table.view(frame, layout[0]);
-
        self.shortcuts.view(frame, layout[1]);
+
        self.table.view(frame, area);
    }

    fn state(&self) -> State {
@@ -243,42 +206,15 @@ pub fn dashboard(context: &Context, theme: &Theme) -> Widget<Dashboard> {
        )
        .to_boxed(),
    );
-
    let shortcuts = common::shortcuts(
-
        theme,
-
        vec![
-
            common::shortcut(theme, "tab", "section"),
-
            common::shortcut(theme, "q", "quit"),
-
        ],
-
    );
-
    let dashboard = Dashboard::new(about, shortcuts);
+
    let dashboard = Dashboard::new(about);

    Widget::new(dashboard)
}

pub fn patches(context: &Context, theme: &Theme) -> Widget<PatchBrowser> {
-
    let shortcuts = common::shortcuts(
-
        theme,
-
        vec![
-
            common::shortcut(theme, "tab", "section"),
-
            common::shortcut(theme, "↑/↓", "navigate"),
-
            common::shortcut(theme, "enter", "show"),
-
            common::shortcut(theme, "q", "quit"),
-
        ],
-
    );
-

-
    Widget::new(PatchBrowser::new(context, theme, shortcuts))
+
    Widget::new(PatchBrowser::new(context, theme))
}

pub fn issues(context: &Context, theme: &Theme) -> Widget<IssueBrowser> {
-
    let shortcuts = common::shortcuts(
-
        theme,
-
        vec![
-
            common::shortcut(theme, "tab", "section"),
-
            common::shortcut(theme, "↑/↓", "navigate"),
-
            common::shortcut(theme, "enter", "show"),
-
            common::shortcut(theme, "q", "quit"),
-
        ],
-
    );
-

-
    Widget::new(IssueBrowser::new(context, theme, shortcuts))
+
    Widget::new(IssueBrowser::new(context, theme))
}