p2p_chat/ui/runner/actions/
dispatch.rs

1//! This module contains the core logic for dispatching UI actions.
2use std::sync::Arc;
3use std::time::Duration;
4
5use anyhow::Result;
6use tokio::sync::mpsc;
7use tokio::time::sleep;
8use tracing::debug;
9
10use crate::cli::commands::Node;
11use crate::ui::{UIAction, UIEvent};
12
13use super::context::CommandContext;
14use super::execute::execute_chat_command;
15
16/// Handles incoming `UIAction`s and dispatches them to appropriate handlers.
17///
18/// This function is the central point for processing user-initiated actions,
19/// translating them into background tasks or direct application responses.
20///
21/// # Arguments
22///
23/// * `action` - The `UIAction` to be handled.
24/// * `node` - A shared reference to the application's core `Node`.
25/// * `ui_sender` - The sender for emitting `UIEvent`s back to the UI.
26///
27/// # Errors
28///
29/// Returns an error if an unrecoverable issue occurs during action processing.
30pub async fn handle_ui_action(
31    action: UIAction,
32    node: &Arc<Node>,
33    ui_sender: mpsc::UnboundedSender<UIEvent>,
34) -> Result<()> {
35    if let UIAction::ExecuteCommand(ref command) = action {
36        if command.trim() == "exit" {
37            let _ = ui_sender.send(UIEvent::ChatMessage("👋 Goodbye!".to_string()));
38            sleep(Duration::from_millis(50)).await;
39            std::process::exit(0);
40        }
41    } else if matches!(action, UIAction::Exit) {
42        let _ = ui_sender.send(UIEvent::ChatMessage("👋 Goodbye!".to_string()));
43        sleep(Duration::from_millis(50)).await;
44        std::process::exit(0);
45    }
46
47    let context = CommandContext::new(node.clone(), ui_sender.clone());
48    tokio::spawn(async move {
49        let cmd_to_run = match action {
50            UIAction::SendMessage(recipient, message) => {
51                format!("send {} {}", recipient, message)
52            }
53            UIAction::ExecuteCommand(command) => command,
54            UIAction::Exit => return,
55        };
56
57        debug!("Executing command in background: '{}'", cmd_to_run);
58        if let Err(e) = execute_chat_command(&cmd_to_run, context.clone()).await {
59            context.emit_chat(format!("❌ Error: {}", e));
60        }
61    });
62
63    Ok(())
64}