// src/modes/general/navigation.rs use crossterm::event::KeyEvent; use crate::config::binds::config::Config; use crate::state::app::state::AppState; use crate::pages::routing::{Router, Page}; use crate::pages::forms::FormState; use crate::ui::handlers::context::UiContext; use crate::modes::handlers::event::EventOutcome; use crate::modes::general::command_navigation::{handle_command_navigation_event, NavigationState}; use canvas::DataProvider; use anyhow::Result; pub async fn handle_navigation_event( key: KeyEvent, config: &Config, app_state: &mut AppState, router: &mut Router, command_mode: &mut bool, command_input: &mut String, command_message: &mut String, navigation_state: &mut NavigationState, ) -> Result { // Handle command navigation first if active if navigation_state.active { return handle_command_navigation_event(navigation_state, key, config).await; } if let Some(action) = config.get_general_action(key.code, key.modifiers) { match action { "up" => { up(app_state, router); return Ok(EventOutcome::Ok(String::new())); } "down" => { down(app_state, router); return Ok(EventOutcome::Ok(String::new())); } "next_option" => { next_option(app_state, router); return Ok(EventOutcome::Ok(String::new())); } "previous_option" => { previous_option(app_state, router); return Ok(EventOutcome::Ok(String::new())); } "next_field" => { if let Some(fs) = app_state.form_state_mut() { next_field(fs); } return Ok(EventOutcome::Ok(String::new())); } "prev_field" => { if let Some(fs) = app_state.form_state_mut() { prev_field(fs); } return Ok(EventOutcome::Ok(String::new())); } "enter_command_mode" => { handle_enter_command_mode(command_mode, command_input, command_message); return Ok(EventOutcome::Ok(String::new())); } "select" => { let (context, index) = match &router.current { Page::Intro(state) => (UiContext::Intro, state.selected_option), Page::Login(_) if app_state.ui.focus_outside_canvas => { (UiContext::Login, app_state.focused_button_index) } Page::Register(_) if app_state.ui.focus_outside_canvas => { (UiContext::Register, app_state.focused_button_index) } Page::Admin(state) => { (UiContext::Admin, state.get_selected_index().unwrap_or(0)) } _ if app_state.ui.dialog.dialog_show => { (UiContext::Dialog, app_state.ui.dialog.dialog_active_button_index) } _ => return Ok(EventOutcome::Ok("Select (No Action)".to_string())), }; return Ok(EventOutcome::ButtonSelected { context, index }); } _ => {} } } Ok(EventOutcome::Ok(String::new())) } pub fn up(app_state: &mut AppState, router: &mut Router) { match &mut router.current { Page::Login(page) if app_state.ui.focus_outside_canvas => { if app_state.focused_button_index == 0 { app_state.ui.focus_outside_canvas = false; let last_field_index = page.state.field_count().saturating_sub(1); page.state.set_current_field(last_field_index); } else { app_state.focused_button_index = app_state.focused_button_index.saturating_sub(1); } } Page::Register(state) if app_state.ui.focus_outside_canvas => { if app_state.focused_button_index == 0 { app_state.ui.focus_outside_canvas = false; let last_field_index = state.field_count().saturating_sub(1); state.set_current_field(last_field_index); } else { app_state.focused_button_index = app_state.focused_button_index.saturating_sub(1); } } Page::Intro(state) => state.previous_option(), Page::Admin(state) => state.previous(), _ => {} } } pub fn down(app_state: &mut AppState, router: &mut Router) { match &mut router.current { Page::Login(_) | Page::Register(_) if app_state.ui.focus_outside_canvas => { let num_general_elements = 2; if app_state.focused_button_index < num_general_elements - 1 { app_state.focused_button_index += 1; } } Page::Intro(state) => state.next_option(), Page::Admin(state) => state.next(), _ => {} } } pub fn next_option(app_state: &mut AppState, router: &mut Router) { match &mut router.current { Page::Intro(state) => state.next_option(), Page::Admin(_) => { let option_count = app_state.profile_tree.profiles.len(); if option_count > 0 { app_state.focused_button_index = (app_state.focused_button_index + 1) % option_count; } } _ => {} } } pub fn previous_option(app_state: &mut AppState, router: &mut Router) { match &mut router.current { Page::Intro(state) => state.previous_option(), Page::Admin(_) => { let option_count = app_state.profile_tree.profiles.len(); if option_count > 0 { app_state.focused_button_index = if app_state.focused_button_index == 0 { option_count.saturating_sub(1) } else { app_state.focused_button_index - 1 }; } } _ => {} } } pub fn next_field(form_state: &mut FormState) { if !form_state.fields.is_empty() { form_state.current_field = (form_state.current_field + 1) % form_state.fields.len(); } } pub fn prev_field(form_state: &mut FormState) { if !form_state.fields.is_empty() { if form_state.current_field == 0 { form_state.current_field = form_state.fields.len() - 1; } else { form_state.current_field -= 1; } } } pub fn handle_enter_command_mode( command_mode: &mut bool, command_input: &mut String, command_message: &mut String, ) { *command_mode = true; command_input.clear(); command_message.clear(); }