mirror of
https://seed.radicle.dev/rad:z39mP9rQAaGmERfUMPULfPUi473tY.git
synced 2026-11-03 18:30:41 +08:00
patch: Fix and clean up selection state
This commit is contained in:
@@ -53,7 +53,6 @@ impl Default for UIState {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct State {
|
||||
patches: Vec<PatchItem>,
|
||||
selected: Option<PatchItem>,
|
||||
mode: Mode,
|
||||
search: store::StateValue<String>,
|
||||
ui: UIState,
|
||||
@@ -73,11 +72,8 @@ impl TryFrom<&Context> for State {
|
||||
}
|
||||
}
|
||||
|
||||
let selected = items.first().cloned();
|
||||
|
||||
Ok(Self {
|
||||
patches: items,
|
||||
selected,
|
||||
mode: context.mode.clone(),
|
||||
search: store::StateValue::new(context.filter.to_string()),
|
||||
ui: UIState::default(),
|
||||
@@ -87,7 +83,6 @@ impl TryFrom<&Context> for State {
|
||||
|
||||
pub enum Action {
|
||||
Exit { selection: Option<Selection> },
|
||||
Select { item: PatchItem },
|
||||
PageSize(usize),
|
||||
OpenSearch,
|
||||
UpdateSearch { value: String },
|
||||
@@ -103,10 +98,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
|
||||
|
||||
@@ -32,7 +32,6 @@ use crate::tui_patch::common::PatchOperation;
|
||||
use super::{Action, State};
|
||||
|
||||
pub struct ListPageProps {
|
||||
selected: Option<PatchItem>,
|
||||
mode: Mode,
|
||||
show_search: bool,
|
||||
show_help: bool,
|
||||
@@ -41,7 +40,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,
|
||||
@@ -108,45 +106,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 operation = match self.props.mode {
|
||||
Mode::Operation => Some(PatchOperation::Show.to_string()),
|
||||
Mode::Id => None,
|
||||
};
|
||||
let _ = self.action_tx.send(Action::Exit {
|
||||
selection: Some(Selection {
|
||||
operation,
|
||||
ids: vec![selected.id],
|
||||
args: vec![],
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
Key::Char('c') => {
|
||||
if let Some(selected) = &self.props.selected {
|
||||
let selection = Selection {
|
||||
operation: Some(PatchOperation::Checkout.to_string()),
|
||||
ids: vec![selected.id],
|
||||
args: vec![],
|
||||
};
|
||||
let _ = self.action_tx.send(Action::Exit {
|
||||
selection: Some(selection),
|
||||
});
|
||||
}
|
||||
}
|
||||
Key::Char('d') => {
|
||||
if let Some(selected) = &self.props.selected {
|
||||
let selection = Selection {
|
||||
operation: Some(PatchOperation::Diff.to_string()),
|
||||
ids: vec![selected.id],
|
||||
args: vec![],
|
||||
};
|
||||
let _ = self.action_tx.send(Action::Exit {
|
||||
selection: Some(selection),
|
||||
});
|
||||
}
|
||||
}
|
||||
Key::Char('/') => {
|
||||
let _ = self.action_tx.send(Action::OpenSearch);
|
||||
}
|
||||
@@ -214,6 +173,7 @@ impl<'a> Render<()> for ListPage<'a> {
|
||||
}
|
||||
|
||||
struct PatchesProps {
|
||||
mode: Mode,
|
||||
patches: Vec<PatchItem>,
|
||||
search: StateValue<String>,
|
||||
stats: HashMap<String, usize>,
|
||||
@@ -263,6 +223,7 @@ impl From<&State> for PatchesProps {
|
||||
]);
|
||||
|
||||
Self {
|
||||
mode: state.mode.clone(),
|
||||
patches,
|
||||
search: state.search.clone(),
|
||||
widths: [
|
||||
@@ -357,18 +318,61 @@ impl Widget<State, Action> for Patches {
|
||||
Key::End => {
|
||||
self.table.end(self.props.patches.len());
|
||||
}
|
||||
Key::Char('\n') => {
|
||||
let operation = match self.props.mode {
|
||||
Mode::Operation => Some(PatchOperation::Show.to_string()),
|
||||
Mode::Id => None,
|
||||
};
|
||||
|
||||
self.table
|
||||
.selected()
|
||||
.and_then(|selected| self.props.patches.get(selected))
|
||||
.and_then(|patch| {
|
||||
self.action_tx
|
||||
.send(Action::Exit {
|
||||
selection: Some(Selection {
|
||||
operation,
|
||||
ids: vec![patch.id],
|
||||
args: vec![],
|
||||
}),
|
||||
})
|
||||
.ok()
|
||||
});
|
||||
}
|
||||
Key::Char('c') => {
|
||||
self.table
|
||||
.selected()
|
||||
.and_then(|selected| self.props.patches.get(selected))
|
||||
.and_then(|patch| {
|
||||
self.action_tx
|
||||
.send(Action::Exit {
|
||||
selection: Some(Selection {
|
||||
operation: Some(PatchOperation::Checkout.to_string()),
|
||||
ids: vec![patch.id],
|
||||
args: vec![],
|
||||
}),
|
||||
})
|
||||
.ok()
|
||||
});
|
||||
}
|
||||
Key::Char('d') => {
|
||||
self.table
|
||||
.selected()
|
||||
.and_then(|selected| self.props.patches.get(selected))
|
||||
.and_then(|patch| {
|
||||
self.action_tx
|
||||
.send(Action::Exit {
|
||||
selection: Some(Selection {
|
||||
operation: Some(PatchOperation::Diff.to_string()),
|
||||
ids: vec![patch.id],
|
||||
args: vec![],
|
||||
}),
|
||||
})
|
||||
.ok()
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
self.table
|
||||
.selected()
|
||||
.and_then(|selected| self.props.patches.get(selected))
|
||||
.and_then(|patch| {
|
||||
self.action_tx
|
||||
.send(Action::Select {
|
||||
item: patch.clone(),
|
||||
})
|
||||
.ok()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user