239 lines
11 KiB
Rust
239 lines
11 KiB
Rust
// src/functions/modes/navigation/add_logic_nav.rs
|
|
use crate::config::binds::config::{Config, EditorKeybindingMode};
|
|
use crate::state::{
|
|
app::state::AppState,
|
|
pages::add_logic::{AddLogicFocus, AddLogicState},
|
|
app::buffer::AppView,
|
|
app::buffer::BufferState,
|
|
};
|
|
use crossterm::event::{KeyEvent, KeyCode, KeyModifiers};
|
|
use crate::services::GrpcClient;
|
|
use tokio::sync::mpsc;
|
|
use anyhow::Result;
|
|
use crate::components::common::text_editor::TextEditor;
|
|
|
|
pub type SaveLogicResultSender = mpsc::Sender<Result<String>>;
|
|
|
|
pub fn handle_add_logic_navigation(
|
|
key_event: KeyEvent,
|
|
config: &Config,
|
|
app_state: &mut AppState,
|
|
add_logic_state: &mut AddLogicState,
|
|
is_edit_mode: &mut bool,
|
|
buffer_state: &mut BufferState,
|
|
grpc_client: GrpcClient,
|
|
save_logic_sender: SaveLogicResultSender,
|
|
command_message: &mut String,
|
|
) -> bool {
|
|
// === FULLSCREEN SCRIPT EDITING - COMPLETE ISOLATION ===
|
|
if add_logic_state.current_focus == AddLogicFocus::InsideScriptContent {
|
|
let mut editor_borrow = add_logic_state.script_content_editor.borrow_mut();
|
|
|
|
// Handle ONLY Escape to exit fullscreen mode
|
|
if key_event.code == KeyCode::Esc && key_event.modifiers == KeyModifiers::NONE {
|
|
match add_logic_state.editor_keybinding_mode {
|
|
EditorKeybindingMode::Vim => {
|
|
if *is_edit_mode {
|
|
// First escape: try to go to Vim Normal mode
|
|
TextEditor::handle_input(
|
|
&mut editor_borrow,
|
|
key_event,
|
|
&add_logic_state.editor_keybinding_mode,
|
|
&mut add_logic_state.vim_state,
|
|
);
|
|
if TextEditor::is_vim_normal_mode(&add_logic_state.vim_state) {
|
|
*is_edit_mode = false;
|
|
*command_message = "VIM: Normal Mode. Esc again to exit script.".to_string();
|
|
}
|
|
} else {
|
|
// Second escape: exit fullscreen
|
|
add_logic_state.current_focus = AddLogicFocus::ScriptContentPreview;
|
|
app_state.ui.focus_outside_canvas = true;
|
|
*is_edit_mode = false;
|
|
*command_message = "Exited script editing.".to_string();
|
|
}
|
|
}
|
|
_ => {
|
|
if *is_edit_mode {
|
|
*is_edit_mode = false;
|
|
*command_message = "Exited script edit. Esc again to exit script.".to_string();
|
|
} else {
|
|
// Exit fullscreen
|
|
add_logic_state.current_focus = AddLogicFocus::ScriptContentPreview;
|
|
app_state.ui.focus_outside_canvas = true;
|
|
*is_edit_mode = false;
|
|
*command_message = "Exited script editing.".to_string();
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// ALL OTHER KEYS: Pass directly to textarea without any interference
|
|
let changed = TextEditor::handle_input(
|
|
&mut editor_borrow,
|
|
key_event,
|
|
&add_logic_state.editor_keybinding_mode,
|
|
&mut add_logic_state.vim_state,
|
|
);
|
|
if changed {
|
|
add_logic_state.has_unsaved_changes = true;
|
|
}
|
|
|
|
// Update edit mode status for Vim
|
|
if add_logic_state.editor_keybinding_mode == EditorKeybindingMode::Vim {
|
|
*is_edit_mode = !TextEditor::is_vim_normal_mode(&add_logic_state.vim_state);
|
|
}
|
|
|
|
return true; // Always consume the event in fullscreen mode
|
|
}
|
|
// === END FULLSCREEN ISOLATION ===
|
|
|
|
// Regular navigation logic for non-fullscreen elements
|
|
let action = config.get_general_action(key_event.code, key_event.modifiers);
|
|
let current_focus = add_logic_state.current_focus;
|
|
let mut handled = true;
|
|
let mut new_focus = current_focus;
|
|
|
|
match action.as_deref() {
|
|
Some("exit_table_scroll") => {
|
|
// This shouldn't happen since we handle InsideScriptContent above
|
|
handled = false;
|
|
}
|
|
Some("move_up") => {
|
|
match current_focus {
|
|
AddLogicFocus::InputLogicName => {
|
|
// Stay at top
|
|
}
|
|
AddLogicFocus::InputTargetColumn => new_focus = AddLogicFocus::InputLogicName,
|
|
AddLogicFocus::InputDescription => new_focus = AddLogicFocus::InputTargetColumn,
|
|
AddLogicFocus::ScriptContentPreview => new_focus = AddLogicFocus::InputDescription,
|
|
AddLogicFocus::SaveButton => new_focus = AddLogicFocus::ScriptContentPreview,
|
|
AddLogicFocus::CancelButton => new_focus = AddLogicFocus::SaveButton,
|
|
_ => handled = false,
|
|
}
|
|
}
|
|
Some("move_down") => {
|
|
match current_focus {
|
|
AddLogicFocus::InputLogicName => new_focus = AddLogicFocus::InputTargetColumn,
|
|
AddLogicFocus::InputTargetColumn => new_focus = AddLogicFocus::InputDescription,
|
|
AddLogicFocus::InputDescription => {
|
|
add_logic_state.last_canvas_field = 2;
|
|
new_focus = AddLogicFocus::ScriptContentPreview;
|
|
},
|
|
AddLogicFocus::ScriptContentPreview => new_focus = AddLogicFocus::SaveButton,
|
|
AddLogicFocus::SaveButton => new_focus = AddLogicFocus::CancelButton,
|
|
AddLogicFocus::CancelButton => {
|
|
// Stay at bottom
|
|
}
|
|
_ => handled = false,
|
|
}
|
|
}
|
|
Some("next_option") => {
|
|
match current_focus {
|
|
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription =>
|
|
{ new_focus = AddLogicFocus::ScriptContentPreview; }
|
|
AddLogicFocus::ScriptContentPreview => new_focus = AddLogicFocus::SaveButton,
|
|
AddLogicFocus::SaveButton => new_focus = AddLogicFocus::CancelButton,
|
|
AddLogicFocus::CancelButton => { /* Stay at last */ }
|
|
_ => handled = false,
|
|
}
|
|
}
|
|
Some("previous_option") => {
|
|
match current_focus {
|
|
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription =>
|
|
{ /* Stay at first */ }
|
|
AddLogicFocus::ScriptContentPreview => new_focus = AddLogicFocus::InputDescription,
|
|
AddLogicFocus::SaveButton => new_focus = AddLogicFocus::ScriptContentPreview,
|
|
AddLogicFocus::CancelButton => new_focus = AddLogicFocus::SaveButton,
|
|
_ => handled = false,
|
|
}
|
|
}
|
|
Some("next_field") => {
|
|
new_focus = match current_focus {
|
|
AddLogicFocus::InputLogicName => AddLogicFocus::InputTargetColumn,
|
|
AddLogicFocus::InputTargetColumn => AddLogicFocus::InputDescription,
|
|
AddLogicFocus::InputDescription => AddLogicFocus::ScriptContentPreview,
|
|
AddLogicFocus::ScriptContentPreview => AddLogicFocus::SaveButton,
|
|
AddLogicFocus::SaveButton => AddLogicFocus::CancelButton,
|
|
AddLogicFocus::CancelButton => AddLogicFocus::InputLogicName,
|
|
_ => current_focus,
|
|
};
|
|
}
|
|
Some("prev_field") => {
|
|
new_focus = match current_focus {
|
|
AddLogicFocus::InputLogicName => AddLogicFocus::CancelButton,
|
|
AddLogicFocus::InputTargetColumn => AddLogicFocus::InputLogicName,
|
|
AddLogicFocus::InputDescription => AddLogicFocus::InputTargetColumn,
|
|
AddLogicFocus::ScriptContentPreview => AddLogicFocus::InputDescription,
|
|
AddLogicFocus::SaveButton => AddLogicFocus::ScriptContentPreview,
|
|
AddLogicFocus::CancelButton => AddLogicFocus::SaveButton,
|
|
_ => current_focus,
|
|
};
|
|
}
|
|
Some("select") => {
|
|
match current_focus {
|
|
AddLogicFocus::ScriptContentPreview => {
|
|
new_focus = AddLogicFocus::InsideScriptContent;
|
|
*is_edit_mode = false; // Start in preview mode
|
|
app_state.ui.focus_outside_canvas = false; // Script is like canvas
|
|
let mode_hint = match add_logic_state.editor_keybinding_mode {
|
|
EditorKeybindingMode::Vim => "VIM mode - 'i'/'a'/'o' to edit",
|
|
_ => "Enter/Ctrl+E to edit",
|
|
};
|
|
*command_message = format!("Fullscreen script editing. {} or Esc to exit.", mode_hint);
|
|
}
|
|
AddLogicFocus::SaveButton => {
|
|
*command_message = "Save logic action".to_string();
|
|
}
|
|
AddLogicFocus::CancelButton => {
|
|
buffer_state.update_history(AppView::Admin);
|
|
app_state.ui.show_add_logic = false;
|
|
*command_message = "Cancelled Add Logic".to_string();
|
|
*is_edit_mode = false;
|
|
}
|
|
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription => {
|
|
*is_edit_mode = !*is_edit_mode;
|
|
*command_message = format!("Field edit mode: {}", if *is_edit_mode { "ON" } else { "OFF" });
|
|
}
|
|
_ => handled = false,
|
|
}
|
|
}
|
|
Some("toggle_edit_mode") => {
|
|
match current_focus {
|
|
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription => {
|
|
*is_edit_mode = !*is_edit_mode;
|
|
*command_message = format!("Canvas field edit mode: {}", if *is_edit_mode { "ON" } else { "OFF" });
|
|
}
|
|
_ => {
|
|
*command_message = "Cannot toggle edit mode here.".to_string();
|
|
}
|
|
}
|
|
}
|
|
_ => handled = false,
|
|
}
|
|
|
|
if handled && current_focus != new_focus {
|
|
add_logic_state.current_focus = new_focus;
|
|
|
|
// Set edit mode and canvas focus based on new focus
|
|
let new_is_canvas_input_focus = matches!(new_focus,
|
|
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription
|
|
);
|
|
|
|
if new_is_canvas_input_focus {
|
|
// Entering canvas - start in readonly mode
|
|
*is_edit_mode = false;
|
|
app_state.ui.focus_outside_canvas = false;
|
|
} else {
|
|
// Outside canvas
|
|
app_state.ui.focus_outside_canvas = true;
|
|
if matches!(new_focus, AddLogicFocus::ScriptContentPreview) {
|
|
*is_edit_mode = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
handled
|
|
}
|