Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
bin: Refactor quitting in `patch select`
Erik Kundt committed 1 year ago
commit a8dc311b9bc0818be9fafc3773a8a6ceaf8967bc
parent 829bb494c75ba0e4671fecf16fa3e88de0f577a1
2 files changed +48 -52
modified bin/commands/patch/select.rs
@@ -27,7 +27,7 @@ use tui::{BoxedAny, Channel, Exit, PageStack};

use self::ui::{Browser, BrowserProps};

-
use super::common::Mode;
+
use super::common::{Mode, PatchOperation};

use crate::cob::patch;
use crate::ui::items::{Filter, PatchItem, PatchItemFilter};
@@ -68,6 +68,18 @@ impl BrowserState {
            .cloned()
            .collect()
    }
+

+
    pub fn patches_ref(&self) -> Vec<&PatchItem> {
+
        self.items
+
            .iter()
+
            .filter(|patch| self.filter.matches(patch))
+
            .collect()
+
    }
+

+
    pub fn selected_item(&self) -> Option<&PatchItem> {
+
        self.selected
+
            .and_then(|selected| self.patches_ref().get(selected).copied())
+
    }
}

#[derive(Clone, Debug)]
@@ -118,7 +130,9 @@ impl TryFrom<&Context> for State {
}

pub enum Message {
-
    Exit { selection: Option<Selection> },
+
    Quit,
+
    Exit { operation: Option<PatchOperation> },
+
    ExitFromMode,
    Select { selected: Option<usize> },
    OpenSearch,
    UpdateSearch { value: String },
@@ -134,7 +148,28 @@ impl store::State<Selection> for State {

    fn update(&mut self, message: Message) -> Option<Exit<Selection>> {
        match message {
-
            Message::Exit { selection } => Some(Exit { value: selection }),
+
            Message::Quit => Some(Exit { value: None }),
+
            Message::Exit { operation } => self.browser.selected_item().map(|issue| Exit {
+
                value: Some(Selection {
+
                    operation: operation.map(|op| op.to_string()),
+
                    ids: vec![issue.id],
+
                    args: vec![],
+
                }),
+
            }),
+
            Message::ExitFromMode => {
+
                let operation = match self.mode {
+
                    Mode::Operation => Some(PatchOperation::Show.to_string()),
+
                    Mode::Id => None,
+
                };
+

+
                self.browser.selected_item().map(|issue| Exit {
+
                    value: Some(Selection {
+
                        operation,
+
                        ids: vec![issue.id],
+
                        args: vec![],
+
                    }),
+
                })
+
            }
            Message::Select { selected } => {
                self.browser.selected = selected;
                None
@@ -255,8 +290,15 @@ fn browser_page(_state: &State, channel: &Channel<Message>) -> Widget<State, Mes

            if props.handle_keys {
                match key {
-
                    Key::Esc | Key::Ctrl('c') => Some(Message::Exit { selection: None }),
+
                    Key::Esc | Key::Ctrl('c') => Some(Message::Quit),
                    Key::Char('?') => Some(Message::OpenHelp),
+
                    Key::Char('\n') => Some(Message::ExitFromMode),
+
                    Key::Char('c') => Some(Message::Exit {
+
                        operation: Some(PatchOperation::Checkout),
+
                    }),
+
                    Key::Char('d') => Some(Message::Exit {
+
                        operation: Some(PatchOperation::Diff),
+
                    }),
                    _ => None,
                }
            } else {
@@ -329,7 +371,7 @@ fn help_page(_state: &State, channel: &Channel<Message>) -> Widget<State, Messag
        .shortcuts(shortcuts)
        .to_widget(tx.clone())
        .on_event(|key, _, _| match key {
-
            Key::Esc | Key::Ctrl('c') => Some(Message::Exit { selection: None }),
+
            Key::Esc | Key::Ctrl('c') => Some(Message::Quit),
            Key::Char('?') => Some(Message::LeavePage),
            _ => None,
        })
modified bin/commands/patch/select/ui.rs
@@ -26,10 +26,8 @@ use tui::ui::widget::list::{Table, TableProps};
use tui::ui::widget::ViewProps;
use tui::ui::widget::{RenderProps, ToWidget, View};

-
use tui::{BoxedAny, Selection};
+
use tui::BoxedAny;

-
use crate::tui_patch::common::Mode;
-
use crate::tui_patch::common::PatchOperation;
use crate::ui::items::{PatchItem, PatchItemFilter};

use super::{Message, State};
@@ -38,12 +36,8 @@ type Widget = widget::Widget<State, Message>;

#[derive(Clone, Default)]
pub struct BrowserProps<'a> {
-
    /// Application mode: openation and id or id only.
-
    mode: Mode,
    /// Filtered patches.
    patches: Vec<PatchItem>,
-
    /// Current (selected) table index
-
    selected: Option<usize>,
    /// Patch statistics.
    stats: HashMap<String, usize>,
    /// Header columns
@@ -85,9 +79,7 @@ impl<'a> From<&State> for BrowserProps<'a> {
        ]);

        Self {
-
            mode: state.mode.clone(),
            patches,
-
            selected: state.browser.selected,
            stats,
            header: [
                Column::new(" ● ", Constraint::Length(3)),
@@ -218,45 +210,7 @@ impl View for Browser {
            }
        } else {
            match key {
-
                Key::Esc | Key::Ctrl('c') => Some(Message::Exit { selection: None }),
                Key::Char('/') => Some(Message::OpenSearch),
-
                Key::Char('\n') => {
-
                    let operation = match props.mode {
-
                        Mode::Operation => Some(PatchOperation::Show.to_string()),
-
                        Mode::Id => None,
-
                    };
-

-
                    props
-
                        .selected
-
                        .and_then(|selected| props.patches.get(selected))
-
                        .map(|patch| Message::Exit {
-
                            selection: Some(Selection {
-
                                operation,
-
                                ids: vec![patch.id],
-
                                args: vec![],
-
                            }),
-
                        })
-
                }
-
                Key::Char('c') => props
-
                    .selected
-
                    .and_then(|selected| props.patches.get(selected))
-
                    .map(|patch| Message::Exit {
-
                        selection: Some(Selection {
-
                            operation: Some(PatchOperation::Checkout.to_string()),
-
                            ids: vec![patch.id],
-
                            args: vec![],
-
                        }),
-
                    }),
-
                Key::Char('d') => props
-
                    .selected
-
                    .and_then(|selected| props.patches.get(selected))
-
                    .map(|patch| Message::Exit {
-
                        selection: Some(Selection {
-
                            operation: Some(PatchOperation::Diff.to_string()),
-
                            ids: vec![patch.id],
-
                            args: vec![],
-
                        }),
-
                    }),
                _ => {
                    self.patches.handle_event(key);
                    None