Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
inbox: Fix and clean up selection state
Erik Kundt committed 2 years ago
commit 608032c5734b6ed447f6a52f5ff8a713beb0516d
parent f657892da5ae2aaccf059bdca18498b267eb3690
3 files changed +61 -46
modified bin/commands/inbox/common.rs
@@ -1,3 +1,7 @@
+
use std::fmt::Display;
+

+
use serde::Serialize;
+

use radicle::identity::RepoId;

/// The application's subject. It tells the application
@@ -44,3 +48,24 @@ impl Mode {
        &self.repository
    }
}
+

+
/// The selected issue operation returned by the operation
+
/// selection widget.
+
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
+
pub enum InboxOperation {
+
    Show,
+
    Clear,
+
}
+

+
impl Display for InboxOperation {
+
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+
        match self {
+
            InboxOperation::Show => {
+
                write!(f, "show")
+
            }
+
            InboxOperation::Clear => {
+
                write!(f, "clear")
+
            }
+
        }
+
    }
+
}
modified bin/commands/inbox/flux/select.rs
@@ -58,7 +58,6 @@ impl Default for UIState {
#[derive(Clone, Debug)]
pub struct State {
    notifications: Vec<NotificationItem>,
-
    selected: Option<NotificationItem>,
    mode: Mode,
    project: Project,
    search: StateValue<String>,
@@ -152,11 +151,8 @@ impl TryFrom<&Context> for State {
            notifications.sort_by(|a, b| a.project.cmp(&b.project));
        }

-
        let selected = notifications.first().cloned();
-

        Ok(Self {
            notifications,
-
            selected,
            mode: mode.clone(),
            project,
            search: StateValue::new(String::new()),
@@ -167,7 +163,6 @@ impl TryFrom<&Context> for State {

pub enum Action {
    Exit { selection: Option<Selection> },
-
    Select { item: NotificationItem },
    PageSize(usize),
    OpenSearch,
    UpdateSearch { value: String },
@@ -183,10 +178,6 @@ impl store::State<Action, Selection> for State {
    fn handle_action(&mut self, action: Action) -> Option<Exit<Selection>> {
        match action {
            Action::Exit { selection } => Some(Exit { value: selection }),
-
            Action::Select { item } => {
-
                self.selected = Some(item);
-
                None
-
            }
            Action::PageSize(size) => {
                self.ui.page_size = size;
                None
modified bin/commands/inbox/flux/select/ui.rs
@@ -24,12 +24,11 @@ use tui::flux::ui::widget::{
};
use tui::Selection;

-
use crate::tui_inbox::common::{Mode, RepositoryMode, SelectionMode};
+
use crate::tui_inbox::common::{InboxOperation, Mode, RepositoryMode, SelectionMode};

use super::{Action, State};

pub struct ListPageProps {
-
    selected: Option<NotificationItem>,
    mode: Mode,
    show_search: bool,
    show_help: bool,
@@ -38,7 +37,6 @@ pub struct ListPageProps {
impl From<&State> for ListPageProps {
    fn from(state: &State) -> Self {
        Self {
-
            selected: state.selected.clone(),
            mode: state.mode.clone(),
            show_search: state.ui.show_search,
            show_help: state.ui.show_help,
@@ -104,30 +102,6 @@ impl<'a> Widget<State, Action> for ListPage<'a> {
                Key::Esc | Key::Ctrl('c') => {
                    let _ = self.action_tx.send(Action::Exit { selection: None });
                }
-
                Key::Char('\n') => {
-
                    if let Some(selected) = &self.props.selected {
-
                        let selection = match self.props.mode.selection() {
-
                            SelectionMode::Operation => Selection::default()
-
                                .with_operation("show".to_string())
-
                                .with_id(selected.id),
-
                            SelectionMode::Id => Selection::default().with_id(selected.id),
-
                        };
-
                        let _ = self.action_tx.send(Action::Exit {
-
                            selection: Some(selection),
-
                        });
-
                    }
-
                }
-
                Key::Char('c') => {
-
                    if let Some(selected) = &self.props.selected {
-
                        let _ = self.action_tx.send(Action::Exit {
-
                            selection: Some(
-
                                Selection::default()
-
                                    .with_operation("clear".to_string())
-
                                    .with_id(selected.id),
-
                            ),
-
                        });
-
                    }
-
                }
                Key::Char('/') => {
                    let _ = self.action_tx.send(Action::OpenSearch);
                }
@@ -321,18 +295,43 @@ impl Widget<State, Action> for Notifications {
            Key::End => {
                self.table.end(self.props.notifications.len());
            }
+
            Key::Char('\n') => {
+
                self.table
+
                    .selected()
+
                    .and_then(|selected| self.props.notifications.get(selected))
+
                    .and_then(|notif| {
+
                        let selection = match self.props.mode.selection() {
+
                            SelectionMode::Operation => Selection::default()
+
                                .with_operation(InboxOperation::Show.to_string())
+
                                .with_id(notif.id),
+
                            SelectionMode::Id => Selection::default().with_id(notif.id),
+
                        };
+

+
                        self.action_tx
+
                            .send(Action::Exit {
+
                                selection: Some(selection),
+
                            })
+
                            .ok()
+
                    });
+
            }
+
            Key::Char('c') => {
+
                self.table
+
                    .selected()
+
                    .and_then(|selected| self.props.notifications.get(selected))
+
                    .and_then(|notif| {
+
                        self.action_tx
+
                            .send(Action::Exit {
+
                                selection: Some(
+
                                    Selection::default()
+
                                        .with_operation(InboxOperation::Clear.to_string())
+
                                        .with_id(notif.id),
+
                                ),
+
                            })
+
                            .ok()
+
                    });
+
            }
            _ => {}
        }
-
        self.table
-
            .selected()
-
            .and_then(|selected| self.props.notifications.get(selected))
-
            .and_then(|notif| {
-
                self.action_tx
-
                    .send(Action::Select {
-
                        item: notif.clone(),
-
                    })
-
                    .ok()
-
            });
    }
}