From 6b241304fb5839ae2c1039ea91fdb1b5361ebd74 Mon Sep 17 00:00:00 2001 From: filipriec Date: Thu, 10 Apr 2025 15:36:43 +0200 Subject: [PATCH] dialog login functionality --- client/src/modes/general/dialog.rs | 27 ++++++++++-------------- client/src/modes/handlers/event.rs | 2 ++ client/src/state/state.rs | 18 ++++++++++------ client/src/tui/functions/common/login.rs | 7 +++--- client/src/ui/handlers/context.rs | 10 +++++++++ 5 files changed, 39 insertions(+), 25 deletions(-) diff --git a/client/src/modes/general/dialog.rs b/client/src/modes/general/dialog.rs index 815f5bf..6f51449 100644 --- a/client/src/modes/general/dialog.rs +++ b/client/src/modes/general/dialog.rs @@ -3,7 +3,8 @@ use crossterm::event::{Event, KeyCode}; use crate::config::binds::config::Config; use crate::state::state::AppState; -use crate::modes::handlers::event::EventOutcome; // Use EventOutcome from event handler +use crate::modes::handlers::event::EventOutcome; +use crate::ui::handlers::context::DialogPurpose; /// Handles key events specifically when a dialog is active. /// Returns Some(Result) if the event was handled (consumed), @@ -41,22 +42,16 @@ pub async fn handle_dialog_event( } "select" => { let selected_index = app_state.ui.dialog.dialog_active_button_index; - let selected_label = app_state.get_active_dialog_button_label().unwrap_or("").to_string(); - let mut message = format!("Dialog '{}' selected", selected_label); + let purpose = match app_state.ui.dialog.purpose { + Some(p) => p, + None => { + app_state.hide_dialog(); + return Some(Ok(EventOutcome::Ok("Internal Error: Dialog context lost".to_string()))); + } + }; - // --- Add specific actions based on button index or label --- - if selected_label.eq_ignore_ascii_case("menu") { - app_state.ui.show_login = false; - app_state.ui.show_intro = true; - // focus_outside_canvas is handled by hide_dialog - message = "Returning to menu".to_string(); - } else if selected_label.eq_ignore_ascii_case("exit") { - app_state.hide_dialog(); - return Some(Ok(EventOutcome::Exit("Exiting via dialog".to_string()))); - } - // --- End specific actions --- - app_state.hide_dialog(); // Hide dialog after processing selection - return Some(Ok(EventOutcome::Ok(message))); // Consume event + app_state.hide_dialog(); + return Some(Ok(EventOutcome::DialogAction { purpose, selected_index })); } _ => {} // Ignore other general actions when dialog is shown } diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index e9e2ed7..db94b77 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -21,6 +21,7 @@ use crate::modes::{ use crate::config::binds::key_sequences::KeySequenceTracker; use crate::modes::handlers::mode_manager::{ModeManager, AppMode}; use crate::tui::functions::common::form::SaveOutcome; +use crate::ui::handlers::context::DialogPurpose; #[derive(Debug, Clone, PartialEq, Eq)] pub enum EventOutcome { @@ -28,6 +29,7 @@ pub enum EventOutcome { Exit(String), DataSaved(SaveOutcome, String), ButtonSelected { context: UiContext, index: usize }, + DialogAction { purpose: DialogPurpose, selected_index: usize }, } pub struct EventHandler { diff --git a/client/src/state/state.rs b/client/src/state/state.rs index b9f9b2a..98f9620 100644 --- a/client/src/state/state.rs +++ b/client/src/state/state.rs @@ -4,6 +4,7 @@ use std::env; use common::proto::multieko2::table_definition::ProfileTreeResponse; use crate::components::IntroState; use crate::modes::handlers::mode_manager::AppMode; +use crate::ui::handlers::context::DialogPurpose; pub struct DialogState { pub dialog_show: bool, @@ -11,6 +12,7 @@ pub struct DialogState { pub dialog_message: String, pub dialog_buttons: Vec, pub dialog_active_button_index: usize, + pub purpose: Option, } pub struct UiState { @@ -84,11 +86,13 @@ impl AppState { title: &str, message: &str, buttons: Vec, + purpose: DialogPurpose, ) { self.ui.dialog.dialog_title = title.to_string(); self.ui.dialog.dialog_message = message.to_string(); self.ui.dialog.dialog_buttons = buttons; - self.ui.dialog.dialog_active_button_index = 0; // Default to first button + self.ui.dialog.dialog_active_button_index = 0; + self.ui.dialog.purpose = Some(purpose); self.ui.dialog.dialog_show = true; self.ui.focus_outside_canvas = true; } @@ -100,6 +104,7 @@ impl AppState { self.ui.dialog.dialog_message.clear(); self.ui.dialog.dialog_buttons.clear(); self.ui.dialog.dialog_active_button_index = 0; + self.ui.dialog.purpose = None; self.ui.focus_outside_canvas = false; } @@ -150,11 +155,12 @@ impl Default for UiState { impl Default for DialogState { fn default() -> Self { Self { - dialog_show: false, // Use new name - dialog_title: String::new(), // Use new name - dialog_message: String::new(), // Use new name - dialog_buttons: Vec::new(), // Use new name - dialog_active_button_index: 0, // Use new name + dialog_show: false, + dialog_title: String::new(), + dialog_message: String::new(), + dialog_buttons: Vec::new(), + dialog_active_button_index: 0, + purpose: None, } } } diff --git a/client/src/tui/functions/common/login.rs b/client/src/tui/functions/common/login.rs index c50c34c..921e06e 100644 --- a/client/src/tui/functions/common/login.rs +++ b/client/src/tui/functions/common/login.rs @@ -3,8 +3,7 @@ use crate::services::auth::AuthClient; use crate::state::pages::auth::AuthState; use crate::state::state::AppState; use crate::state::canvas_state::CanvasState; -// Remove unused import if CanvasState is not directly used here -// use crate::state::canvas_state::CanvasState; +use crate::ui::handlers::context::DialogPurpose; /// Attempts to log the user in using the provided credentials via gRPC. /// Updates AuthState and AppState on success or failure. @@ -51,6 +50,7 @@ pub async fn save( "Login Success", &success_message, vec!["Menu".to_string(), "Exit".to_string()], + DialogPurpose::LoginSuccess, ); Ok("Login successful, details shown in dialog.".to_string()) @@ -62,7 +62,8 @@ pub async fn save( app_state.show_dialog( "Login Failed", &error_message, - vec!["OK".to_string()], // Pass buttons here + vec!["OK".to_string()], + DialogPurpose::LoginFailed, ); // REMOVE these lines: // app_state.ui.dialog.dialog_title = "Login Failed".to_string(); diff --git a/client/src/ui/handlers/context.rs b/client/src/ui/handlers/context.rs index 9607e10..7c54eb8 100644 --- a/client/src/ui/handlers/context.rs +++ b/client/src/ui/handlers/context.rs @@ -1,3 +1,5 @@ +// src/ui/handlers/context.rs + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum UiContext { Intro, @@ -6,3 +8,11 @@ pub enum UiContext { Dialog, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DialogPurpose { + LoginSuccess, + LoginFailed, + // TODO in the future: + // ConfirmQuit, +} +