canvasstate is now officially nonexistent as dep
This commit is contained in:
@@ -3,7 +3,7 @@ use crate::config::colors::themes::Theme;
|
|||||||
use crate::state::app::highlight::HighlightState;
|
use crate::state::app::highlight::HighlightState;
|
||||||
use crate::state::app::state::AppState;
|
use crate::state::app::state::AppState;
|
||||||
use crate::state::pages::add_table::{AddTableFocus, AddTableState};
|
use crate::state::pages::add_table::{AddTableFocus, AddTableState};
|
||||||
use canvas::canvas::{render_canvas, CanvasState, HighlightState as CanvasHighlightState}; // Use canvas library
|
use canvas::canvas::{render_canvas, CanvasState, HighlightState as CanvasHighlightState};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||||
style::{Modifier, Style},
|
style::{Modifier, Style},
|
||||||
|
|||||||
@@ -9,43 +9,14 @@ use ratatui::{
|
|||||||
};
|
};
|
||||||
use crate::config::colors::themes::Theme;
|
use crate::config::colors::themes::Theme;
|
||||||
use crate::state::app::highlight::HighlightState;
|
use crate::state::app::highlight::HighlightState;
|
||||||
use crate::state::pages::canvas_state::CanvasState as LegacyCanvasState;
|
use canvas::canvas::CanvasState;
|
||||||
use canvas::canvas::CanvasState as LibraryCanvasState;
|
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
/// Render canvas for legacy CanvasState (AddTableState, LoginState, RegisterState, AddLogicState)
|
/// Render canvas (FormState)
|
||||||
pub fn render_canvas(
|
pub fn render_canvas(
|
||||||
f: &mut Frame,
|
f: &mut Frame,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
form_state: &impl LegacyCanvasState,
|
form_state: &impl CanvasState,
|
||||||
fields: &[&str],
|
|
||||||
current_field_idx: &usize,
|
|
||||||
inputs: &[&String],
|
|
||||||
theme: &Theme,
|
|
||||||
is_edit_mode: bool,
|
|
||||||
highlight_state: &HighlightState,
|
|
||||||
) -> Option<Rect> {
|
|
||||||
render_canvas_impl(
|
|
||||||
f,
|
|
||||||
area,
|
|
||||||
fields,
|
|
||||||
current_field_idx,
|
|
||||||
inputs,
|
|
||||||
theme,
|
|
||||||
is_edit_mode,
|
|
||||||
highlight_state,
|
|
||||||
form_state.current_cursor_pos(),
|
|
||||||
form_state.has_unsaved_changes(),
|
|
||||||
|i| form_state.get_display_value_for_field(i).to_string(),
|
|
||||||
|i| form_state.has_display_override(i),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Render canvas for library CanvasState (FormState)
|
|
||||||
pub fn render_canvas_library(
|
|
||||||
f: &mut Frame,
|
|
||||||
area: Rect,
|
|
||||||
form_state: &impl LibraryCanvasState,
|
|
||||||
fields: &[&str],
|
fields: &[&str],
|
||||||
current_field_idx: &usize,
|
current_field_idx: &usize,
|
||||||
inputs: &[&String],
|
inputs: &[&String],
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use crate::config::binds::key_sequences::KeySequenceTracker;
|
|||||||
use crate::services::grpc_client::GrpcClient;
|
use crate::services::grpc_client::GrpcClient;
|
||||||
use crate::state::pages::auth::LoginState;
|
use crate::state::pages::auth::LoginState;
|
||||||
use crate::state::pages::auth::RegisterState;
|
use crate::state::pages::auth::RegisterState;
|
||||||
use crate::state::pages::canvas_state::CanvasState as LocalCanvasState;
|
|
||||||
use crate::state::pages::form::FormState;
|
use crate::state::pages::form::FormState;
|
||||||
use crate::state::pages::add_logic::AddLogicState;
|
use crate::state::pages::add_logic::AddLogicState;
|
||||||
use crate::state::pages::add_table::AddTableState;
|
use crate::state::pages::add_table::AddTableState;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// src/modes/handlers.rs
|
// src/modes/handlers.rs
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod event_helper;
|
|
||||||
pub mod mode_manager;
|
pub mod mode_manager;
|
||||||
|
|||||||
@@ -15,23 +15,20 @@ use crate::modes::{
|
|||||||
general::{dialog, navigation},
|
general::{dialog, navigation},
|
||||||
handlers::mode_manager::{AppMode, ModeManager},
|
handlers::mode_manager::{AppMode, ModeManager},
|
||||||
};
|
};
|
||||||
use crate::state::pages::canvas_state::CanvasState as LegacyCanvasState;
|
|
||||||
use crate::services::auth::AuthClient;
|
use crate::services::auth::AuthClient;
|
||||||
use crate::services::grpc_client::GrpcClient;
|
use crate::services::grpc_client::GrpcClient;
|
||||||
use canvas::{canvas::CanvasAction, dispatcher::ActionDispatcher};
|
use canvas::{canvas::CanvasAction, dispatcher::ActionDispatcher};
|
||||||
use canvas::canvas::CanvasState as LibraryCanvasState;
|
use canvas::canvas::CanvasState; // Only need this import now
|
||||||
use super::event_helper::*;
|
|
||||||
use crate::state::{
|
use crate::state::{
|
||||||
app::{
|
app::{
|
||||||
buffer::{AppView, BufferState},
|
buffer::{AppView, BufferState},
|
||||||
highlight::HighlightState,
|
highlight::HighlightState,
|
||||||
search::SearchState, // Correctly imported
|
search::SearchState,
|
||||||
state::AppState,
|
state::AppState,
|
||||||
},
|
},
|
||||||
pages::{
|
pages::{
|
||||||
admin::AdminState,
|
admin::AdminState,
|
||||||
auth::{AuthState, LoginState, RegisterState},
|
auth::{AuthState, LoginState, RegisterState},
|
||||||
canvas_state::CanvasState,
|
|
||||||
form::FormState,
|
form::FormState,
|
||||||
intro::IntroState,
|
intro::IntroState,
|
||||||
},
|
},
|
||||||
@@ -89,7 +86,6 @@ pub struct EventHandler {
|
|||||||
pub navigation_state: NavigationState,
|
pub navigation_state: NavigationState,
|
||||||
pub search_result_sender: mpsc::UnboundedSender<Vec<Hit>>,
|
pub search_result_sender: mpsc::UnboundedSender<Vec<Hit>>,
|
||||||
pub search_result_receiver: mpsc::UnboundedReceiver<Vec<Hit>>,
|
pub search_result_receiver: mpsc::UnboundedReceiver<Vec<Hit>>,
|
||||||
// --- ADDED FOR LIVE AUTOCOMPLETE ---
|
|
||||||
pub autocomplete_result_sender: mpsc::UnboundedSender<Vec<Hit>>,
|
pub autocomplete_result_sender: mpsc::UnboundedSender<Vec<Hit>>,
|
||||||
pub autocomplete_result_receiver: mpsc::UnboundedReceiver<Vec<Hit>>,
|
pub autocomplete_result_receiver: mpsc::UnboundedReceiver<Vec<Hit>>,
|
||||||
}
|
}
|
||||||
@@ -103,7 +99,7 @@ impl EventHandler {
|
|||||||
grpc_client: GrpcClient,
|
grpc_client: GrpcClient,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let (search_tx, search_rx) = unbounded_channel();
|
let (search_tx, search_rx) = unbounded_channel();
|
||||||
let (autocomplete_tx, autocomplete_rx) = unbounded_channel(); // ADDED
|
let (autocomplete_tx, autocomplete_rx) = unbounded_channel();
|
||||||
Ok(EventHandler {
|
Ok(EventHandler {
|
||||||
command_mode: false,
|
command_mode: false,
|
||||||
command_input: String::new(),
|
command_input: String::new(),
|
||||||
@@ -122,7 +118,6 @@ impl EventHandler {
|
|||||||
navigation_state: NavigationState::new(),
|
navigation_state: NavigationState::new(),
|
||||||
search_result_sender: search_tx,
|
search_result_sender: search_tx,
|
||||||
search_result_receiver: search_rx,
|
search_result_receiver: search_rx,
|
||||||
// --- ADDED ---
|
|
||||||
autocomplete_result_sender: autocomplete_tx,
|
autocomplete_result_sender: autocomplete_tx,
|
||||||
autocomplete_result_receiver: autocomplete_rx,
|
autocomplete_result_receiver: autocomplete_rx,
|
||||||
})
|
})
|
||||||
@@ -136,6 +131,95 @@ impl EventHandler {
|
|||||||
self.navigation_state.activate_find_file(options);
|
self.navigation_state.activate_find_file(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper functions - replace the removed event_helper functions
|
||||||
|
fn get_current_field_for_state(
|
||||||
|
app_state: &AppState,
|
||||||
|
login_state: &LoginState,
|
||||||
|
register_state: &RegisterState,
|
||||||
|
form_state: &FormState,
|
||||||
|
) -> usize {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_current_cursor_pos_for_state(
|
||||||
|
app_state: &AppState,
|
||||||
|
login_state: &LoginState,
|
||||||
|
register_state: &RegisterState,
|
||||||
|
form_state: &FormState,
|
||||||
|
) -> usize {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_has_unsaved_changes_for_state(
|
||||||
|
app_state: &AppState,
|
||||||
|
login_state: &LoginState,
|
||||||
|
register_state: &RegisterState,
|
||||||
|
form_state: &FormState,
|
||||||
|
) -> bool {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_current_input_for_state<'a>(
|
||||||
|
app_state: &AppState,
|
||||||
|
login_state: &'a LoginState,
|
||||||
|
register_state: &'a RegisterState,
|
||||||
|
form_state: &'a FormState,
|
||||||
|
) -> &'a str {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_current_cursor_pos_for_state(
|
||||||
|
app_state: &AppState,
|
||||||
|
login_state: &mut LoginState,
|
||||||
|
register_state: &mut RegisterState,
|
||||||
|
form_state: &mut FormState,
|
||||||
|
pos: usize,
|
||||||
|
) {
|
||||||
|
if app_state.ui.show_login {
|
||||||
|
login_state.set_current_cursor_pos(pos);
|
||||||
|
} else if app_state.ui.show_register {
|
||||||
|
register_state.set_current_cursor_pos(pos);
|
||||||
|
} else {
|
||||||
|
form_state.set_current_cursor_pos(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cursor_pos_for_mixed_state(
|
||||||
|
app_state: &AppState,
|
||||||
|
login_state: &LoginState,
|
||||||
|
form_state: &FormState,
|
||||||
|
) -> usize {
|
||||||
|
if app_state.ui.show_login || app_state.ui.show_register {
|
||||||
|
login_state.current_cursor_pos()
|
||||||
|
} else {
|
||||||
|
form_state.current_cursor_pos()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This function handles state changes.
|
// This function handles state changes.
|
||||||
async fn handle_search_palette_event(
|
async fn handle_search_palette_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -199,7 +283,6 @@ impl EventHandler {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- START CORRECTED LOGIC ---
|
|
||||||
if trigger_search {
|
if trigger_search {
|
||||||
search_state.is_loading = true;
|
search_state.is_loading = true;
|
||||||
search_state.results.clear();
|
search_state.results.clear();
|
||||||
@@ -214,7 +297,6 @@ impl EventHandler {
|
|||||||
"--- 1. Spawning search task for query: '{}' ---",
|
"--- 1. Spawning search task for query: '{}' ---",
|
||||||
query
|
query
|
||||||
);
|
);
|
||||||
// We now move the grpc_client into the task, just like with login.
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
info!("--- 2. Background task started. ---");
|
info!("--- 2. Background task started. ---");
|
||||||
match grpc_client.search_table(table_name, query).await {
|
match grpc_client.search_table(table_name, query).await {
|
||||||
@@ -226,7 +308,6 @@ impl EventHandler {
|
|||||||
let _ = sender.send(response.hits);
|
let _ = sender.send(response.hits);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// THE FIX: Use the debug formatter `{:?}` to print the full error chain.
|
|
||||||
error!("--- 3b. gRPC call failed: {:?} ---", e);
|
error!("--- 3b. gRPC call failed: {:?} ---", e);
|
||||||
let _ = sender.send(vec![]);
|
let _ = sender.send(vec![]);
|
||||||
}
|
}
|
||||||
@@ -235,8 +316,6 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The borrow on `app_state.search_state` ends here.
|
|
||||||
// Now we can safely modify the Option itself.
|
|
||||||
if should_close {
|
if should_close {
|
||||||
app_state.search_state = None;
|
app_state.search_state = None;
|
||||||
app_state.ui.show_search_palette = false;
|
app_state.ui.show_search_palette = false;
|
||||||
@@ -264,7 +343,6 @@ impl EventHandler {
|
|||||||
) -> Result<EventOutcome> {
|
) -> Result<EventOutcome> {
|
||||||
if app_state.ui.show_search_palette {
|
if app_state.ui.show_search_palette {
|
||||||
if let Event::Key(key_event) = event {
|
if let Event::Key(key_event) = event {
|
||||||
// The call no longer passes grpc_client
|
|
||||||
return self
|
return self
|
||||||
.handle_search_palette_event(
|
.handle_search_palette_event(
|
||||||
key_event,
|
key_event,
|
||||||
@@ -581,7 +659,7 @@ impl EventHandler {
|
|||||||
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)
|
&& ModeManager::can_enter_highlight_mode(current_mode)
|
||||||
{
|
{
|
||||||
let current_field_index = get_current_field_for_state(
|
let current_field_index = Self::get_current_field_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
@@ -596,13 +674,13 @@ impl EventHandler {
|
|||||||
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)
|
&& ModeManager::can_enter_highlight_mode(current_mode)
|
||||||
{
|
{
|
||||||
let current_field_index = get_current_field_for_state(
|
let current_field_index = Self::get_current_field_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
form_state
|
form_state
|
||||||
);
|
);
|
||||||
let current_cursor_pos = get_current_cursor_pos_for_state(
|
let current_cursor_pos = Self::get_current_cursor_pos_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
@@ -627,13 +705,13 @@ impl EventHandler {
|
|||||||
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_after")
|
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)
|
&& ModeManager::can_enter_edit_mode(current_mode)
|
||||||
{
|
{
|
||||||
let current_input = get_current_input_for_state(
|
let current_input = Self::get_current_input_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
form_state
|
form_state
|
||||||
);
|
);
|
||||||
let current_cursor_pos = get_cursor_pos_for_mixed_state(
|
let current_cursor_pos = Self::get_cursor_pos_for_mixed_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
form_state
|
form_state
|
||||||
@@ -642,14 +720,14 @@ impl EventHandler {
|
|||||||
// Move cursor forward if possible
|
// Move cursor forward if possible
|
||||||
if !current_input.is_empty() && current_cursor_pos < current_input.len() {
|
if !current_input.is_empty() && current_cursor_pos < current_input.len() {
|
||||||
let new_cursor_pos = current_cursor_pos + 1;
|
let new_cursor_pos = current_cursor_pos + 1;
|
||||||
set_current_cursor_pos_for_state(
|
Self::set_current_cursor_pos_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
form_state,
|
form_state,
|
||||||
new_cursor_pos
|
new_cursor_pos
|
||||||
);
|
);
|
||||||
self.ideal_cursor_column = get_current_cursor_pos_for_state(
|
self.ideal_cursor_column = Self::get_current_cursor_pos_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
@@ -694,13 +772,13 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try canvas action for form first (NEW: Canvas library integration)
|
// Try canvas action for form first
|
||||||
if app_state.ui.show_form {
|
if app_state.ui.show_form {
|
||||||
if let Ok(Some(canvas_message)) = self.handle_form_canvas_action(
|
if let Ok(Some(canvas_message)) = self.handle_form_canvas_action(
|
||||||
key_event,
|
key_event,
|
||||||
config,
|
config,
|
||||||
form_state,
|
form_state,
|
||||||
false, // not edit mode
|
false,
|
||||||
).await {
|
).await {
|
||||||
return Ok(EventOutcome::Ok(canvas_message));
|
return Ok(EventOutcome::Ok(canvas_message));
|
||||||
}
|
}
|
||||||
@@ -753,7 +831,7 @@ impl EventHandler {
|
|||||||
&mut admin_state.add_table_state,
|
&mut admin_state.add_table_state,
|
||||||
&mut admin_state.add_logic_state,
|
&mut admin_state.add_logic_state,
|
||||||
&mut self.key_sequence_tracker,
|
&mut self.key_sequence_tracker,
|
||||||
&mut self.grpc_client, // <-- FIX 2
|
&mut self.grpc_client,
|
||||||
&mut self.command_message,
|
&mut self.command_message,
|
||||||
&mut self.edit_mode_cooldown,
|
&mut self.edit_mode_cooldown,
|
||||||
&mut self.ideal_cursor_column,
|
&mut self.ideal_cursor_column,
|
||||||
@@ -784,13 +862,13 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try canvas action for form first (NEW: Canvas library integration)
|
// Try canvas action for form first
|
||||||
if app_state.ui.show_form {
|
if app_state.ui.show_form {
|
||||||
if let Ok(Some(canvas_message)) = self.handle_form_canvas_action(
|
if let Ok(Some(canvas_message)) = self.handle_form_canvas_action(
|
||||||
key_event,
|
key_event,
|
||||||
config,
|
config,
|
||||||
form_state,
|
form_state,
|
||||||
true, // edit mode
|
true,
|
||||||
).await {
|
).await {
|
||||||
if !canvas_message.is_empty() {
|
if !canvas_message.is_empty() {
|
||||||
self.command_message = canvas_message.clone();
|
self.command_message = canvas_message.clone();
|
||||||
@@ -823,7 +901,7 @@ impl EventHandler {
|
|||||||
self.edit_mode_cooldown = true;
|
self.edit_mode_cooldown = true;
|
||||||
|
|
||||||
// Check for unsaved changes across all states
|
// Check for unsaved changes across all states
|
||||||
let has_changes = get_has_unsaved_changes_for_state(
|
let has_changes = Self::get_has_unsaved_changes_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
@@ -840,13 +918,13 @@ impl EventHandler {
|
|||||||
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
|
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
|
||||||
|
|
||||||
// Get current input and cursor position
|
// Get current input and cursor position
|
||||||
let current_input = get_current_input_for_state(
|
let current_input = Self::get_current_input_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
form_state
|
form_state
|
||||||
);
|
);
|
||||||
let current_cursor_pos = get_current_cursor_pos_for_state(
|
let current_cursor_pos = Self::get_current_cursor_pos_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
@@ -856,7 +934,7 @@ impl EventHandler {
|
|||||||
// Adjust cursor if it's beyond the input length
|
// Adjust cursor if it's beyond the input length
|
||||||
if !current_input.is_empty() && current_cursor_pos >= current_input.len() {
|
if !current_input.is_empty() && current_cursor_pos >= current_input.len() {
|
||||||
let new_pos = current_input.len() - 1;
|
let new_pos = current_input.len() - 1;
|
||||||
set_current_cursor_pos_for_state(
|
Self::set_current_cursor_pos_for_state(
|
||||||
app_state,
|
app_state,
|
||||||
login_state,
|
login_state,
|
||||||
register_state,
|
register_state,
|
||||||
@@ -906,7 +984,7 @@ impl EventHandler {
|
|||||||
form_state,
|
form_state,
|
||||||
&mut self.command_input,
|
&mut self.command_input,
|
||||||
&mut self.command_message,
|
&mut self.command_message,
|
||||||
&mut self.grpc_client, // <-- FIX 5
|
&mut self.grpc_client,
|
||||||
command_handler,
|
command_handler,
|
||||||
terminal,
|
terminal,
|
||||||
&mut current_position,
|
&mut current_position,
|
||||||
@@ -1024,11 +1102,10 @@ impl EventHandler {
|
|||||||
async fn handle_form_canvas_action(
|
async fn handle_form_canvas_action(
|
||||||
&mut self,
|
&mut self,
|
||||||
key_event: KeyEvent,
|
key_event: KeyEvent,
|
||||||
_config: &Config, // Not used anymore - canvas has its own config
|
_config: &Config,
|
||||||
form_state: &mut FormState,
|
form_state: &mut FormState,
|
||||||
is_edit_mode: bool,
|
is_edit_mode: bool,
|
||||||
) -> Result<Option<String>> {
|
) -> Result<Option<String>> {
|
||||||
// Load canvas config (canvas_config.toml or vim defaults)
|
|
||||||
let canvas_config = canvas::config::CanvasConfig::load();
|
let canvas_config = canvas::config::CanvasConfig::load();
|
||||||
|
|
||||||
// Handle suggestion actions first if suggestions are active
|
// Handle suggestion actions first if suggestions are active
|
||||||
@@ -1083,7 +1160,6 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXED: Use canvas config instead of client config
|
|
||||||
let action_str = canvas_config.get_action_for_key(
|
let action_str = canvas_config.get_action_for_key(
|
||||||
key_event.code,
|
key_event.code,
|
||||||
key_event.modifiers,
|
key_event.modifiers,
|
||||||
@@ -1092,9 +1168,8 @@ impl EventHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Some(action_str) = action_str {
|
if let Some(action_str) = action_str {
|
||||||
// Filter out mode transition actions - let legacy handlers deal with these
|
|
||||||
if Self::is_mode_transition_action(action_str) {
|
if Self::is_mode_transition_action(action_str) {
|
||||||
return Ok(None); // Let legacy handler handle mode transitions
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let canvas_action = CanvasAction::from_string(&action_str);
|
let canvas_action = CanvasAction::from_string(&action_str);
|
||||||
@@ -1131,7 +1206,6 @@ impl EventHandler {
|
|||||||
} else {
|
} else {
|
||||||
// In read-only mode, only handle non-character keys
|
// In read-only mode, only handle non-character keys
|
||||||
let canvas_action = match key_event.code {
|
let canvas_action = match key_event.code {
|
||||||
// Only handle special keys that don't conflict with vim bindings
|
|
||||||
KeyCode::Left => Some(CanvasAction::MoveLeft),
|
KeyCode::Left => Some(CanvasAction::MoveLeft),
|
||||||
KeyCode::Right => Some(CanvasAction::MoveRight),
|
KeyCode::Right => Some(CanvasAction::MoveRight),
|
||||||
KeyCode::Up => Some(CanvasAction::MoveUp),
|
KeyCode::Up => Some(CanvasAction::MoveUp),
|
||||||
@@ -1164,7 +1238,6 @@ impl EventHandler {
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADDED: Helper function to identify mode transition actions
|
|
||||||
fn is_mode_transition_action(action: &str) -> bool {
|
fn is_mode_transition_action(action: &str) -> bool {
|
||||||
matches!(action,
|
matches!(action,
|
||||||
"exit" |
|
"exit" |
|
||||||
@@ -1181,11 +1254,11 @@ impl EventHandler {
|
|||||||
"force_quit" |
|
"force_quit" |
|
||||||
"save_and_quit" |
|
"save_and_quit" |
|
||||||
"revert" |
|
"revert" |
|
||||||
"enter_decider" | // This is also handled specially by legacy system
|
"enter_decider" |
|
||||||
"trigger_autocomplete" | // This is handled specially by legacy system
|
"trigger_autocomplete" |
|
||||||
"suggestion_up" | // These are handled above in suggestion logic
|
"suggestion_up" |
|
||||||
"suggestion_down" |
|
"suggestion_down" |
|
||||||
"previous_entry" | // Navigation between records
|
"previous_entry" |
|
||||||
"next_entry" |
|
"next_entry" |
|
||||||
"toggle_sidebar" |
|
"toggle_sidebar" |
|
||||||
"toggle_buffer_list" |
|
"toggle_buffer_list" |
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
|
|
||||||
// src/modes/handlers/event_helper.rs
|
|
||||||
//! Helper functions to handle the differences between legacy and library CanvasState traits
|
|
||||||
|
|
||||||
use crate::state::app::state::AppState;
|
|
||||||
use crate::state::pages::{
|
|
||||||
form::FormState,
|
|
||||||
auth::{LoginState, RegisterState},
|
|
||||||
};
|
|
||||||
use crate::state::pages::canvas_state::CanvasState as LegacyCanvasState;
|
|
||||||
use canvas::canvas::CanvasState as LibraryCanvasState;
|
|
||||||
|
|
||||||
/// Get the current field index from the appropriate state based on which UI is active
|
|
||||||
pub fn get_current_field_for_state(
|
|
||||||
app_state: &AppState,
|
|
||||||
login_state: &LoginState,
|
|
||||||
register_state: &RegisterState,
|
|
||||||
form_state: &FormState,
|
|
||||||
) -> usize {
|
|
||||||
if app_state.ui.show_login {
|
|
||||||
login_state.current_field() // Uses LegacyCanvasState
|
|
||||||
} else if app_state.ui.show_register {
|
|
||||||
register_state.current_field() // Uses LegacyCanvasState
|
|
||||||
} else {
|
|
||||||
form_state.current_field() // Uses LibraryCanvasState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the current cursor position from the appropriate state based on which UI is active
|
|
||||||
pub fn get_current_cursor_pos_for_state(
|
|
||||||
app_state: &AppState,
|
|
||||||
login_state: &LoginState,
|
|
||||||
register_state: &RegisterState,
|
|
||||||
form_state: &FormState,
|
|
||||||
) -> usize {
|
|
||||||
if app_state.ui.show_login {
|
|
||||||
login_state.current_cursor_pos() // Uses LegacyCanvasState
|
|
||||||
} else if app_state.ui.show_register {
|
|
||||||
register_state.current_cursor_pos() // Uses LegacyCanvasState
|
|
||||||
} else {
|
|
||||||
form_state.current_cursor_pos() // Uses LibraryCanvasState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if the appropriate state has unsaved changes based on which UI is active
|
|
||||||
pub fn get_has_unsaved_changes_for_state(
|
|
||||||
app_state: &AppState,
|
|
||||||
login_state: &LoginState,
|
|
||||||
register_state: &RegisterState,
|
|
||||||
form_state: &FormState,
|
|
||||||
) -> bool {
|
|
||||||
if app_state.ui.show_login {
|
|
||||||
login_state.has_unsaved_changes() // Uses LegacyCanvasState
|
|
||||||
} else if app_state.ui.show_register {
|
|
||||||
register_state.has_unsaved_changes() // Uses LegacyCanvasState
|
|
||||||
} else {
|
|
||||||
form_state.has_unsaved_changes() // Uses LibraryCanvasState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the current input from the appropriate state based on which UI is active
|
|
||||||
pub fn get_current_input_for_state<'a>(
|
|
||||||
app_state: &AppState,
|
|
||||||
login_state: &'a LoginState,
|
|
||||||
register_state: &'a RegisterState,
|
|
||||||
form_state: &'a FormState,
|
|
||||||
) -> &'a str {
|
|
||||||
if app_state.ui.show_login {
|
|
||||||
login_state.get_current_input() // Uses LegacyCanvasState
|
|
||||||
} else if app_state.ui.show_register {
|
|
||||||
register_state.get_current_input() // Uses LegacyCanvasState
|
|
||||||
} else {
|
|
||||||
form_state.get_current_input() // Uses LibraryCanvasState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the cursor position for the appropriate state based on which UI is active
|
|
||||||
pub fn set_current_cursor_pos_for_state(
|
|
||||||
app_state: &AppState,
|
|
||||||
login_state: &mut LoginState,
|
|
||||||
register_state: &mut RegisterState,
|
|
||||||
form_state: &mut FormState,
|
|
||||||
pos: usize,
|
|
||||||
) {
|
|
||||||
if app_state.ui.show_login {
|
|
||||||
login_state.set_current_cursor_pos(pos); // Uses LegacyCanvasState
|
|
||||||
} else if app_state.ui.show_register {
|
|
||||||
register_state.set_current_cursor_pos(pos); // Uses LegacyCanvasState
|
|
||||||
} else {
|
|
||||||
form_state.set_current_cursor_pos(pos); // Uses LibraryCanvasState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get cursor position for mixed login/register vs form logic
|
|
||||||
pub fn get_cursor_pos_for_mixed_state(
|
|
||||||
app_state: &AppState,
|
|
||||||
login_state: &LoginState,
|
|
||||||
form_state: &FormState,
|
|
||||||
) -> usize {
|
|
||||||
if app_state.ui.show_login || app_state.ui.show_register {
|
|
||||||
login_state.current_cursor_pos() // Uses LegacyCanvasState
|
|
||||||
} else {
|
|
||||||
form_state.current_cursor_pos() // Uses LibraryCanvasState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,11 +16,10 @@ use crate::components::{
|
|||||||
};
|
};
|
||||||
use crate::config::colors::themes::Theme;
|
use crate::config::colors::themes::Theme;
|
||||||
use crate::modes::general::command_navigation::NavigationState;
|
use crate::modes::general::command_navigation::NavigationState;
|
||||||
use crate::state::pages::canvas_state::CanvasState as LocalCanvasState; // Keep local one with alias
|
use canvas::canvas::CanvasState;
|
||||||
use canvas::canvas::CanvasState; // Import external library's CanvasState trait
|
|
||||||
use crate::state::app::buffer::BufferState;
|
use crate::state::app::buffer::BufferState;
|
||||||
use crate::state::app::highlight::HighlightState as LocalHighlightState; // CHANGED: Alias local version
|
use crate::state::app::highlight::HighlightState as LocalHighlightState;
|
||||||
use canvas::canvas::HighlightState as CanvasHighlightState; // CHANGED: Import canvas version with alias
|
use canvas::canvas::HighlightState as CanvasHighlightState;
|
||||||
use crate::state::app::state::AppState;
|
use crate::state::app::state::AppState;
|
||||||
use crate::state::pages::admin::AdminState;
|
use crate::state::pages::admin::AdminState;
|
||||||
use crate::state::pages::auth::AuthState;
|
use crate::state::pages::auth::AuthState;
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ use crate::config::storage::storage::load_auth_data;
|
|||||||
use crate::modes::common::commands::CommandHandler;
|
use crate::modes::common::commands::CommandHandler;
|
||||||
use crate::modes::handlers::event::{EventHandler, EventOutcome};
|
use crate::modes::handlers::event::{EventHandler, EventOutcome};
|
||||||
use crate::modes::handlers::mode_manager::{AppMode, ModeManager};
|
use crate::modes::handlers::mode_manager::{AppMode, ModeManager};
|
||||||
use crate::state::pages::canvas_state::CanvasState as LocalCanvasState; // Keep local one with alias
|
use canvas::canvas::CanvasState; // Only external library import
|
||||||
use canvas::canvas::CanvasState; // Import external library's CanvasState trait
|
use crate::state::pages::form::{FormState, FieldDefinition};
|
||||||
use crate::state::pages::form::{FormState, FieldDefinition}; // Import FieldDefinition
|
|
||||||
use crate::state::pages::auth::AuthState;
|
use crate::state::pages::auth::AuthState;
|
||||||
use crate::state::pages::auth::LoginState;
|
use crate::state::pages::auth::LoginState;
|
||||||
use crate::state::pages::auth::RegisterState;
|
use crate::state::pages::auth::RegisterState;
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
use rstest::{fixture, rstest};
|
use rstest::{fixture, rstest};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use client::state::pages::form::{FormState, FieldDefinition};
|
use client::state::pages::form::{FormState, FieldDefinition};
|
||||||
use canvas::state::CanvasState
|
use canvas::canvas::CanvasState;
|
||||||
use client::state::pages::canvas_state::CanvasState;
|
|
||||||
|
|
||||||
#[fixture]
|
#[fixture]
|
||||||
fn test_form_state() -> FormState {
|
fn test_form_state() -> FormState {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
pub use rstest::{fixture, rstest};
|
pub use rstest::{fixture, rstest};
|
||||||
pub use client::services::grpc_client::GrpcClient;
|
pub use client::services::grpc_client::GrpcClient;
|
||||||
pub use client::state::pages::form::FormState;
|
pub use client::state::pages::form::FormState;
|
||||||
pub use client::state::pages::canvas_state::CanvasState;
|
pub use canvas::canvas::CanvasState;
|
||||||
pub use prost_types::Value;
|
pub use prost_types::Value;
|
||||||
pub use prost_types::value::Kind;
|
pub use prost_types::value::Kind;
|
||||||
pub use std::collections::HashMap;
|
pub use std::collections::HashMap;
|
||||||
|
|||||||
Reference in New Issue
Block a user