we compiled but buffer doesnt work
This commit is contained in:
@@ -6,6 +6,7 @@ use crate::bottom_panel::find_file_palette;
|
|||||||
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::app::state::AppState;
|
use crate::state::app::state::AppState;
|
||||||
|
use crate::pages::routing::Router;
|
||||||
|
|
||||||
/// Calculate the layout constraints for the bottom panel (status line + command line/palette).
|
/// Calculate the layout constraints for the bottom panel (status line + command line/palette).
|
||||||
pub fn bottom_panel_constraints(
|
pub fn bottom_panel_constraints(
|
||||||
@@ -48,6 +49,7 @@ pub fn render_bottom_panel(
|
|||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
current_fps: f64,
|
current_fps: f64,
|
||||||
app_state: &AppState,
|
app_state: &AppState,
|
||||||
|
router: &Router,
|
||||||
navigation_state: &NavigationState,
|
navigation_state: &NavigationState,
|
||||||
event_handler_command_input: &str,
|
event_handler_command_input: &str,
|
||||||
event_handler_command_mode_active: bool,
|
event_handler_command_mode_active: bool,
|
||||||
@@ -75,6 +77,7 @@ pub fn render_bottom_panel(
|
|||||||
theme,
|
theme,
|
||||||
current_fps,
|
current_fps,
|
||||||
app_state,
|
app_state,
|
||||||
|
router,
|
||||||
);
|
);
|
||||||
|
|
||||||
// --- Render command line or palette ---
|
// --- Render command line or palette ---
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ use ratatui::{
|
|||||||
widgets::{Paragraph, Wrap},
|
widgets::{Paragraph, Wrap},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
use crate::pages::routing::Page;
|
||||||
|
use crate::pages::routing::Router;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
@@ -18,6 +20,7 @@ pub fn render_status_line(
|
|||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
current_fps: f64,
|
current_fps: f64,
|
||||||
app_state: &AppState,
|
app_state: &AppState,
|
||||||
|
router: &Router,
|
||||||
) {
|
) {
|
||||||
#[cfg(feature = "ui-debug")]
|
#[cfg(feature = "ui-debug")]
|
||||||
{
|
{
|
||||||
@@ -47,13 +50,17 @@ pub fn render_status_line(
|
|||||||
|
|
||||||
// --- The normal status line rendering logic (unchanged) ---
|
// --- The normal status line rendering logic (unchanged) ---
|
||||||
let program_info = format!("komp_ac v{}", env!("CARGO_PKG_VERSION"));
|
let program_info = format!("komp_ac v{}", env!("CARGO_PKG_VERSION"));
|
||||||
let mode_text = if let Some(editor) = &app_state.form_editor {
|
let mode_text = if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(editor) = app_state.editor_for_path_ref(path) {
|
||||||
match editor.mode() {
|
match editor.mode() {
|
||||||
canvas::AppMode::Edit => "[EDIT]",
|
canvas::AppMode::Edit => "[EDIT]",
|
||||||
canvas::AppMode::ReadOnly => "[READ-ONLY]",
|
canvas::AppMode::ReadOnly => "[READ-ONLY]",
|
||||||
canvas::AppMode::Highlight => "[VISUAL]",
|
canvas::AppMode::Highlight => "[VISUAL]",
|
||||||
_ => "",
|
_ => "",
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
"" // No canvas active
|
"" // No canvas active
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ async fn process_command(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"save" => {
|
"save" => {
|
||||||
let outcome = save(app_state, grpc_client).await?;
|
if let Page::Form(path) = &router.current {
|
||||||
|
let outcome = save(app_state, path, grpc_client).await?;
|
||||||
let message = match outcome {
|
let message = match outcome {
|
||||||
SaveOutcome::CreatedNew(_) => "New entry created".to_string(),
|
SaveOutcome::CreatedNew(_) => "New entry created".to_string(),
|
||||||
SaveOutcome::UpdatedExisting => "Entry updated".to_string(),
|
SaveOutcome::UpdatedExisting => "Entry updated".to_string(),
|
||||||
@@ -106,11 +107,18 @@ async fn process_command(
|
|||||||
};
|
};
|
||||||
command_input.clear();
|
command_input.clear();
|
||||||
Ok(EventOutcome::DataSaved(outcome, message))
|
Ok(EventOutcome::DataSaved(outcome, message))
|
||||||
|
} else {
|
||||||
|
Ok(EventOutcome::Ok("Not in a form page".to_string()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"revert" => {
|
"revert" => {
|
||||||
let message = revert(app_state, grpc_client).await?;
|
if let Page::Form(path) = &router.current {
|
||||||
|
let message = revert(app_state, path, grpc_client).await?;
|
||||||
command_input.clear();
|
command_input.clear();
|
||||||
Ok(EventOutcome::Ok(message))
|
Ok(EventOutcome::Ok(message))
|
||||||
|
} else {
|
||||||
|
Ok(EventOutcome::Ok("Not in a form page".to_string()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let message = format!("Unhandled action: {}", action);
|
let message = format!("Unhandled action: {}", action);
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ impl CommandHandler {
|
|||||||
let has_unsaved = match &router.current {
|
let has_unsaved = match &router.current {
|
||||||
Page::Login(page) => page.state.has_unsaved_changes(),
|
Page::Login(page) => page.state.has_unsaved_changes(),
|
||||||
Page::Register(state) => state.has_unsaved_changes(),
|
Page::Register(state) => state.has_unsaved_changes(),
|
||||||
Page::Form(fs) => fs.has_unsaved_changes,
|
Page::Form(path) => app_state
|
||||||
|
.form_state_for_path_ref(path)
|
||||||
|
.map(|fs| fs.has_unsaved_changes())
|
||||||
|
.unwrap_or(false),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -45,15 +45,19 @@ pub async fn handle_navigation_event(
|
|||||||
return Ok(EventOutcome::Ok(String::new()));
|
return Ok(EventOutcome::Ok(String::new()));
|
||||||
}
|
}
|
||||||
"next_field" => {
|
"next_field" => {
|
||||||
if let Some(fs) = app_state.form_state_mut() {
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(fs) = app_state.form_state_for_path(path) {
|
||||||
next_field(fs);
|
next_field(fs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Ok(EventOutcome::Ok(String::new()));
|
return Ok(EventOutcome::Ok(String::new()));
|
||||||
}
|
}
|
||||||
"prev_field" => {
|
"prev_field" => {
|
||||||
if let Some(fs) = app_state.form_state_mut() {
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(fs) = app_state.form_state_for_path(path) {
|
||||||
prev_field(fs);
|
prev_field(fs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Ok(EventOutcome::Ok(String::new()));
|
return Ok(EventOutcome::Ok(String::new()));
|
||||||
}
|
}
|
||||||
"enter_command_mode" => {
|
"enter_command_mode" => {
|
||||||
|
|||||||
@@ -128,69 +128,84 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions - replace the removed event_helper functions
|
// Helper functions - replace the removed event_helper functions
|
||||||
fn get_current_field_for_state(
|
fn get_current_field_for_state(&self, router: &Router, app_state: &AppState) -> usize {
|
||||||
router: &Router,
|
|
||||||
) -> usize {
|
|
||||||
match &router.current {
|
match &router.current {
|
||||||
Page::Login(state) => state.current_field(),
|
Page::Login(state) => state.current_field(),
|
||||||
Page::Register(state) => state.current_field(),
|
Page::Register(state) => state.current_field(),
|
||||||
Page::Form(state) => state.current_field(),
|
Page::Form(path) => app_state
|
||||||
|
.editor_for_path_ref(path)
|
||||||
|
.map(|e| e.data_provider().current_field())
|
||||||
|
.unwrap_or(0),
|
||||||
_ => 0,
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_current_cursor_pos_for_state(
|
fn get_current_cursor_pos_for_state(&self, router: &Router, app_state: &AppState) -> usize {
|
||||||
router: &Router,
|
|
||||||
) -> usize {
|
|
||||||
match &router.current {
|
match &router.current {
|
||||||
Page::Login(state) => state.current_cursor_pos(),
|
Page::Login(state) => state.current_cursor_pos(),
|
||||||
Page::Register(state) => state.current_cursor_pos(),
|
Page::Register(state) => state.current_cursor_pos(),
|
||||||
Page::Form(state) => state.current_cursor_pos(),
|
Page::Form(path) => app_state
|
||||||
|
.form_state_for_path_ref(path)
|
||||||
|
.map(|fs| fs.current_cursor_pos())
|
||||||
|
.unwrap_or(0),
|
||||||
_ => 0,
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_has_unsaved_changes_for_state(
|
fn get_has_unsaved_changes_for_state(&self, router: &Router, app_state: &AppState) -> bool {
|
||||||
router: &Router,
|
|
||||||
) -> bool {
|
|
||||||
match &router.current {
|
match &router.current {
|
||||||
Page::Login(state) => state.has_unsaved_changes(),
|
Page::Login(state) => state.has_unsaved_changes(),
|
||||||
Page::Register(state) => state.has_unsaved_changes(),
|
Page::Register(state) => state.has_unsaved_changes(),
|
||||||
Page::Form(state) => state.has_unsaved_changes(),
|
Page::Form(path) => app_state
|
||||||
|
.form_state_for_path_ref(path)
|
||||||
|
.map(|fs| fs.has_unsaved_changes())
|
||||||
|
.unwrap_or(false),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_current_input_for_state<'a>(
|
fn get_current_input_for_state<'a>(
|
||||||
|
&'a self,
|
||||||
router: &'a Router,
|
router: &'a Router,
|
||||||
|
app_state: &'a AppState,
|
||||||
) -> &'a str {
|
) -> &'a str {
|
||||||
match &router.current {
|
match &router.current {
|
||||||
Page::Login(state) => state.get_current_input(),
|
Page::Login(state) => state.get_current_input(),
|
||||||
Page::Register(state) => state.get_current_input(),
|
Page::Register(state) => state.get_current_input(),
|
||||||
Page::Form(state) => state.get_current_input(),
|
Page::Form(path) => app_state
|
||||||
|
.form_state_for_path_ref(path)
|
||||||
|
.map(|fs| fs.get_current_input())
|
||||||
|
.unwrap_or(""),
|
||||||
_ => "",
|
_ => "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_current_cursor_pos_for_state(
|
fn set_current_cursor_pos_for_state(
|
||||||
|
&mut self,
|
||||||
router: &mut Router,
|
router: &mut Router,
|
||||||
|
app_state: &mut AppState,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
) {
|
) {
|
||||||
match &mut router.current {
|
match &mut router.current {
|
||||||
Page::Login(state) => state.set_current_cursor_pos(pos),
|
Page::Login(state) => state.set_current_cursor_pos(pos),
|
||||||
Page::Register(state) => state.set_current_cursor_pos(pos),
|
Page::Register(state) => state.set_current_cursor_pos(pos),
|
||||||
Page::Form(state) => state.set_current_cursor_pos(pos),
|
Page::Form(path) => {
|
||||||
|
if let Some(fs) = app_state.form_state_for_path(path) {
|
||||||
|
fs.set_current_cursor_pos(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cursor_pos_for_mixed_state(
|
fn get_cursor_pos_for_mixed_state(&self, router: &Router, app_state: &AppState) -> usize {
|
||||||
router: &Router,
|
|
||||||
) -> usize {
|
|
||||||
match &router.current {
|
match &router.current {
|
||||||
Page::Login(state) => state.current_cursor_pos(),
|
Page::Login(state) => state.current_cursor_pos(),
|
||||||
Page::Register(state) => state.current_cursor_pos(),
|
Page::Register(state) => state.current_cursor_pos(),
|
||||||
Page::Form(state) => state.current_cursor_pos(),
|
Page::Form(path) => app_state
|
||||||
|
.form_state_for_path_ref(path)
|
||||||
|
.map(|fs| fs.current_cursor_pos())
|
||||||
|
.unwrap_or(0),
|
||||||
_ => 0,
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,7 +269,7 @@ impl EventHandler {
|
|||||||
Page::Admin(_) => AppView::Admin,
|
Page::Admin(_) => AppView::Admin,
|
||||||
Page::AddLogic(_) => AppView::AddLogic,
|
Page::AddLogic(_) => AppView::AddLogic,
|
||||||
Page::AddTable(_) => AppView::AddTable,
|
Page::AddTable(_) => AppView::AddTable,
|
||||||
Page::Form(_) => AppView::Form,
|
Page::Form(path) => AppView::Form(path.clone()),
|
||||||
};
|
};
|
||||||
buffer_state.update_history(current_view);
|
buffer_state.update_history(current_view);
|
||||||
|
|
||||||
@@ -678,19 +693,28 @@ impl EventHandler {
|
|||||||
self.command_message.clear();
|
self.command_message.clear();
|
||||||
self.command_mode = false;
|
self.command_mode = false;
|
||||||
self.key_sequence_tracker.reset();
|
self.key_sequence_tracker.reset();
|
||||||
if let Some(editor) = &mut app_state.form_editor {
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(editor) = app_state.editor_for_path(path) {
|
||||||
editor.set_mode(CanvasMode::ReadOnly);
|
editor.set_mode(CanvasMode::ReadOnly);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Ok(EventOutcome::Ok(
|
return Ok(EventOutcome::Ok(
|
||||||
"Exited command mode".to_string(),
|
"Exited command mode".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.is_command_execute(key_code, modifiers) {
|
if config.is_command_execute(key_code, modifiers) {
|
||||||
let (mut current_position, total_count) = if let Page::Form(fs) = &router.current {
|
let (mut current_position, total_count) =
|
||||||
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(fs) =
|
||||||
|
app_state.form_state_for_path_ref(path)
|
||||||
|
{
|
||||||
(fs.current_position, fs.total_count)
|
(fs.current_position, fs.total_count)
|
||||||
} else {
|
} else {
|
||||||
(1, 0)
|
(1, 0)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(1, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
let outcome = command_mode::handle_command_event(
|
let outcome = command_mode::handle_command_event(
|
||||||
@@ -706,9 +730,11 @@ impl EventHandler {
|
|||||||
&mut current_position,
|
&mut current_position,
|
||||||
total_count,
|
total_count,
|
||||||
).await?;
|
).await?;
|
||||||
if let Page::Form(fs) = &mut router.current {
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(fs) = app_state.form_state_for_path(path) {
|
||||||
fs.current_position = current_position;
|
fs.current_position = current_position;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.command_mode = false;
|
self.command_mode = false;
|
||||||
self.key_sequence_tracker.reset();
|
self.key_sequence_tracker.reset();
|
||||||
let new_mode = ModeManager::derive_mode(
|
let new_mode = ModeManager::derive_mode(
|
||||||
@@ -834,9 +860,10 @@ impl EventHandler {
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(EventOutcome::Ok(message))
|
Ok(EventOutcome::Ok(message))
|
||||||
} else {
|
} else {
|
||||||
let save_outcome = if let Page::Form(_) = &router.current {
|
let save_outcome = if let Page::Form(path) = &router.current {
|
||||||
save(
|
save(
|
||||||
app_state,
|
app_state,
|
||||||
|
path,
|
||||||
&mut self.grpc_client,
|
&mut self.grpc_client,
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
@@ -852,9 +879,11 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"force_quit" => {
|
"force_quit" => {
|
||||||
if let Some(editor) = &mut app_state.form_editor {
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(editor) = app_state.editor_for_path(path) {
|
||||||
editor.cleanup_cursor()?;
|
editor.cleanup_cursor()?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
terminal.cleanup()?;
|
terminal.cleanup()?;
|
||||||
Ok(EventOutcome::Exit(
|
Ok(EventOutcome::Exit(
|
||||||
"Force exiting without saving.".to_string(),
|
"Force exiting without saving.".to_string(),
|
||||||
@@ -870,19 +899,22 @@ impl EventHandler {
|
|||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
} else {
|
} else {
|
||||||
let save_outcome = save(
|
let save_outcome = if let Page::Form(path) = &router.current {
|
||||||
app_state,
|
save(app_state, path, &mut self.grpc_client).await?
|
||||||
&mut self.grpc_client,
|
} else {
|
||||||
).await?;
|
SaveOutcome::NoChange
|
||||||
|
};
|
||||||
match save_outcome {
|
match save_outcome {
|
||||||
SaveOutcome::NoChange => "No changes to save.".to_string(),
|
SaveOutcome::NoChange => "No changes to save.".to_string(),
|
||||||
SaveOutcome::UpdatedExisting => "Entry updated.".to_string(),
|
SaveOutcome::UpdatedExisting => "Entry updated.".to_string(),
|
||||||
SaveOutcome::CreatedNew(_) => "New entry created.".to_string(),
|
SaveOutcome::CreatedNew(_) => "New entry created.".to_string(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(editor) = &mut app_state.form_editor {
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(editor) = app_state.editor_for_path(path) {
|
||||||
editor.cleanup_cursor()?;
|
editor.cleanup_cursor()?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
terminal.cleanup()?;
|
terminal.cleanup()?;
|
||||||
Ok(EventOutcome::Exit(format!(
|
Ok(EventOutcome::Exit(format!(
|
||||||
"{}. Exiting application.",
|
"{}. Exiting application.",
|
||||||
@@ -899,12 +931,8 @@ impl EventHandler {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
if let Page::Form(_) = &router.current {
|
if let Page::Form(path) = &router.current {
|
||||||
revert(
|
revert(app_state, path, &mut self.grpc_client).await?
|
||||||
app_state,
|
|
||||||
&mut self.grpc_client,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
} else {
|
} else {
|
||||||
"Nothing to revert".to_string()
|
"Nothing to revert".to_string()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,10 @@ pub enum SaveOutcome {
|
|||||||
|
|
||||||
pub async fn save(
|
pub async fn save(
|
||||||
app_state: &mut AppState,
|
app_state: &mut AppState,
|
||||||
|
path: &str,
|
||||||
grpc_client: &mut GrpcClient,
|
grpc_client: &mut GrpcClient,
|
||||||
) -> Result<SaveOutcome> {
|
) -> Result<SaveOutcome> {
|
||||||
if let Some(fs) = app_state.active_form_state_mut(buffer_state) {
|
if let Some(fs) = app_state.form_state_for_path(path) {
|
||||||
if !fs.has_unsaved_changes {
|
if !fs.has_unsaved_changes {
|
||||||
return Ok(SaveOutcome::NoChange);
|
return Ok(SaveOutcome::NoChange);
|
||||||
}
|
}
|
||||||
@@ -62,7 +63,7 @@ pub async fn save(
|
|||||||
.context("Failed to post new table data")?;
|
.context("Failed to post new table data")?;
|
||||||
|
|
||||||
if response.success {
|
if response.success {
|
||||||
if let Some(fs) = app_state.active_form_state_mut(buffer_state) {
|
if let Some(fs) = app_state.form_state_for_path(path) {
|
||||||
fs.id = response.inserted_id;
|
fs.id = response.inserted_id;
|
||||||
fs.total_count += 1;
|
fs.total_count += 1;
|
||||||
fs.current_position = fs.total_count;
|
fs.current_position = fs.total_count;
|
||||||
@@ -84,7 +85,7 @@ pub async fn save(
|
|||||||
.context("Failed to put (update) table data")?;
|
.context("Failed to put (update) table data")?;
|
||||||
|
|
||||||
if response.success {
|
if response.success {
|
||||||
if let Some(fs) = app_state.active_form_state_mut(buffer_state) {
|
if let Some(fs) = app_state.form_state_for_path(path) {
|
||||||
fs.has_unsaved_changes = false;
|
fs.has_unsaved_changes = false;
|
||||||
}
|
}
|
||||||
SaveOutcome::UpdatedExisting
|
SaveOutcome::UpdatedExisting
|
||||||
@@ -101,9 +102,10 @@ pub async fn save(
|
|||||||
|
|
||||||
pub async fn revert(
|
pub async fn revert(
|
||||||
app_state: &mut AppState,
|
app_state: &mut AppState,
|
||||||
|
path: &str,
|
||||||
grpc_client: &mut GrpcClient,
|
grpc_client: &mut GrpcClient,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
if let Some(fs) = app_state.active_form_state_mut(buffer_state) {
|
if let Some(fs) = app_state.form_state_for_path(path) {
|
||||||
if fs.id == 0
|
if fs.id == 0
|
||||||
|| (fs.total_count > 0 && fs.current_position > fs.total_count)
|
|| (fs.total_count > 0 && fs.current_position > fs.total_count)
|
||||||
|| (fs.total_count == 0 && fs.current_position == 1)
|
|| (fs.total_count == 0 && fs.current_position == 1)
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
// src/pages/forms/ui.rs
|
// src/pages/forms/ui.rs
|
||||||
use crate::config::colors::themes::Theme;
|
use crate::config::colors::themes::Theme;
|
||||||
use crate::state::app::state::AppState;
|
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::{Alignment, Constraint, Direction, Layout, Margin, Rect},
|
layout::{Alignment, Constraint, Direction, Layout, Margin, Rect},
|
||||||
style::Style,
|
style::Style,
|
||||||
widgets::{Block, Borders, Paragraph},
|
widgets::{Block, Borders, Paragraph},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use crate::pages::forms::FormState;
|
|
||||||
use canvas::{
|
use canvas::{
|
||||||
render_canvas, render_suggestions_dropdown, DefaultCanvasTheme,
|
render_canvas, render_suggestions_dropdown, DefaultCanvasTheme, FormEditor,
|
||||||
};
|
};
|
||||||
|
use crate::pages::forms::FormState;
|
||||||
|
|
||||||
pub fn render_form_page(
|
pub fn render_form_page(
|
||||||
f: &mut Frame,
|
f: &mut Frame,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
app_state: &AppState,
|
editor: &FormEditor<FormState>,
|
||||||
form_state: &FormState, // not needed directly anymore, editor holds it
|
|
||||||
table_name: &str,
|
table_name: &str,
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
total_count: u64,
|
total_count: u64,
|
||||||
@@ -61,8 +59,6 @@ pub fn render_form_page(
|
|||||||
f.render_widget(count_para, main_layout[0]);
|
f.render_widget(count_para, main_layout[0]);
|
||||||
|
|
||||||
// --- FORM RENDERING (Using persistent FormEditor) ---
|
// --- FORM RENDERING (Using persistent FormEditor) ---
|
||||||
if let Some(AppView::Form(path)) = buffer_state.get_active_view() {
|
|
||||||
if let Some(editor) = app_state.form_editor.get(path) {
|
|
||||||
let active_field_rect = render_canvas(f, main_layout[1], editor, theme);
|
let active_field_rect = render_canvas(f, main_layout[1], editor, theme);
|
||||||
if let Some(active_rect) = active_field_rect {
|
if let Some(active_rect) = active_field_rect {
|
||||||
render_suggestions_dropdown(
|
render_suggestions_dropdown(
|
||||||
@@ -74,5 +70,3 @@ pub fn render_form_page(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub fn handle_intro_selection(
|
|||||||
index: usize,
|
index: usize,
|
||||||
) {
|
) {
|
||||||
let target_view = match index {
|
let target_view = match index {
|
||||||
0 => AppView::Form,
|
0 => AppView::Form("".to_string()), // or better: pick a real path
|
||||||
1 => AppView::Admin,
|
1 => AppView::Admin,
|
||||||
2 => AppView::Login,
|
2 => AppView::Login,
|
||||||
3 => AppView::Register,
|
3 => AppView::Register,
|
||||||
|
|||||||
@@ -34,10 +34,17 @@ pub async fn handle_search_palette_event(
|
|||||||
// Step 2: Process outside the borrow
|
// Step 2: Process outside the borrow
|
||||||
if let Some((id, content_json)) = maybe_data {
|
if let Some((id, content_json)) = maybe_data {
|
||||||
if let Ok(data) = serde_json::from_str::<HashMap<String, String>>(&content_json) {
|
if let Ok(data) = serde_json::from_str::<HashMap<String, String>>(&content_json) {
|
||||||
if let Some(fs) = app_state.form_state_mut() {
|
// Use current view path to access the active form
|
||||||
|
if let (Some(profile), Some(table)) = (
|
||||||
|
app_state.current_view_profile_name.clone(),
|
||||||
|
app_state.current_view_table_name.clone(),
|
||||||
|
) {
|
||||||
|
let path = format!("{}/{}", profile, table);
|
||||||
|
if let Some(fs) = app_state.form_state_for_path(&path) {
|
||||||
let detached_pos = fs.total_count + 2;
|
let detached_pos = fs.total_count + 2;
|
||||||
fs.update_from_response(&data, detached_pos);
|
fs.update_from_response(&data, detached_pos);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
should_close = true;
|
should_close = true;
|
||||||
outcome_message = Some(format!("Loaded record ID {}", id));
|
outcome_message = Some(format!("Loaded record ID {}", id));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,16 +99,40 @@ impl AppState {
|
|||||||
self.current_view_table_name = Some(table_name);
|
self.current_view_table_name = Some(table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the current view's editor is in Edit mode.
|
||||||
|
/// Uses current_view_profile_name/current_view_table_name to build the path.
|
||||||
pub fn is_canvas_edit_mode(&self) -> bool {
|
pub fn is_canvas_edit_mode(&self) -> bool {
|
||||||
matches!(self.form_editor.as_ref().map(|e| e.mode()), Some(canvas::AppMode::Edit))
|
if let (Some(profile), Some(table)) =
|
||||||
|
(self.current_view_profile_name.as_ref(), self.current_view_table_name.as_ref())
|
||||||
|
{
|
||||||
|
let path = format!("{}/{}", profile, table);
|
||||||
|
if let Some(editor) = self.form_editor.get(&path) {
|
||||||
|
return matches!(editor.mode(), canvas::AppMode::Edit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mutable editor accessor
|
||||||
pub fn editor_for_path(&mut self, path: &str) -> Option<&mut FormEditor<FormState>> {
|
pub fn editor_for_path(&mut self, path: &str) -> Option<&mut FormEditor<FormState>> {
|
||||||
self.form_editor.get_mut(path)
|
self.form_editor.get_mut(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mutable FormState accessor
|
||||||
pub fn form_state_for_path(&mut self, path: &str) -> Option<&mut FormState> {
|
pub fn form_state_for_path(&mut self, path: &str) -> Option<&mut FormState> {
|
||||||
self.form_editor.get_mut(path).map(|e| e.data_provider_mut())
|
self.form_editor
|
||||||
|
.get_mut(path)
|
||||||
|
.map(|e| e.data_provider_mut())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Immutable editor accessor
|
||||||
|
pub fn editor_for_path_ref(&self, path: &str) -> Option<&FormEditor<FormState>> {
|
||||||
|
self.form_editor.get(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Immutable FormState accessor
|
||||||
|
pub fn form_state_for_path_ref(&self, path: &str) -> Option<&FormState> {
|
||||||
|
self.form_editor.get(path).map(|e| e.data_provider())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ensure_form_editor<F>(&mut self, path: &str, config: &Config, loader: F)
|
pub fn ensure_form_editor<F>(&mut self, path: &str, config: &Config, loader: F)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ use crate::buffer::state::BufferState;
|
|||||||
use crate::state::app::state::AppState;
|
use crate::state::app::state::AppState;
|
||||||
use crate::state::pages::auth::AuthState;
|
use crate::state::pages::auth::AuthState;
|
||||||
use crate::bottom_panel::layout::{bottom_panel_constraints, render_bottom_panel};
|
use crate::bottom_panel::layout::{bottom_panel_constraints, render_bottom_panel};
|
||||||
|
use canvas::FormEditor;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::{Constraint, Direction, Layout},
|
layout::{Constraint, Direction, Layout},
|
||||||
Frame,
|
Frame,
|
||||||
@@ -114,7 +115,7 @@ pub fn render_ui(
|
|||||||
app_state,
|
app_state,
|
||||||
state,
|
state,
|
||||||
),
|
),
|
||||||
Page::Form(state) => {
|
Page::Form(path) => {
|
||||||
let (sidebar_area, form_actual_area) =
|
let (sidebar_area, form_actual_area) =
|
||||||
calculate_sidebar_layout(app_state.ui.show_sidebar, main_content_area);
|
calculate_sidebar_layout(app_state.ui.show_sidebar, main_content_area);
|
||||||
if let Some(sidebar_rect) = sidebar_area {
|
if let Some(sidebar_rect) = sidebar_area {
|
||||||
@@ -143,18 +144,26 @@ pub fn render_ui(
|
|||||||
.split(form_actual_area)[1]
|
.split(form_actual_area)[1]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(editor) = app_state.editor_for_path_ref(path) {
|
||||||
|
let (total_count, current_position) =
|
||||||
|
if let Some(fs) = app_state.form_state_for_path_ref(path) {
|
||||||
|
(fs.total_count, fs.current_position)
|
||||||
|
} else {
|
||||||
|
(0, 1)
|
||||||
|
};
|
||||||
|
|
||||||
render_form_page(
|
render_form_page(
|
||||||
f,
|
f,
|
||||||
form_render_area,
|
form_render_area,
|
||||||
app_state,
|
editor,
|
||||||
state,
|
|
||||||
app_state.current_view_table_name.as_deref().unwrap_or(""),
|
app_state.current_view_table_name.as_deref().unwrap_or(""),
|
||||||
theme,
|
theme,
|
||||||
state.total_count,
|
total_count,
|
||||||
state.current_position,
|
current_position,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Global overlays (not tied to a page)
|
// Global overlays (not tied to a page)
|
||||||
if let Some(area) = buffer_list_area {
|
if let Some(area) = buffer_list_area {
|
||||||
@@ -186,6 +195,7 @@ pub fn render_ui(
|
|||||||
theme,
|
theme,
|
||||||
current_fps,
|
current_fps,
|
||||||
app_state,
|
app_state,
|
||||||
|
router,
|
||||||
navigation_state,
|
navigation_state,
|
||||||
event_handler_command_input,
|
event_handler_command_input,
|
||||||
event_handler_command_mode_active,
|
event_handler_command_mode_active,
|
||||||
|
|||||||
@@ -118,10 +118,10 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
FormState::new(initial_profile.clone(), initial_table.clone(), initial_field_defs)
|
FormState::new(initial_profile.clone(), initial_table.clone(), initial_field_defs)
|
||||||
});
|
});
|
||||||
buffer_state.update_history(AppView::Form(path.clone()));
|
buffer_state.update_history(AppView::Form(path.clone()));
|
||||||
router.navigate(Page::Form(path));
|
router.navigate(Page::Form(path.clone()));
|
||||||
|
|
||||||
// Fetch initial count using app_state accessor
|
// Fetch initial count using app_state accessor
|
||||||
if let Some(form_state) = app_state.active_form_state_mut(&buffer_state) {
|
if let Some(form_state) = app_state.form_state_for_path(&path) {
|
||||||
UiService::fetch_and_set_table_count(&mut grpc_client, form_state)
|
UiService::fetch_and_set_table_count(&mut grpc_client, form_state)
|
||||||
.await
|
.await
|
||||||
.context(format!(
|
.context(format!(
|
||||||
@@ -154,9 +154,11 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
let mut table_just_switched = false;
|
let mut table_just_switched = false;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let position_before_event = app_state.active_form_state_mut(&buffer_state)
|
let position_before_event = if let Page::Form(path) = &router.current {
|
||||||
.map(|fs| fs.current_position)
|
app_state.form_state_for_path(path).map(|fs| fs.current_position).unwrap_or(1)
|
||||||
.unwrap_or(1);
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
let mut event_processed = false;
|
let mut event_processed = false;
|
||||||
|
|
||||||
// --- CHANNEL RECEIVERS ---
|
// --- CHANNEL RECEIVERS ---
|
||||||
@@ -181,7 +183,8 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
// --- ADDED: For live form autocomplete ---
|
// --- ADDED: For live form autocomplete ---
|
||||||
match event_handler.autocomplete_result_receiver.try_recv() {
|
match event_handler.autocomplete_result_receiver.try_recv() {
|
||||||
Ok(hits) => {
|
Ok(hits) => {
|
||||||
if let Some(form_state) = app_state.form_state_mut() {
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(form_state) = app_state.form_state_for_path(path) {
|
||||||
if form_state.autocomplete_active {
|
if form_state.autocomplete_active {
|
||||||
form_state.autocomplete_suggestions = hits;
|
form_state.autocomplete_suggestions = hits;
|
||||||
form_state.autocomplete_loading = false;
|
form_state.autocomplete_loading = false;
|
||||||
@@ -193,6 +196,7 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
event_handler.command_message = format!("Found {} suggestions.", form_state.autocomplete_suggestions.len());
|
event_handler.command_message = format!("Found {} suggestions.", form_state.autocomplete_suggestions.len());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
needs_redraw = true;
|
needs_redraw = true;
|
||||||
}
|
}
|
||||||
Err(mpsc::error::TryRecvError::Empty) => {}
|
Err(mpsc::error::TryRecvError::Empty) => {}
|
||||||
@@ -218,9 +222,9 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
|| app_state.ui.show_search_palette
|
|| app_state.ui.show_search_palette
|
||||||
|| event_handler.navigation_state.active;
|
|| event_handler.navigation_state.active;
|
||||||
if !overlay_active {
|
if !overlay_active {
|
||||||
if let Page::Form(_) = &router.current {
|
if let Page::Form(path) = &router.current {
|
||||||
if !app_state.ui.focus_outside_canvas {
|
if !app_state.ui.focus_outside_canvas {
|
||||||
if let Some(editor) = app_state.active_form_editor_mut(&buffer_state) {
|
if let Some(editor) = app_state.editor_for_path(path) {
|
||||||
match editor.handle_key_event(*key_event) {
|
match editor.handle_key_event(*key_event) {
|
||||||
KeyEventOutcome::Consumed(Some(msg)) => {
|
KeyEventOutcome::Consumed(Some(msg)) => {
|
||||||
event_handler.command_message = msg;
|
event_handler.command_message = msg;
|
||||||
@@ -245,9 +249,7 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get form state from app_state and pass to handle_event
|
// Call handle_event directly
|
||||||
let form_state = app_state.form_state_mut().unwrap();
|
|
||||||
|
|
||||||
let event_outcome_result = event_handler.handle_event(
|
let event_outcome_result = event_handler.handle_event(
|
||||||
event,
|
event,
|
||||||
&config,
|
&config,
|
||||||
@@ -272,8 +274,8 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
}
|
}
|
||||||
EventOutcome::DataSaved(save_outcome, message) => {
|
EventOutcome::DataSaved(save_outcome, message) => {
|
||||||
event_handler.command_message = message;
|
event_handler.command_message = message;
|
||||||
// Clone form_state to avoid double borrow
|
if let Page::Form(path) = &router.current {
|
||||||
let mut temp_form_state = app_state.form_state().unwrap().clone();
|
if let Some(mut temp_form_state) = app_state.form_state_for_path(path).cloned() {
|
||||||
if let Err(e) = UiService::handle_save_outcome(
|
if let Err(e) = UiService::handle_save_outcome(
|
||||||
save_outcome,
|
save_outcome,
|
||||||
&mut grpc_client,
|
&mut grpc_client,
|
||||||
@@ -284,10 +286,12 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
format!("Error handling save outcome: {}", e);
|
format!("Error handling save outcome: {}", e);
|
||||||
}
|
}
|
||||||
// Update app_state with changes
|
// Update app_state with changes
|
||||||
if let Some(form_state) = app_state.form_state_mut() {
|
if let Some(form_state) = app_state.form_state_for_path(path) {
|
||||||
*form_state = temp_form_state;
|
*form_state = temp_form_state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
EventOutcome::ButtonSelected { .. } => {}
|
EventOutcome::ButtonSelected { .. } => {}
|
||||||
EventOutcome::TableSelected { path } => {
|
EventOutcome::TableSelected { path } => {
|
||||||
let parts: Vec<&str> = path.split('/').collect();
|
let parts: Vec<&str> = path.split('/').collect();
|
||||||
@@ -296,7 +300,7 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
let table_name = parts[1].to_string();
|
let table_name = parts[1].to_string();
|
||||||
|
|
||||||
app_state.set_current_view_table(profile_name, table_name);
|
app_state.set_current_view_table(profile_name, table_name);
|
||||||
buffer_state.update_history(AppView::Form);
|
buffer_state.update_history(AppView::Form(path.clone()));
|
||||||
event_handler.command_message = format!("Loading table: {}", path);
|
event_handler.command_message = format!("Loading table: {}", path);
|
||||||
} else {
|
} else {
|
||||||
event_handler.command_message = format!("Invalid table path: {}", path);
|
event_handler.command_message = format!("Invalid table path: {}", path);
|
||||||
@@ -382,7 +386,7 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
router.navigate(Page::Intro(intro_state.clone()));
|
router.navigate(Page::Intro(intro_state.clone()));
|
||||||
}
|
}
|
||||||
AppView::Login => {
|
AppView::Login => {
|
||||||
// Do not re-create the page every frame. If we’re already on Login,
|
// Do not re-create the page every frame. If we're already on Login,
|
||||||
// keep it. If we just switched into Login, create it once and
|
// keep it. If we just switched into Login, create it once and
|
||||||
// inject the keymap.
|
// inject the keymap.
|
||||||
if let Page::Login(_) = &router.current {
|
if let Page::Login(_) = &router.current {
|
||||||
@@ -440,16 +444,15 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
}
|
}
|
||||||
AppView::AddTable => router.navigate(Page::AddTable(admin_state.add_table_state.clone())),
|
AppView::AddTable => router.navigate(Page::AddTable(admin_state.add_table_state.clone())),
|
||||||
AppView::AddLogic => router.navigate(Page::AddLogic(admin_state.add_logic_state.clone())),
|
AppView::AddLogic => router.navigate(Page::AddLogic(admin_state.add_logic_state.clone())),
|
||||||
AppView::Form => {
|
AppView::Form(path) => {
|
||||||
if let Some(form_state) = app_state.form_state().cloned() {
|
// Router now carries the path; just navigate with it
|
||||||
router.navigate(Page::Form(form_state));
|
router.navigate(Page::Form(path.clone()));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AppView::Scratch => {}
|
AppView::Scratch => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Page::Form(_) = &router.current {
|
if let Page::Form(current_path) = &router.current {
|
||||||
let current_view_profile = app_state.current_view_profile_name.clone();
|
let current_view_profile = app_state.current_view_profile_name.clone();
|
||||||
let current_view_table = app_state.current_view_table_name.clone();
|
let current_view_table = app_state.current_view_table_name.clone();
|
||||||
|
|
||||||
@@ -475,9 +478,10 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
{
|
{
|
||||||
Ok(new_form_state) => {
|
Ok(new_form_state) => {
|
||||||
// Set the new form state and fetch count
|
// Set the new form state and fetch count
|
||||||
app_state.set_form_state(new_form_state, &config);
|
let path = format!("{}/{}", prof_name, tbl_name);
|
||||||
|
app_state.ensure_form_editor(&path, &config, || new_form_state);
|
||||||
|
|
||||||
if let Some(form_state) = app_state.form_state_mut() {
|
if let Some(form_state) = app_state.form_state_for_path(&path) {
|
||||||
if let Err(e) = UiService::fetch_and_set_table_count(
|
if let Err(e) = UiService::fetch_and_set_table_count(
|
||||||
&mut grpc_client,
|
&mut grpc_client,
|
||||||
form_state,
|
form_state,
|
||||||
@@ -596,18 +600,20 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_position = app_state.form_state()
|
let current_position = if let Page::Form(path) = &router.current {
|
||||||
.map(|fs| fs.current_position)
|
app_state.form_state_for_path(path).map(|fs| fs.current_position).unwrap_or(1)
|
||||||
.unwrap_or(1);
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
let position_changed = current_position != position_before_event;
|
let position_changed = current_position != position_before_event;
|
||||||
let mut position_logic_needs_redraw = false;
|
let mut position_logic_needs_redraw = false;
|
||||||
|
|
||||||
if let Page::Form(form_state) = &mut router.current {
|
if let Page::Form(path) = &router.current {
|
||||||
if !table_just_switched {
|
if !table_just_switched {
|
||||||
if position_changed && !app_state.is_canvas_edit_mode() {
|
if position_changed && !app_state.is_canvas_edit_mode() {
|
||||||
position_logic_needs_redraw = true;
|
position_logic_needs_redraw = true;
|
||||||
|
|
||||||
if let Some(form_state) = app_state.form_state_mut() {
|
if let Some(form_state) = app_state.form_state_for_path(path) {
|
||||||
if form_state.current_position > form_state.total_count {
|
if form_state.current_position > form_state.total_count {
|
||||||
form_state.reset_to_empty();
|
form_state.reset_to_empty();
|
||||||
event_handler.command_message = format!(
|
event_handler.command_message = format!(
|
||||||
@@ -643,7 +649,7 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
event_handler.ideal_cursor_column.min(max_cursor_pos);
|
event_handler.ideal_cursor_column.min(max_cursor_pos);
|
||||||
}
|
}
|
||||||
} else if !position_changed && !app_state.is_canvas_edit_mode() {
|
} else if !position_changed && !app_state.is_canvas_edit_mode() {
|
||||||
if let Some(form_state) = app_state.form_state_mut() {
|
if let Some(form_state) = app_state.form_state_for_path(path) {
|
||||||
let current_input_str = form_state.get_current_input();
|
let current_input_str = form_state.get_current_input();
|
||||||
let current_input_len = current_input_str.chars().count();
|
let current_input_len = current_input_str.chars().count();
|
||||||
let max_cursor_pos = if current_input_len > 0 {
|
let max_cursor_pos = if current_input_len > 0 {
|
||||||
@@ -709,9 +715,11 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
terminal.show_cursor()?;
|
terminal.show_cursor()?;
|
||||||
} else {
|
} else {
|
||||||
// Inside canvas → let canvas handle it
|
// Inside canvas → let canvas handle it
|
||||||
if let Some(editor) = &app_state.form_editor {
|
if let Page::Form(path) = &router.current {
|
||||||
|
if let Some(editor) = app_state.editor_for_path(path) {
|
||||||
let _ = CursorManager::update_for_mode(editor.mode());
|
let _ = CursorManager::update_for_mode(editor.mode());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if let Page::Login(page) = &router.current {
|
if let Page::Login(page) = &router.current {
|
||||||
let _ = CursorManager::update_for_mode(page.editor.mode());
|
let _ = CursorManager::update_for_mode(page.editor.mode());
|
||||||
}
|
}
|
||||||
@@ -727,16 +735,9 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround for borrow checker
|
|
||||||
let current_dir = app_state.current_dir.clone();
|
let current_dir = app_state.current_dir.clone();
|
||||||
let form_state_clone = if let Page::Form(path) = &router.current {
|
terminal
|
||||||
app_state.form_state_for_path(path).cloned()
|
.draw(|f| {
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(form_state_clone) = form_state_clone {
|
|
||||||
terminal.draw(|f| {
|
|
||||||
render_ui(
|
render_ui(
|
||||||
f,
|
f,
|
||||||
&mut router,
|
&mut router,
|
||||||
@@ -754,7 +755,6 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
.context("Terminal draw call failed")?;
|
.context("Terminal draw call failed")?;
|
||||||
needs_redraw = false;
|
needs_redraw = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let frame_duration = now.duration_since(last_frame_time);
|
let frame_duration = now.duration_since(last_frame_time);
|
||||||
|
|||||||
Reference in New Issue
Block a user