use crate::command::chat::app::{Action, AskAnswer, ChatApp, ChatMode, CursorDirection};
use crossterm::event::{KeyCode, KeyEvent};
pub fn handle_tool_confirm_mode(app: &mut ChatApp, key: KeyEvent) {
let is_ask = app.ui.tool_ask_mode;
if is_ask {
handle_ask_mode(app, key);
app.ui.msg_lines_cache = None;
return;
}
if app.ui.tool_interact_typing {
let action = match key.code {
KeyCode::Esc => {
app.ui.tool_interact_typing = false;
app.ui.msg_lines_cache = None;
return;
}
KeyCode::Enter => {
let input_text = app.ui.tool_interact_input.trim().to_string();
app.update(Action::RejectPendingToolWithReason(input_text));
app.ui.tool_interact_input.clear();
app.ui.tool_interact_cursor = 0;
app.ui.tool_interact_typing = false;
app.ui.msg_lines_cache = None;
return;
}
KeyCode::Backspace => Action::ToolInteractDeleteChar,
KeyCode::Left => {
if app.ui.tool_interact_cursor > 0 {
app.ui.tool_interact_cursor -= 1;
}
app.ui.msg_lines_cache = None;
return;
}
KeyCode::Right => {
let char_count = app.ui.tool_interact_input.chars().count();
if app.ui.tool_interact_cursor < char_count {
app.ui.tool_interact_cursor += 1;
}
app.ui.msg_lines_cache = None;
return;
}
KeyCode::Char(c) => Action::ToolInteractInputChar(c),
_ => {
app.ui.msg_lines_cache = None;
return;
}
};
app.update(action);
app.ui.msg_lines_cache = None;
return;
}
let action = match key.code {
KeyCode::Up => Action::ToolInteractNavigate(CursorDirection::Up),
KeyCode::Down => Action::ToolInteractNavigate(CursorDirection::Down),
KeyCode::Enter => Action::ToolInteractConfirm,
KeyCode::Esc => Action::RejectPendingTool,
_ => {
app.ui.msg_lines_cache = None;
return;
}
};
app.update(action);
app.ui.msg_lines_cache = None;
}
pub fn handle_agent_perm_confirm_mode(app: &mut ChatApp, key: KeyEvent) {
match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') | KeyCode::Enter => {
if let Some(req) = app.ui.pending_agent_perm.take() {
req.resolve(true);
}
app.ui.mode = ChatMode::Chat;
app.ui.msg_lines_cache = None;
}
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
if let Some(req) = app.ui.pending_agent_perm.take() {
req.resolve(false);
}
app.ui.mode = ChatMode::Chat;
app.ui.msg_lines_cache = None;
}
_ => {}
}
}
pub fn handle_plan_approval_confirm_mode(app: &mut ChatApp, key: KeyEvent) {
use crate::command::chat::app::types::PlanDecision;
match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') | KeyCode::Enter => {
if let Some(req) = app.ui.pending_plan_approval.take() {
req.resolve(PlanDecision::Approve);
}
app.ui.mode = ChatMode::Chat;
app.ui.msg_lines_cache = None;
}
KeyCode::Char('c') | KeyCode::Char('C') => {
if let Some(req) = app.ui.pending_plan_approval.take() {
req.resolve(PlanDecision::ApproveAndClearContext);
}
app.ui.mode = ChatMode::Chat;
app.ui.msg_lines_cache = None;
}
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
if let Some(req) = app.ui.pending_plan_approval.take() {
req.resolve(PlanDecision::Reject);
}
app.ui.mode = ChatMode::Chat;
app.ui.msg_lines_cache = None;
}
_ => {}
}
}
fn handle_ask_mode(app: &mut ChatApp, key: KeyEvent) {
let total_questions = app.ui.tool_ask_questions.len();
if total_questions == 0 {
return;
}
if app.ui.tool_interact_typing {
let action = match key.code {
KeyCode::Esc => {
app.ui.tool_interact_typing = false;
app.ui.tool_interact_input.clear();
app.ui.tool_interact_cursor = 0;
return;
}
KeyCode::Enter => {
if app.ui.tool_interact_input.trim().is_empty() {
return;
}
Action::AskSubmitAnswer
}
KeyCode::Backspace => Action::AskDeleteChar,
KeyCode::Left => {
if app.ui.tool_interact_cursor > 0 {
app.ui.tool_interact_cursor -= 1;
}
return;
}
KeyCode::Right => {
let char_count = app.ui.tool_interact_input.chars().count();
if app.ui.tool_interact_cursor < char_count {
app.ui.tool_interact_cursor += 1;
}
return;
}
KeyCode::Char(c) => Action::AskInputChar(c),
_ => return,
};
app.update(action);
return;
}
let cur_q = match app.ui.tool_ask_questions.get(app.ui.tool_ask_current_idx) {
Some(q) => q,
None => return,
};
let is_multi = cur_q.multi_select;
let action = match key.code {
KeyCode::Up => Action::AskOptionNavigate(CursorDirection::Up),
KeyCode::Down => Action::AskOptionNavigate(CursorDirection::Down),
KeyCode::Char(' ') if is_multi => Action::AskToggleMultiSelect,
KeyCode::Enter => {
let cursor = app.ui.tool_ask_cursor;
if cursor == cur_q.options.len() {
app.ui.tool_interact_typing = true;
app.ui.tool_interact_input.clear();
app.ui.tool_interact_cursor = 0;
return;
} else if is_multi {
let selected: Vec<usize> = app
.ui
.tool_ask_selections
.iter()
.enumerate()
.filter(|(i, sel)| **sel && *i < cur_q.options.len())
.map(|(i, _)| i)
.collect();
if selected.is_empty() {
app.ask_submit_answer(AskAnswer::Selected(vec![cursor]));
} else {
app.ask_submit_answer(AskAnswer::Selected(selected));
}
return;
} else {
app.ask_submit_answer(AskAnswer::Selected(vec![cursor]));
return;
}
}
KeyCode::Left | KeyCode::BackTab => Action::AskNavigate(CursorDirection::Up),
KeyCode::Right | KeyCode::Tab => Action::AskNavigate(CursorDirection::Down),
KeyCode::Esc => Action::AskCancel,
KeyCode::PageUp => Action::PageScroll(CursorDirection::Up),
KeyCode::PageDown => Action::PageScroll(CursorDirection::Down),
KeyCode::Char(c) => {
let free_idx = cur_q.options.len();
app.ui.tool_ask_cursor = free_idx;
app.ui.tool_interact_typing = true;
app.ui.tool_interact_input.clear();
app.ui.tool_interact_cursor = 0;
app.update(Action::AskInputChar(c));
return;
}
_ => return,
};
app.update(action);
}