use crate::{
components::{
popup_paragraph, visibility_blocking, CommandBlocking,
CommandInfo, Component, DrawableComponent, EventState,
},
keys::{key_match, SharedKeyConfig},
queue::{Action, InternalEvent, Queue},
strings, ui,
};
use anyhow::Result;
use crossterm::event::Event;
use std::borrow::Cow;
use tui::{
backend::Backend, layout::Rect, text::Text, widgets::Clear, Frame,
};
use ui::style::SharedTheme;
pub struct ConfirmComponent {
target: Option<Action>,
visible: bool,
queue: Queue,
theme: SharedTheme,
key_config: SharedKeyConfig,
}
impl DrawableComponent for ConfirmComponent {
fn draw<B: Backend>(
&self,
f: &mut Frame<B>,
_rect: Rect,
) -> Result<()> {
if self.visible {
let (title, msg) = self.get_text();
let txt = Text::styled(
Cow::from(msg),
self.theme.text_danger(),
);
let area = ui::centered_rect(50, 20, f.size());
f.render_widget(Clear, area);
f.render_widget(
popup_paragraph(&title, txt, &self.theme, true, true),
area,
);
}
Ok(())
}
}
impl Component for ConfirmComponent {
fn commands(
&self,
out: &mut Vec<CommandInfo>,
_force_all: bool,
) -> CommandBlocking {
out.push(CommandInfo::new(
strings::commands::confirm_action(&self.key_config),
true,
self.visible,
));
out.push(CommandInfo::new(
strings::commands::close_popup(&self.key_config),
true,
self.visible,
));
visibility_blocking(self)
}
fn event(&mut self, ev: &Event) -> Result<EventState> {
if self.visible {
if let Event::Key(e) = ev {
if key_match(e, self.key_config.keys.exit_popup) {
self.hide();
} else if key_match(e, self.key_config.keys.enter) {
self.confirm();
}
return Ok(EventState::Consumed);
}
}
Ok(EventState::NotConsumed)
}
fn is_visible(&self) -> bool {
self.visible
}
fn hide(&mut self) {
self.visible = false;
}
fn show(&mut self) -> Result<()> {
self.visible = true;
Ok(())
}
}
impl ConfirmComponent {
pub fn new(
queue: Queue,
theme: SharedTheme,
key_config: SharedKeyConfig,
) -> Self {
Self {
target: None,
visible: false,
queue,
theme,
key_config,
}
}
pub fn open(&mut self, a: Action) -> Result<()> {
self.target = Some(a);
self.show()?;
Ok(())
}
pub fn confirm(&mut self) {
if let Some(a) = self.target.take() {
self.queue.push(InternalEvent::ConfirmedAction(a));
}
self.hide();
}
fn get_text(&self) -> (String, String) {
if let Some(ref a) = self.target {
return match a {
Action::Reset(_) => (
strings::confirm_title_reset(),
strings::confirm_msg_reset(),
),
Action::StashDrop(ids) => (
strings::confirm_title_stashdrop(
&self.key_config,ids.len()>1
),
strings::confirm_msg_stashdrop(&self.key_config,ids),
),
Action::StashPop(_) => (
strings::confirm_title_stashpop(&self.key_config),
strings::confirm_msg_stashpop(&self.key_config),
),
Action::ResetHunk(_, _) => (
strings::confirm_title_reset(),
strings::confirm_msg_resethunk(&self.key_config),
),
Action::ResetLines(_, lines) => (
strings::confirm_title_reset(),
strings::confirm_msg_reset_lines(lines.len()),
),
Action::DeleteLocalBranch(branch_ref) => (
strings::confirm_title_delete_branch(
&self.key_config,
),
strings::confirm_msg_delete_branch(
&self.key_config,
branch_ref,
),
),
Action::DeleteRemoteBranch(branch_ref) => (
strings::confirm_title_delete_remote_branch(
&self.key_config,
),
strings::confirm_msg_delete_remote_branch(
&self.key_config,
branch_ref,
),
),
Action::DeleteTag(tag_name) => (
strings::confirm_title_delete_tag(
&self.key_config,
),
strings::confirm_msg_delete_tag(
&self.key_config,
tag_name,
),
),
Action::DeleteRemoteTag(_tag_name,remote) => (
strings::confirm_title_delete_tag_remote(),
strings::confirm_msg_delete_tag_remote(remote),
),
Action::ForcePush(branch, _force) => (
strings::confirm_title_force_push(
&self.key_config,
),
strings::confirm_msg_force_push(
&self.key_config,
branch.rsplit('/').next().expect("There was no / in the head reference which is impossible in git"),
),
),
Action::PullMerge{incoming,rebase} => (
strings::confirm_title_merge(&self.key_config,*rebase),
strings::confirm_msg_merge(&self.key_config,*incoming,*rebase),
),
Action::AbortMerge => (
strings::confirm_title_abortmerge(),
strings::confirm_msg_revertchanges(),
),
Action::AbortRebase => (
strings::confirm_title_abortrebase(),
strings::confirm_msg_abortrebase(),
),
Action::AbortRevert => (
strings::confirm_title_abortrevert(),
strings::confirm_msg_revertchanges(),
),
};
}
(String::new(), String::new())
}
}