code cleanup

This commit is contained in:
filipriec
2025-05-31 23:02:09 +02:00
parent ea88c2686d
commit 6e2fc5349b
5 changed files with 316 additions and 214 deletions

View File

@@ -1,52 +1,50 @@
// src/modes/handlers/event.rs
use crossterm::event::{Event, KeyEvent};
use crossterm::cursor::SetCursorStyle;
use crate::services::grpc_client::GrpcClient;
use crate::services::auth::AuthClient;
use crate::config::binds::config::Config;
use crate::ui::handlers::rat_state::UiStateHandler;
use crate::ui::handlers::context::UiContext;
use crate::config::binds::key_sequences::KeySequenceTracker;
use crate::functions::common::buffer;
use anyhow::Result;
use crate::tui::{
terminal::core::TerminalCore,
functions::{
common::{form::SaveOutcome, login, register},
},
{intro, admin},
use crate::functions::modes::navigation::add_logic_nav;
use crate::functions::modes::navigation::add_logic_nav::SaveLogicResultSender;
use crate::functions::modes::navigation::add_table_nav::SaveTableResultSender;
use crate::functions::modes::navigation::{add_table_nav, admin_nav};
use crate::modes::general::command_navigation::{
handle_command_navigation_event, NavigationState, TableDependencyGraph,
};
use crate::modes::{
canvas::{common_mode, edit, read_only},
common::{command_mode, commands::CommandHandler},
general::{dialog, navigation},
handlers::mode_manager::{AppMode, ModeManager},
};
use crate::services::auth::AuthClient;
use crate::services::grpc_client::GrpcClient;
use crate::state::{
app::{
buffer::{AppView, BufferState},
highlight::HighlightState,
state::AppState,
buffer::{AppView, BufferState},
},
pages::{
auth::{AuthState, LoginState, RegisterState},
admin::AdminState,
auth::{AuthState, LoginState, RegisterState},
canvas_state::CanvasState,
form::FormState,
intro::IntroState,
},
};
use crate::modes::{
common::{command_mode, commands::CommandHandler},
handlers::mode_manager::{ModeManager, AppMode},
canvas::{edit, read_only, common_mode},
general::{navigation, dialog},
};
use crate::modes::general::command_navigation::{
handle_command_navigation_event, NavigationState, TableDependencyGraph,
};
use crate::functions::modes::navigation::{admin_nav, add_table_nav};
use crate::config::binds::key_sequences::KeySequenceTracker;
use tokio::sync::mpsc;
use crate::tui::functions::common::login::LoginResult;
use crate::tui::functions::common::register::RegisterResult;
use crate::functions::modes::navigation::add_table_nav::SaveTableResultSender;
use crate::functions::modes::navigation::add_logic_nav::SaveLogicResultSender;
use crate::functions::modes::navigation::add_logic_nav;
use crate::tui::{
functions::common::{form::SaveOutcome, login, register},
terminal::core::TerminalCore,
{admin, intro},
};
use crate::ui::handlers::context::UiContext;
use crate::ui::handlers::rat_state::UiStateHandler;
use anyhow::Result;
use crossterm::cursor::SetCursorStyle;
use crossterm::event::KeyCode;
use crossterm::event::{Event, KeyEvent};
use tokio::sync::mpsc;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventOutcome {
@@ -139,12 +137,10 @@ impl EventHandler {
// Handle active command navigation first
if current_mode == AppMode::General && self.navigation_state.active {
if let Event::Key(key_event) = event {
let outcome = handle_command_navigation_event(
&mut self.navigation_state,
key_event,
config,
).await?;
let outcome =
handle_command_navigation_event(&mut self.navigation_state, key_event, config)
.await?;
if !self.navigation_state.active {
self.command_message = outcome.get_message_if_ok();
current_mode = ModeManager::derive_mode(app_state, self, admin_state);
@@ -160,14 +156,23 @@ impl EventHandler {
let current_view = {
let ui = &app_state.ui;
if ui.show_intro { AppView::Intro }
else if ui.show_login { AppView::Login }
else if ui.show_register { AppView::Register }
else if ui.show_admin { AppView::Admin }
else if ui.show_add_logic { AppView::AddLogic }
else if ui.show_add_table { AppView::AddTable }
else if ui.show_form { AppView::Form }
else { AppView::Scratch }
if ui.show_intro {
AppView::Intro
} else if ui.show_login {
AppView::Login
} else if ui.show_register {
AppView::Register
} else if ui.show_admin {
AppView::Admin
} else if ui.show_add_logic {
AppView::AddLogic
} else if ui.show_add_table {
AppView::AddTable
} else if ui.show_form {
AppView::Form
} else {
AppView::Scratch
}
};
buffer_state.update_history(current_view);
@@ -175,11 +180,18 @@ impl EventHandler {
if let Event::Key(key_event) = event {
if let Some(dialog_result) = dialog::handle_dialog_event(
&Event::Key(key_event),
config, app_state, login_state, register_state, buffer_state, admin_state,
).await {
config,
app_state,
login_state,
register_state,
buffer_state,
admin_state,
)
.await
{
return dialog_result;
}
} else if let Event::Resize(_,_) = event {
} else if let Event::Resize(_, _) = event {
// Handle resize if needed
}
return Ok(EventOutcome::Ok(String::new()));
@@ -190,17 +202,33 @@ impl EventHandler {
let modifiers = key_event.modifiers;
if UiStateHandler::toggle_sidebar(&mut app_state.ui, config, key_code, modifiers) {
let message = format!("Sidebar {}", if app_state.ui.show_sidebar { "shown" } else { "hidden" });
let message = format!(
"Sidebar {}",
if app_state.ui.show_sidebar {
"shown"
} else {
"hidden"
}
);
return Ok(EventOutcome::Ok(message));
}
if UiStateHandler::toggle_buffer_list(&mut app_state.ui, config, key_code, modifiers) {
let message = format!("Buffer {}", if app_state.ui.show_buffer_list { "shown" } else { "hidden" });
let message = format!(
"Buffer {}",
if app_state.ui.show_buffer_list {
"shown"
} else {
"hidden"
}
);
return Ok(EventOutcome::Ok(message));
}
if !matches!(current_mode, AppMode::Edit | AppMode::Command) {
if let Some(action) = config.get_action_for_key_in_mode(
&config.keybindings.global, key_code, modifiers
&config.keybindings.global,
key_code,
modifiers,
) {
match action {
"next_buffer" => {
@@ -210,12 +238,15 @@ impl EventHandler {
}
"previous_buffer" => {
if buffer::switch_buffer(buffer_state, false) {
return Ok(EventOutcome::Ok("Switched to previous buffer".to_string()));
return Ok(EventOutcome::Ok(
"Switched to previous buffer".to_string(),
));
}
}
"close_buffer" => {
let current_table_name = Some("2025_customer");
let message = buffer_state.close_buffer_with_intro_fallback(current_table_name);
let message =
buffer_state.close_buffer_with_intro_fallback(current_table_name);
return Ok(EventOutcome::Ok(message));
}
_ => {}
@@ -287,7 +318,8 @@ impl EventHandler {
&mut self.command_input,
&mut self.command_message,
&mut self.navigation_state,
).await;
)
.await;
match nav_outcome {
Ok(EventOutcome::ButtonSelected { context, index }) => {
@@ -301,24 +333,36 @@ impl EventHandler {
}
format!("Intro Option {} selected", index)
}
UiContext::Login => {
match index {
0 => {
login::initiate_login(login_state, app_state, self.auth_client.clone(), self.login_result_sender.clone())
},
1 => login::back_to_main(login_state, app_state, buffer_state).await,
_ => "Invalid Login Option".to_string(),
UiContext::Login => match index {
0 => login::initiate_login(
login_state,
app_state,
self.auth_client.clone(),
self.login_result_sender.clone(),
),
1 => {
login::back_to_main(login_state, app_state, buffer_state)
.await
}
}
UiContext::Register => {
match index {
0 => {
register::initiate_registration(register_state, app_state, self.auth_client.clone(), self.register_result_sender.clone())
},
1 => register::back_to_login(register_state, app_state, buffer_state).await,
_ => "Invalid Login Option".to_string(),
_ => "Invalid Login Option".to_string(),
},
UiContext::Register => match index {
0 => register::initiate_registration(
register_state,
app_state,
self.auth_client.clone(),
self.register_result_sender.clone(),
),
1 => {
register::back_to_login(
register_state,
app_state,
buffer_state,
)
.await
}
}
_ => "Invalid Login Option".to_string(),
},
UiContext::Admin => {
admin::handle_admin_selection(app_state, admin_state);
format!("Admin Option {} selected", index)
@@ -334,53 +378,76 @@ impl EventHandler {
}
AppMode::ReadOnly => {
if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise")
if config.get_read_only_action_for_key(key_code, modifiers)
== Some("enter_highlight_mode_linewise")
&& ModeManager::can_enter_highlight_mode(current_mode)
{
let current_field_index = if app_state.ui.show_login { login_state.current_field() }
else if app_state.ui.show_register { register_state.current_field() }
else { form_state.current_field() };
self.highlight_state = HighlightState::Linewise { anchor_line: current_field_index };
let current_field_index = if app_state.ui.show_login {
login_state.current_field()
} else if app_state.ui.show_register {
register_state.current_field()
} else {
form_state.current_field()
};
self.highlight_state = HighlightState::Linewise {
anchor_line: current_field_index,
};
self.command_message = "-- LINE HIGHLIGHT --".to_string();
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode")
} else if config.get_read_only_action_for_key(key_code, modifiers)
== Some("enter_highlight_mode")
&& ModeManager::can_enter_highlight_mode(current_mode)
{
let current_field_index = if app_state.ui.show_login { login_state.current_field() }
else if app_state.ui.show_register { register_state.current_field() }
else { form_state.current_field() };
let current_cursor_pos = if app_state.ui.show_login { login_state.current_cursor_pos() }
else if app_state.ui.show_register { register_state.current_cursor_pos() }
else { form_state.current_cursor_pos() };
let current_field_index = if app_state.ui.show_login {
login_state.current_field()
} else if app_state.ui.show_register {
register_state.current_field()
} else {
form_state.current_field()
};
let current_cursor_pos = if app_state.ui.show_login {
login_state.current_cursor_pos()
} else if app_state.ui.show_register {
register_state.current_cursor_pos()
} else {
form_state.current_cursor_pos()
};
let anchor = (current_field_index, current_cursor_pos);
self.highlight_state = HighlightState::Characterwise { anchor };
self.command_message = "-- HIGHLIGHT --".to_string();
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_before")
&& ModeManager::can_enter_edit_mode(current_mode) {
} else if config
.get_read_only_action_for_key(key_code, modifiers)
.as_deref()
== Some("enter_edit_mode_before")
&& ModeManager::can_enter_edit_mode(current_mode)
{
self.is_edit_mode = true;
self.edit_mode_cooldown = true;
self.command_message = "Edit mode".to_string();
terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_after")
&& ModeManager::can_enter_edit_mode(current_mode) {
let current_input = if app_state.ui.show_login || app_state.ui.show_register{
} else if config
.get_read_only_action_for_key(key_code, modifiers)
.as_deref()
== Some("enter_edit_mode_after")
&& ModeManager::can_enter_edit_mode(current_mode)
{
let current_input = if app_state.ui.show_login || app_state.ui.show_register
{
login_state.get_current_input()
} else {
form_state.get_current_input()
};
let current_cursor_pos = if app_state.ui.show_login || app_state.ui.show_register{
login_state.current_cursor_pos()
} else {
form_state.current_cursor_pos()
};
let current_cursor_pos =
if app_state.ui.show_login || app_state.ui.show_register {
login_state.current_cursor_pos()
} else {
form_state.current_cursor_pos()
};
if !current_input.is_empty() && current_cursor_pos < current_input.len() {
if app_state.ui.show_login || app_state.ui.show_register{
if app_state.ui.show_login || app_state.ui.show_register {
login_state.set_current_cursor_pos(current_cursor_pos + 1);
self.ideal_cursor_column = login_state.current_cursor_pos();
} else {
@@ -394,13 +461,14 @@ impl EventHandler {
self.command_message = "Edit mode (after cursor)".to_string();
terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_command_mode")
&& ModeManager::can_enter_command_mode(current_mode) {
self.command_mode = true;
self.command_input.clear();
self.command_message.clear();
return Ok(EventOutcome::Ok(String::new()));
} else if config.get_read_only_action_for_key(key_code, modifiers)
== Some("enter_command_mode")
&& ModeManager::can_enter_command_mode(current_mode)
{
self.command_mode = true;
self.command_input.clear();
self.command_message.clear();
return Ok(EventOutcome::Ok(String::new()));
}
if let Some(action) = config.get_common_action(key_code, modifiers) {
@@ -418,8 +486,9 @@ impl EventHandler {
app_state,
current_position,
total_count,
).await;
},
)
.await;
}
_ => {}
}
}
@@ -440,28 +509,38 @@ impl EventHandler {
&mut self.command_message,
&mut self.edit_mode_cooldown,
&mut self.ideal_cursor_column,
).await?;
)
.await?;
return Ok(EventOutcome::Ok(message));
}
AppMode::Highlight => {
if config.get_highlight_action_for_key(key_code, modifiers) == Some("exit_highlight_mode") {
self.highlight_state = HighlightState::Off;
self.command_message = "Exited highlight mode".to_string();
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
else if config.get_highlight_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise") {
if let HighlightState::Characterwise { anchor } = self.highlight_state {
self.highlight_state = HighlightState::Linewise { anchor_line: anchor.0 };
self.command_message = "-- LINE HIGHLIGHT --".to_string();
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
if config.get_highlight_action_for_key(key_code, modifiers)
== Some("exit_highlight_mode")
{
self.highlight_state = HighlightState::Off;
self.command_message = "Exited highlight mode".to_string();
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
return Ok(EventOutcome::Ok(self.command_message.clone()));
} else if config.get_highlight_action_for_key(key_code, modifiers)
== Some("enter_highlight_mode_linewise")
{
if let HighlightState::Characterwise { anchor } = self.highlight_state {
self.highlight_state = HighlightState::Linewise {
anchor_line: anchor.0,
};
self.command_message = "-- LINE HIGHLIGHT --".to_string();
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
return Ok(EventOutcome::Ok("".to_string()));
}
}
let (_should_exit, message) = read_only::handle_read_only_event(
app_state, key_event, config, form_state, login_state,
app_state,
key_event,
config,
form_state,
login_state,
register_state,
&mut admin_state.add_table_state,
&mut admin_state.add_logic_state,
@@ -493,8 +572,9 @@ impl EventHandler {
app_state,
current_position,
total_count,
).await;
},
)
.await;
}
_ => {}
}
}
@@ -511,30 +591,52 @@ impl EventHandler {
total_count,
grpc_client,
app_state,
).await;
)
.await;
match edit_result {
Ok(edit::EditEventOutcome::ExitEditMode) => {
self.is_edit_mode = false;
self.edit_mode_cooldown = true;
let has_changes = if app_state.ui.show_login { login_state.has_unsaved_changes() }
else if app_state.ui.show_register { register_state.has_unsaved_changes() }
else { form_state.has_unsaved_changes() };
let has_changes = if app_state.ui.show_login {
login_state.has_unsaved_changes()
} else if app_state.ui.show_register {
register_state.has_unsaved_changes()
} else {
form_state.has_unsaved_changes()
};
self.command_message = if has_changes {
"Exited edit mode (unsaved changes remain)".to_string()
} else {
"Read-only mode".to_string()
};
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
let current_input = if app_state.ui.show_login { login_state.get_current_input() }
else if app_state.ui.show_register { register_state.get_current_input() }
else { form_state.get_current_input() };
let current_cursor_pos = if app_state.ui.show_login { login_state.current_cursor_pos() }
else if app_state.ui.show_register { register_state.current_cursor_pos() }
else { form_state.current_cursor_pos() };
if !current_input.is_empty() && current_cursor_pos >= current_input.len() {
let current_input = if app_state.ui.show_login {
login_state.get_current_input()
} else if app_state.ui.show_register {
register_state.get_current_input()
} else {
form_state.get_current_input()
};
let current_cursor_pos = if app_state.ui.show_login {
login_state.current_cursor_pos()
} else if app_state.ui.show_register {
register_state.current_cursor_pos()
} else {
form_state.current_cursor_pos()
};
if !current_input.is_empty()
&& current_cursor_pos >= current_input.len()
{
let new_pos = current_input.len() - 1;
let target_state: &mut dyn CanvasState = if app_state.ui.show_login { login_state } else if app_state.ui.show_register { register_state } else { form_state };
let target_state: &mut dyn CanvasState = if app_state.ui.show_login
{
login_state
} else if app_state.ui.show_register {
register_state
} else {
form_state
};
target_state.set_current_cursor_pos(new_pos);
self.ideal_cursor_column = new_pos;
}
@@ -564,10 +666,21 @@ impl EventHandler {
if config.is_command_execute(key_code, modifiers) {
let outcome = command_mode::handle_command_event(
key_event, config, app_state, login_state, register_state, form_state,
&mut self.command_input, &mut self.command_message,
grpc_client, command_handler, terminal, current_position, total_count,
).await?;
key_event,
config,
app_state,
login_state,
register_state,
form_state,
&mut self.command_input,
&mut self.command_message,
grpc_client,
command_handler,
terminal,
current_position,
total_count,
)
.await?;
self.command_mode = false;
self.key_sequence_tracker.reset();
let new_mode = ModeManager::derive_mode(app_state, self, admin_state);
@@ -582,14 +695,19 @@ impl EventHandler {
}
if let KeyCode::Char(c) = key_code {
if c == 'f' { // Assuming 'f' is part of the sequence, e.g. ":f" or " f"
if c == 'f' {
// Assuming 'f' is part of the sequence, e.g. ":f" or " f"
self.key_sequence_tracker.add_key(key_code);
let sequence = self.key_sequence_tracker.get_sequence();
if config.matches_key_sequence_generalized(&sequence) == Some("find_file_palette_toggle") {
if config.matches_key_sequence_generalized(&sequence)
== Some("find_file_palette_toggle")
{
if app_state.ui.show_form || app_state.ui.show_intro {
// Build table graph from profile data
let graph = TableDependencyGraph::from_profile_tree(&app_state.profile_tree);
let graph = TableDependencyGraph::from_profile_tree(
&app_state.profile_tree,
);
// Activate navigation with graph
self.navigation_state.activate_table_tree(graph);
@@ -601,14 +719,17 @@ impl EventHandler {
self.key_sequence_tracker.reset();
// ModeManager will derive AppMode::General due to navigation_state.active
// app_state.update_mode(AppMode::General); // This will be handled by ModeManager
return Ok(EventOutcome::Ok("Table tree palette activated".to_string()));
return Ok(EventOutcome::Ok(
"Table tree palette activated".to_string(),
));
} else {
self.key_sequence_tracker.reset();
self.command_input.push('f');
if sequence.len() > 1 && sequence[0] == KeyCode::Char('f') {
self.command_input.push('f');
self.command_input.push('f');
}
self.command_message = "Find File not available in this view.".to_string();
self.command_message =
"Find File not available in this view.".to_string();
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
}
@@ -630,7 +751,7 @@ impl EventHandler {
return Ok(EventOutcome::Ok(String::new()));
}
}
} else if let Event::Resize(_,_) = event {
} else if let Event::Resize(_, _) = event {
return Ok(EventOutcome::Ok("Resized".to_string()));
}