Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
inbox: Implement operation selection
Erik Kundt committed 2 years ago
commit 23dc98ef630966f83c31b9ae4c5f4caa60665084
parent f23cc04759a543247c3b48d426291a1d30d5c19b
8 files changed +71 -68
modified bin/commands/inbox/select.rs
@@ -67,27 +67,19 @@ pub enum Mode {
/// The selected issue operation returned by the operation
/// selection widget.
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-
pub enum IssueOperation {
+
pub enum InboxOperation {
    Show,
-
    Delete,
-
    Edit,
-
    Comment,
+
    Clear,
}

-
impl Display for IssueOperation {
+
impl Display for InboxOperation {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
-
            IssueOperation::Show => {
+
            InboxOperation::Show => {
                write!(f, "show")
            }
-
            IssueOperation::Delete => {
-
                write!(f, "delete")
-
            }
-
            IssueOperation::Edit => {
-
                write!(f, "edit")
-
            }
-
            IssueOperation::Comment => {
-
                write!(f, "comment")
+
            InboxOperation::Clear => {
+
                write!(f, "clear")
            }
        }
    }
modified bin/commands/inbox/select/event.rs
@@ -1,4 +1,4 @@
-
use radicle::issue::IssueId;
+
use radicle::node::notifications::NotificationId;

use tuirealm::command::{Cmd, CmdResult, Direction as MoveDirection};
use tuirealm::event::{Event, Key, KeyEvent};
@@ -6,14 +6,15 @@ use tuirealm::{MockComponent, NoUserEvent};

use radicle_tui as tui;

+
use tui::ui::state::ItemState;
use tui::ui::widget::container::{AppHeader, GlobalListener, LabeledContainer};
use tui::ui::widget::context::{ContextBar, Shortcuts};
use tui::ui::widget::list::PropertyList;
use tui::ui::widget::Widget;
-
use tui::SelectionExit;
+
use tui::{Id, SelectionExit};

use super::ui::OperationSelect;
-
use super::{IssueOperation, Message};
+
use super::{InboxOperation, Message};

/// 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
@@ -34,9 +35,13 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<GlobalListener> {

impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
    fn on(&mut self, event: Event<NoUserEvent>) -> Option<Message> {
-
        let mut submit = || -> Option<radicle::cob::patch::PatchId> {
+
        let mut submit = || -> Option<NotificationId> {
            match self.perform(Cmd::Submit) {
-
                CmdResult::Submit(_) => None,
+
                CmdResult::Submit(state) => {
+
                    let selected = ItemState::try_from(state).ok()?.selected()?;
+
                    let item = self.items().get(selected)?;
+
                    Some(item.id().to_owned())
+
                }
                _ => None,
            }
        };
@@ -64,35 +69,17 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
                code: Key::Enter, ..
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
-
                    .with_operation(IssueOperation::Show.to_string())
-
                    .with_id(IssueId::from(id));
+
                    .with_operation(InboxOperation::Show.to_string())
+
                    .with_id(Id::Notification(id));
                Message::Quit(Some(exit))
            }),
            Event::Keyboard(KeyEvent {
-
                code: Key::Char('d'),
+
                code: Key::Char('c'),
                ..
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
-
                    .with_operation(IssueOperation::Delete.to_string())
-
                    .with_id(IssueId::from(id));
-
                Message::Quit(Some(exit))
-
            }),
-
            Event::Keyboard(KeyEvent {
-
                code: Key::Char('e'),
-
                ..
-
            }) => submit().map(|id| {
-
                let exit = SelectionExit::default()
-
                    .with_operation(IssueOperation::Edit.to_string())
-
                    .with_id(IssueId::from(id));
-
                Message::Quit(Some(exit))
-
            }),
-
            Event::Keyboard(KeyEvent {
-
                code: Key::Char('m'),
-
                ..
-
            }) => submit().map(|id| {
-
                let exit = SelectionExit::default()
-
                    .with_operation(IssueOperation::Comment.to_string())
-
                    .with_id(IssueId::from(id));
+
                    .with_operation(InboxOperation::Clear.to_string())
+
                    .with_id(Id::Notification(id));
                Message::Quit(Some(exit))
            }),
            _ => None,
modified bin/commands/inbox/select/page.rs
@@ -84,7 +84,7 @@ impl ViewPage<Cid, Message> for ListView {
        context: &Context,
        theme: &Theme,
    ) -> Result<()> {
-
        let browser = ui::operation_select(theme, context, self.filter.clone()).to_boxed();
+
        let browser = ui::operation_select(theme, context, self.filter.clone(), None).to_boxed();
        self.shortcuts = browser.as_ref().shortcuts();

        app.remount(Cid::List(ListCid::NotificationBrowser), browser, vec![])?;
modified bin/commands/inbox/select/ui.rs
@@ -44,7 +44,7 @@ impl NotificationBrowser {
            ColumnWidth::Fixed(10),
            ColumnWidth::Fixed(15),
        ];
-
        
+

        let mut items = vec![];
        for notification in context.notifications() {
            if let Ok(item) =
@@ -100,12 +100,20 @@ impl OperationSelect {
        Self { theme, browser }
    }

+
    pub fn items(&self) -> &Vec<NotificationItem> {
+
        self.browser.items()
+
    }
+

    pub fn shortcuts(&self) -> HashMap<ListCid, Widget<Shortcuts>> {
        [(
            ListCid::NotificationBrowser,
            tui::ui::shortcuts(
                &self.theme,
-
                vec![tui::ui::shortcut(&self.theme, "q", "quit")],
+
                vec![
+
                    tui::ui::shortcut(&self.theme, "enter", "show"),
+
                    tui::ui::shortcut(&self.theme, "c", "clear"),
+
                    tui::ui::shortcut(&self.theme, "q", "quit"),
+
                ],
            ),
        )]
        .iter()
modified bin/commands/issue/select/event.rs
@@ -1,17 +1,15 @@
-
use radicle::issue::IssueId;
-
use tui::ui::state::ItemState;
-
use tui::SelectionExit;
use tuirealm::command::{Cmd, CmdResult, Direction as MoveDirection};
use tuirealm::event::{Event, Key, KeyEvent};
use tuirealm::{MockComponent, NoUserEvent};

use radicle_tui as tui;

+
use tui::ui::state::ItemState;
use tui::ui::widget::container::{AppHeader, GlobalListener, LabeledContainer};
use tui::ui::widget::context::{ContextBar, Shortcuts};
use tui::ui::widget::list::PropertyList;
-

use tui::ui::widget::Widget;
+
use tui::{Id, SelectionExit};

use super::ui::{IdSelect, OperationSelect};
use super::{IssueOperation, Message};
@@ -68,7 +66,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<IdSelect> {
            Event::Keyboard(KeyEvent {
                code: Key::Enter, ..
            }) => submit().map(|id| {
-
                let output = SelectionExit::default().with_id(IssueId::from(id));
+
                let output = SelectionExit::default().with_id(Id::Object(id));
                Message::Quit(Some(output))
            }),
            _ => None,
@@ -113,7 +111,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(IssueOperation::Show.to_string())
-
                    .with_id(IssueId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            Event::Keyboard(KeyEvent {
@@ -122,7 +120,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(IssueOperation::Delete.to_string())
-
                    .with_id(IssueId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            Event::Keyboard(KeyEvent {
@@ -131,7 +129,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(IssueOperation::Edit.to_string())
-
                    .with_id(IssueId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            Event::Keyboard(KeyEvent {
@@ -140,7 +138,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(IssueOperation::Comment.to_string())
-
                    .with_id(IssueId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            _ => None,
modified bin/commands/patch/select/event.rs
@@ -1,17 +1,15 @@
-
use radicle::patch::PatchId;
-
use tui::ui::state::ItemState;
-
use tui::SelectionExit;
use tuirealm::command::{Cmd, CmdResult, Direction as MoveDirection};
use tuirealm::event::{Event, Key, KeyEvent};
use tuirealm::{MockComponent, NoUserEvent};

use radicle_tui as tui;

+
use tui::ui::state::ItemState;
use tui::ui::widget::container::{AppHeader, GlobalListener, LabeledContainer};
use tui::ui::widget::context::{ContextBar, Shortcuts};
use tui::ui::widget::list::PropertyList;
-

use tui::ui::widget::Widget;
+
use tui::{Id, SelectionExit};

use super::ui::{IdSelect, OperationSelect};
use super::{Message, PatchOperation};
@@ -68,7 +66,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<IdSelect> {
            Event::Keyboard(KeyEvent {
                code: Key::Enter, ..
            }) => submit().map(|id| {
-
                let output = SelectionExit::default().with_id(PatchId::from(id));
+
                let output = SelectionExit::default().with_id(Id::Object(id));
                Message::Quit(Some(output))
            }),
            _ => None,
@@ -113,7 +111,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(PatchOperation::Show.to_string())
-
                    .with_id(PatchId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            Event::Keyboard(KeyEvent {
@@ -122,7 +120,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(PatchOperation::Checkout.to_string())
-
                    .with_id(PatchId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            Event::Keyboard(KeyEvent {
@@ -131,7 +129,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(PatchOperation::Delete.to_string())
-
                    .with_id(PatchId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            Event::Keyboard(KeyEvent {
@@ -140,7 +138,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(PatchOperation::Edit.to_string())
-
                    .with_id(PatchId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            Event::Keyboard(KeyEvent {
@@ -149,7 +147,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<OperationSelect> {
            }) => submit().map(|id| {
                let exit = SelectionExit::default()
                    .with_operation(PatchOperation::Comment.to_string())
-
                    .with_id(PatchId::from(id));
+
                    .with_id(Id::Object(id));
                Message::Quit(Some(exit))
            }),
            _ => None,
modified src/context.rs
@@ -8,8 +8,6 @@ use radicle::identity::{Project, RepoId};
use radicle::profile::env::RAD_PASSPHRASE;
use radicle::storage::git::Repository;
use radicle::storage::{ReadRepository, ReadStorage};
-
use radicle::node::notifications::*;
-

use radicle::Profile;

use radicle_term as term;
modified src/lib.rs
@@ -1,7 +1,9 @@
+
use std::fmt::Display;
use std::hash::Hash;
use std::time::Duration;

use anyhow::Result;
+
use radicle::node::notifications::NotificationId;
use serde::ser::{Serialize, SerializeStruct, Serializer};

use radicle::cob::ObjectId;
@@ -49,11 +51,31 @@ pub struct Exit<T> {
    pub value: Option<T>,
}

+
/// Returned ids can be of type `ObjectId` or `NotificationId`.
+
#[derive(Clone, Debug, Eq, PartialEq)]
+
pub enum Id {
+
    Object(ObjectId),
+
    Notification(NotificationId),
+
}
+

+
impl Display for Id {
+
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+
        match self {
+
            Id::Object(id) => {
+
                write!(f, "{id}")
+
            }
+
            Id::Notification(id) => {
+
                write!(f, "{id}")
+
            }
+
        }
+
    }
+
}
+

/// The output that is returned by all selection interfaces.
#[derive(Clone, Default, Debug, Eq, PartialEq)]
pub struct SelectionExit {
    operation: Option<String>,
-
    ids: Vec<ObjectId>,
+
    ids: Vec<Id>,
    args: Vec<String>,
}

@@ -63,7 +85,7 @@ impl SelectionExit {
        self
    }

-
    pub fn with_id(mut self, id: ObjectId) -> Self {
+
    pub fn with_id(mut self, id: Id) -> Self {
        self.ids.push(id);
        self
    }