refactor happend and its perfectly fine

This commit is contained in:
filipriec
2025-04-18 23:16:22 +02:00
parent 8d1adccec6
commit dc6c1ce43c
4 changed files with 99 additions and 196 deletions

View File

@@ -9,7 +9,10 @@ use crate::state::{
use crate::ui::handlers::context::DialogPurpose;
use crate::state::app::buffer::{AppView, BufferState};
use common::proto::multieko2::auth::AuthResponse;
use anyhow::Result;
use anyhow::Context;
use tokio::spawn;
use tokio::sync::mpsc;
use tracing::{info, error};
#[derive(Debug)]
pub enum RegisterResult {
@@ -18,109 +21,6 @@ pub enum RegisterResult {
ConnectionError(String),
}
/// Attempts to register the user using the provided details via gRPC.
/// Updates RegisterState and AppState on success or failure.
pub async fn save(
register_state: &mut RegisterState,
auth_client: &mut AuthClient,
app_state: &mut AppState,
) -> Result<String> {
let username = register_state.username.clone();
let email = register_state.email.clone();
// Handle optional passwords: send None if empty, Some(value) otherwise
let password = if register_state.password.is_empty() {
None
} else {
Some(register_state.password.clone())
};
let password_confirmation = if register_state.password_confirmation.is_empty() {
None
} else {
Some(register_state.password_confirmation.clone())
};
let role = if register_state.role.is_empty() {
None
} else {
Some(register_state.role.clone())
};
// Basic client-side validation (example)
if username.is_empty() {
app_state.show_dialog(
"Registration Failed",
"Username cannot be empty.",
vec!["OK".to_string()],
DialogPurpose::RegisterFailed,
);
register_state.error_message = Some("Username cannot be empty.".to_string());
return Ok("Registration failed: Username cannot be empty.".to_string());
}
if password.is_some() && password != password_confirmation {
app_state.show_dialog(
"Registration Failed",
"Passwords do not match.",
vec!["OK".to_string()],
DialogPurpose::RegisterFailed,
);
register_state.error_message = Some("Passwords do not match.".to_string());
return Ok("Registration failed: Passwords do not match.".to_string());
}
// Clear previous error/dialog state before attempting
register_state.error_message = None;
app_state.hide_dialog();
// Call the gRPC register method
match auth_client.register(username, email, password, password_confirmation, role).await {
Ok(response) => {
// Clear fields on success? Optional, maybe wait for dialog confirmation.
// register_state.username.clear();
// register_state.email.clear();
// register_state.password.clear();
// register_state.password_confirmation.clear();
register_state.set_has_unsaved_changes(false);
let success_message = format!(
"Registration Successful!\n\n\
User ID: {}\n\
Username: {}\n\
Email: {}\n\
Role: {}",
response.id,
response.username,
response.email,
response.role
);
// Show success dialog
app_state.show_dialog(
"Registration Success",
&success_message,
vec!["OK".to_string()], // Simple OK for now
DialogPurpose::RegisterSuccess,
);
Ok("Registration successful, details shown in dialog.".to_string())
}
Err(e) => {
let error_message = format!("{}", e);
register_state.error_message = Some(error_message.clone());
register_state.set_has_unsaved_changes(true); // Keep changes on error
// Show error dialog
app_state.show_dialog(
"Registration Failed",
&error_message,
vec!["OK".to_string()],
DialogPurpose::RegisterFailed,
);
Ok(format!("Registration failed: {}", error_message))
}
}
}
/// Clears the registration form fields.
pub async fn revert(
register_state: &mut RegisterState,
@@ -161,3 +61,89 @@ pub async fn back_to_login(
"Returned to main menu".to_string()
}
/// Validates input, shows loading, and spawns the registration task.
pub fn initiate_registration(
register_state: &RegisterState,
app_state: &mut AppState,
sender: mpsc::Sender<RegisterResult>,
) -> String {
// Clone necessary data
let username = register_state.username.clone();
let email = register_state.email.clone();
let password = register_state.password.clone();
let password_confirmation = register_state.password_confirmation.clone();
let role = register_state.role.clone();
// 1. Client-side validation
if username.trim().is_empty() {
app_state.show_dialog("Registration Failed", "Username cannot be empty.", vec!["OK".to_string()], DialogPurpose::RegisterFailed);
"Username cannot be empty.".to_string()
} else if !password.is_empty() && password != password_confirmation {
app_state.show_dialog("Registration Failed", "Passwords do not match.", vec!["OK".to_string()], DialogPurpose::RegisterFailed);
"Passwords do not match.".to_string()
} else {
// 2. Show Loading Dialog
app_state.show_loading_dialog("Registering", "Please wait...");
// 3. Spawn the registration task
spawn(async move {
let register_outcome = match AuthClient::new().await {
Ok(mut auth_client) => {
// Handle optional fields correctly for the gRPC call
let password_opt = if password.is_empty() { None } else { Some(password) };
let password_conf_opt = if password_confirmation.is_empty() { None } else { Some(password_confirmation) };
let role_opt = if role.is_empty() { None } else { Some(role) };
match auth_client.register(username.clone(), email, password_opt, password_conf_opt, role_opt).await
.with_context(|| format!("Spawned register task failed for username: {}", username))
{
Ok(response) => RegisterResult::Success(response),
Err(e) => RegisterResult::Failure(format!("{}", e)),
}
}
Err(e) => RegisterResult::ConnectionError(format!("Failed to create AuthClient: {}", e)),
};
// Send result back to the main UI thread
if let Err(e) = sender.send(register_outcome).await {
error!("Failed to send registration result: {}", e);
}
});
// 4. Return immediately
"Registration initiated.".to_string()
}
}
/// Handles the result received from the registration task.
/// Returns true if a redraw is needed.
pub fn handle_registration_result(
result: RegisterResult,
app_state: &mut AppState,
register_state: &mut RegisterState,
) -> bool {
match result {
RegisterResult::Success(response) => {
let success_message = format!(
"Registration Successful!\n\nUser ID: {}\nUsername: {}\nEmail: {}\nRole: {}",
response.id, response.username, response.email, response.role
);
app_state.update_dialog_content(
&success_message,
vec!["OK".to_string()],
DialogPurpose::RegisterSuccess,
);
info!(message = %success_message, "Registration successful");
}
RegisterResult::Failure(err_msg) | RegisterResult::ConnectionError(err_msg) => {
app_state.update_dialog_content(
&err_msg,
vec!["OK".to_string()],
DialogPurpose::RegisterFailed,
);
register_state.error_message = Some(err_msg.clone());
error!(error = %err_msg, "Registration failed/connection error");
}
}
register_state.set_has_unsaved_changes(false); // Clear flag after processing
true // Request redraw as dialog content changed
}