added optional confirm message

This commit is contained in:
Uber Veng
2026-03-14 03:27:43 +07:00
parent f958e704f6
commit 533df4a476
4 changed files with 58 additions and 22 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
/target /target
*txt

View File

@@ -35,7 +35,11 @@ pub struct App {
} }
pub enum Popup { pub enum Popup {
Confirming { action: Action, item_title: String }, Confirming {
action: Action,
item_title: String,
confirm_message: Option<String>,
},
ExecutingBashTerminal { child: tokio::process::Child }, ExecutingBashTerminal { child: tokio::process::Child },
ExecutingStructured { ExecutingStructured {
reply_tx: tokio::sync::mpsc::UnboundedSender<String>, reply_tx: tokio::sync::mpsc::UnboundedSender<String>,
@@ -153,7 +157,8 @@ impl App {
// Если есть popup, передаём ему // Если есть popup, передаём ему
if let Some(popup) = &mut self.popup { if let Some(popup) = &mut self.popup {
match popup { match popup {
Popup::Confirming { action, item_title } => { Popup::Confirming { action, item_title: _, confirm_message: _ } => {
// confirm_message можно не использовать здесь, но нужно изменить паттерн
match key.code { match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') => { KeyCode::Char('y') | KeyCode::Char('Y') => {
let action = action.clone(); let action = action.clone();
@@ -264,11 +269,12 @@ impl App {
} }
} }
MenuItemKind::Action { action } => { MenuItemKind::Action { action } => {
// Если требуется подтверждение
if action.confirm() { if action.confirm() {
let confirm_message = action.confirm_message(); // забираем до перемещения
self.popup = Some(Popup::Confirming { self.popup = Some(Popup::Confirming {
action, action, // перемещаем
item_title: item.title, item_title: item.title,
confirm_message,
}); });
} else { } else {
self.run_action(action).await?; self.run_action(action).await?;
@@ -284,6 +290,7 @@ impl App {
script, script,
interaction, interaction,
confirm: _, confirm: _,
confirm_message: _,
} => match interaction { } => match interaction {
InteractionMode::Terminal => { InteractionMode::Terminal => {
// Запуск в PTY (упрощённо) // Запуск в PTY (упрощённо)
@@ -298,6 +305,7 @@ impl App {
filename: _, filename: _,
target_dir: _, target_dir: _,
confirm: _, confirm: _,
confirm_message: _,
} => { } => {
// Заглушка // Заглушка
self.popup = Some(Popup::Message { self.popup = Some(Popup::Message {
@@ -363,14 +371,3 @@ impl App {
Ok(()) Ok(())
} }
} }
impl Action {
fn confirm(&self) -> bool {
match self {
Action::Bash { confirm, .. } => *confirm,
Action::Download { confirm, .. } => *confirm,
Action::DownloadAndRun { confirm, .. } => *confirm,
Action::HttpRequest { confirm, .. } => *confirm,
}
}
}

View File

@@ -32,6 +32,8 @@ pub enum Action {
interaction: InteractionMode, interaction: InteractionMode,
#[serde(default)] #[serde(default)]
confirm: bool, confirm: bool,
#[serde(default)]
confirm_message: Option<String>,
}, },
Download { Download {
url: String, url: String,
@@ -39,6 +41,8 @@ pub enum Action {
target_dir: Option<String>, target_dir: Option<String>,
#[serde(default)] #[serde(default)]
confirm: bool, confirm: bool,
#[serde(default)]
confirm_message: Option<String>,
}, },
DownloadAndRun { DownloadAndRun {
url: String, url: String,
@@ -48,14 +52,18 @@ pub enum Action {
keep_file: bool, keep_file: bool,
#[serde(default)] #[serde(default)]
confirm: bool, confirm: bool,
#[serde(default)]
confirm_message: Option<String>,
}, },
HttpRequest { HttpRequest {
method: HttpMethod, method: HttpMethod,
url: String, url: String,
headers: std::collections::HashMap<String, String>, headers: HashMap<String, String>,
body: Option<String>, body: Option<String>,
#[serde(default)] #[serde(default)]
confirm: bool, confirm: bool,
#[serde(default)]
confirm_message: Option<String>,
}, },
} }
@@ -78,3 +86,25 @@ pub enum HttpMethod {
Put, Put,
Delete, Delete,
} }
impl Action {
// Уже существующий метод confirm
pub fn confirm(&self) -> bool {
match self {
Action::Bash { confirm, .. } => *confirm,
Action::Download { confirm, .. } => *confirm,
Action::DownloadAndRun { confirm, .. } => *confirm,
Action::HttpRequest { confirm, .. } => *confirm,
}
}
// Добавляем новый метод
pub fn confirm_message(&self) -> Option<String> {
match self {
Action::Bash { confirm_message, .. } => confirm_message.clone(),
Action::Download { confirm_message, .. } => confirm_message.clone(),
Action::DownloadAndRun { confirm_message, .. } => confirm_message.clone(),
Action::HttpRequest { confirm_message, .. } => confirm_message.clone(),
}
}
}

View File

@@ -70,13 +70,21 @@ fn render_popup(f: &mut Frame, popup: &mut Popup) {
f.render_widget(Clear, popup_area); f.render_widget(Clear, popup_area);
match popup { match popup {
Popup::Confirming { action: _, item_title } => { Popup::Confirming { action: _, item_title, confirm_message } => {
let block = Block::default().borders(Borders::ALL).title("Подтверждение"); let block = Block::default().borders(Borders::ALL).title("Подтверждение");
let text = vec![ let text = if let Some(msg) = confirm_message {
Line::from(format!("Запустить '{}'?", item_title)), vec![
Line::from(""), Line::from(msg.as_str()),
Line::from("Нажмите Y для подтверждения, N для отмены"), Line::from(""),
]; Line::from("Нажмите Y для подтверждения, N для отмены"),
]
} else {
vec![
Line::from(format!("Запустить '{}'?", item_title)),
Line::from(""),
Line::from("Нажмите Y для подтверждения, N для отмены"),
]
};
let paragraph = Paragraph::new(text) let paragraph = Paragraph::new(text)
.block(block) .block(block)
.alignment(Alignment::Center) .alignment(Alignment::Center)