diff --git a/bin/commands/patch/select.rs b/bin/commands/patch/select.rs index 60e014b9..5e157d53 100644 --- a/bin/commands/patch/select.rs +++ b/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 }, + Quit, + Exit { operation: Option }, + ExitFromMode, Select { selected: Option }, OpenSearch, UpdateSearch { value: String }, @@ -134,7 +148,28 @@ impl store::State for State { fn update(&mut self, message: Message) -> Option> { 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) -> Widget 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) -> Widget Some(Message::Exit { selection: None }), + Key::Esc | Key::Ctrl('c') => Some(Message::Quit), Key::Char('?') => Some(Message::LeavePage), _ => None, }) diff --git a/bin/commands/patch/select/ui.rs b/bin/commands/patch/select/ui.rs index c6d8080b..feb67bf6 100644 --- a/bin/commands/patch/select/ui.rs +++ b/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; #[derive(Clone, Default)] pub struct BrowserProps<'a> { - /// Application mode: openation and id or id only. - mode: Mode, /// Filtered patches. patches: Vec, - /// Current (selected) table index - selected: Option, /// Patch statistics. stats: HashMap, /// 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