Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
patch-list: Add operations
Erik Kundt committed 2 years ago
commit 856cd8b37b29b599955de284c3668edf3f2dcf65
parent 9253736a528e54b71ef4539f9baececb4ef94912
8 files changed +118 -24
modified bin/commands/issue/suite.rs
@@ -301,7 +301,7 @@ impl App {
    }
}

-
impl Tui<Cid, Message> for App {
+
impl Tui<Cid, Message, ()> for App {
    fn init(&mut self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
        self.view_list(app, &self.theme.clone())?;

@@ -344,7 +344,7 @@ impl Tui<Cid, Message> for App {
        }
    }

-
    fn exit(&self) -> Option<Exit> {
+
    fn exit(&self) -> Option<Exit<()>> {
        if self.quit {
            return Some(Exit { value: None });
        }
modified bin/commands/patch.rs
@@ -8,6 +8,7 @@ mod select;
mod suite;

use std::ffi::OsString;
+
use std::process::Command;

use anyhow::anyhow;

@@ -16,6 +17,8 @@ use radicle_tui::{context, log, Window};
use crate::terminal;
use crate::terminal::args::{Args, Error, Help};

+
use self::list::PatchCommand;
+

pub const FPS: u64 = 60;
pub const HELP: Help = Help {
    name: "patch",
@@ -88,11 +91,46 @@ pub fn run(options: Options, _ctx: impl terminal::Context) -> anyhow::Result<()>

            log::enable(context.profile(), "patch", "list")?;

-
            let patch_id = Window::default()
-
                .run(&mut list::App::new(context), 1000 / FPS)?
-
                .unwrap_or_default();
+
            let mut app = list::App::new(context);
+
            if let Some(command) = Window::default().run(&mut app, 1000 / FPS)? {
+
                match command {
+
                    PatchCommand::Show(id) => {
+
                        match Command::new("rad")
+
                            .arg("patch")
+
                            .arg("show")
+
                            .arg(id.to_string())
+
                            .spawn()
+
                        {
+
                            Ok(_) => {}
+
                            Err(_) => {}
+
                        }
+
                    },
+
                    PatchCommand::Edit(id) => {
+
                        match Command::new("rad")
+
                            .arg("patch")
+
                            .arg("edit")
+
                            .arg(id.to_string())
+
                            .spawn()
+
                        {
+
                            Ok(_) => {}
+
                            Err(_) => {}
+
                        }
+
                    }
+
                    PatchCommand::Checkout(id) => {
+
                        match Command::new("rad")
+
                            .arg("patch")
+
                            .arg("checkout")
+
                            .arg(id.to_string())
+
                            .spawn()
+
                        {
+
                            Ok(_) => {}
+
                            Err(_) => {}
+
                        }
+
                    }
+
                }
+
            }

-
            eprint!("{patch_id}");
+
            // eprint!("{patch_id}");
        }
        Operation::Select => {
            let context = context::Context::new(id)?.with_patches();
modified bin/commands/patch/list.rs
@@ -24,6 +24,13 @@ use tui::{Exit, PageStack, Tui};

use page::ListView;

+
#[derive(Clone, Debug, Eq, PartialEq)]
+
pub enum PatchCommand {
+
    Show(PatchId),
+
    Edit(PatchId),
+
    Checkout(PatchId),
+
}
+

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum ListCid {
    Header,
@@ -44,7 +51,7 @@ pub enum Cid {
pub enum Message {
    #[default]
    Tick,
-
    Quit(Option<PatchId>),
+
    Quit(Option<PatchCommand>),
    Batch(Vec<Message>),
}

@@ -53,7 +60,7 @@ pub struct App {
    pages: PageStack<Cid, Message>,
    theme: Theme,
    quit: bool,
-
    result: Option<PatchId>,
+
    result: Option<PatchCommand>,
}

/// Creates a new application using a tui-realm-application, mounts all
@@ -113,7 +120,7 @@ impl App {
    }
}

-
impl Tui<Cid, Message> for App {
+
impl Tui<Cid, Message, PatchCommand> for App {
    fn init(&mut self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
        self.view_list(app, &self.theme.clone())?;

@@ -152,10 +159,10 @@ impl Tui<Cid, Message> for App {
        }
    }

-
    fn exit(&self) -> Option<Exit> {
+
    fn exit(&self) -> Option<Exit<PatchCommand>> {
        if self.quit {
            return Some(Exit {
-
                value: self.result.map(|id| format!("{id}")),
+
                value: self.result.clone(),
            });
        }
        None
modified bin/commands/patch/list/event.rs
@@ -1,6 +1,6 @@
-
use tuirealm::command::{Cmd, Direction as MoveDirection};
+
use tuirealm::command::{Cmd, CmdResult, Direction as MoveDirection};
use tuirealm::event::{Event, Key, KeyEvent};
-
use tuirealm::{MockComponent, NoUserEvent};
+
use tuirealm::{MockComponent, NoUserEvent, State, StateValue};

use radicle_tui as tui;

@@ -11,7 +11,7 @@ use tui::ui::widget::list::PropertyList;
use tui::ui::widget::Widget;

use super::super::common;
-
use super::Message;
+
use super::{Message, PatchCommand};

/// Since the framework does not know the type of messages that are being
/// passed around in the app, the following handlers need to be implemented for
@@ -51,6 +51,48 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<common::ui::PatchBrows
                self.perform(Cmd::Move(MoveDirection::Down));
                Some(Message::Tick)
            }
+
            Event::Keyboard(KeyEvent {
+
                code: Key::Enter, ..
+
            }) => {
+
                let result = self.perform(Cmd::Submit);
+
                match result {
+
                    CmdResult::Submit(State::One(StateValue::Usize(selected))) => {
+
                        let item = self.items().get(selected)?;
+
                        Some(Message::Quit(Some(PatchCommand::Show(
+
                            item.id().to_owned(),
+
                        ))))
+
                    }
+
                    _ => None,
+
                }
+
            }
+
            Event::Keyboard(KeyEvent {
+
                code: Key::Char('e'), ..
+
            }) => {
+
                let result = self.perform(Cmd::Submit);
+
                match result {
+
                    CmdResult::Submit(State::One(StateValue::Usize(selected))) => {
+
                        let item = self.items().get(selected)?;
+
                        Some(Message::Quit(Some(PatchCommand::Edit(
+
                            item.id().to_owned(),
+
                        ))))
+
                    }
+
                    _ => None,
+
                }
+
            }
+
            Event::Keyboard(KeyEvent {
+
                code: Key::Char('c'), ..
+
            }) => {
+
                let result = self.perform(Cmd::Submit);
+
                match result {
+
                    CmdResult::Submit(State::One(StateValue::Usize(selected))) => {
+
                        let item = self.items().get(selected)?;
+
                        Some(Message::Quit(Some(PatchCommand::Checkout(
+
                            item.id().to_owned(),
+
                        ))))
+
                    }
+
                    _ => None,
+
                }
+
            }
            _ => None,
        }
    }
modified bin/commands/patch/list/page.rs
@@ -39,6 +39,9 @@ impl ListView {
                theme,
                vec![
                    tui::ui::shortcut(theme, "↑/↓", "navigate"),
+
                    tui::ui::shortcut(theme, "enter", "show"),
+
                    tui::ui::shortcut(theme, "c", "checkout"),
+
                    tui::ui::shortcut(theme, "e", "edit"),
                    tui::ui::shortcut(theme, "q", "quit"),
                ],
            ),
modified bin/commands/patch/select.rs
@@ -113,7 +113,7 @@ impl App {
    }
}

-
impl Tui<Cid, Message> for App {
+
impl Tui<Cid, Message, String> for App {
    fn init(&mut self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
        self.view_list(app, &self.theme.clone())?;

@@ -152,7 +152,7 @@ impl Tui<Cid, Message> for App {
        }
    }

-
    fn exit(&self) -> Option<Exit> {
+
    fn exit(&self) -> Option<Exit<String>> {
        if self.quit {
            return Some(Exit {
                value: self.result.map(|id| format!("{id}")),
modified bin/commands/patch/suite.rs
@@ -232,7 +232,7 @@ impl App {
    }
}

-
impl Tui<Cid, Message> for App {
+
impl Tui<Cid, Message, ()> for App {
    fn init(&mut self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
        self.view_list(app, &self.theme.clone())?;

@@ -275,7 +275,7 @@ impl Tui<Cid, Message> for App {
        }
    }

-
    fn exit(&self) -> Option<Exit> {
+
    fn exit(&self) -> Option<Exit<()>> {
        if self.quit {
            return Some(Exit { value: None });
        }
modified src/lib.rs
@@ -22,7 +22,7 @@ use ui::theme::Theme;
/// accordingly and rendered with new state.
///
/// Please see `examples/` for further information on how to use it.
-
pub trait Tui<Id, Message>
+
pub trait Tui<Id, Message, Return>
where
    Id: Eq + PartialEq + Clone + Hash,
    Message: Eq,
@@ -38,12 +38,12 @@ where
    fn view(&mut self, app: &mut Application<Id, Message, NoUserEvent>, frame: &mut Frame);

    /// Should return `Some` if the application is requested to quit.
-
    fn exit(&self) -> Option<Exit>;
+
    fn exit(&self) -> Option<Exit<Return>>;
}

/// An optional return value.
-
pub struct Exit {
-
    pub value: Option<String>,
+
pub struct Exit<T> {
+
    pub value: Option<T>,
}

/// A tui-window using the cross-platform Terminal helper provided
@@ -77,9 +77,13 @@ impl Window {
    ///    - update application state
    ///    - redraw view
    /// 3. Leave alternative terminal screen
-
    pub fn run<T, Id, Message>(&mut self, tui: &mut T, interval: u64) -> Result<Option<String>>
+
    pub fn run<T, Id, Message, Return>(
+
        &mut self,
+
        tui: &mut T,
+
        interval: u64,
+
    ) -> Result<Option<Return>>
    where
-
        T: Tui<Id, Message>,
+
        T: Tui<Id, Message, Return>,
        Id: Eq + PartialEq + Clone + Hash,
        Message: Eq,
    {