chat_desktop/
main.rs

1use dioxus::prelude::*;
2use network_libp2p::NodeOptions;
3
4use chat_ui_components::{ChatApp, ChatAppSignals, use_chat_app_signals, run_chat_event_loop};
5
6const CSS: &str = include_str!("../public/styles.css");
7
8fn main() {
9    tracing_subscriber::fmt()
10        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
11        .init();
12
13    dioxus::launch(App);
14}
15
16#[component]
17fn App() -> Element {
18    let signals = use_chat_app_signals();
19    let ChatAppSignals {
20        mut tab_lock_acquired,
21        mut coordinator_handle,
22        mut error_messages,
23        ..
24    } = signals;
25
26    // Spawn coordinator and event listener
27    use_hook(|| {
28        spawn(async move {
29            let node = {
30                let node_options = NodeOptions {
31                    listen_addresses: vec!["/ip4/0.0.0.0/tcp/0".into()],
32                    bootstrap_peers: chat_core::config::BOOTSTRAP_PEERS.iter().map(|s| s.to_string()).collect(),
33                    max_connections: 100,
34                    dht_client_mode: true,
35                    dht_discovery_enabled: true,
36                    stun_servers: None,
37                };
38                network_libp2p::build_node(node_options).await
39            };
40
41            match node {
42                Ok(node) => {
43                    let data_dir = dirs::data_dir()
44                        .unwrap_or_else(|| std::path::PathBuf::from("."))
45                        .join("p2pandemonium");
46                    let _ = std::fs::create_dir_all(&data_dir);
47
48                    let conn = chat_platform_native::storage::open_storage(
49                        "chat",
50                        Some(data_dir.to_str().unwrap()),
51                    ).await.unwrap();
52                    let storage = chat_core::storage::SqliteStorage::new(conn);
53                    storage.init_schema().unwrap();
54
55                    let (handle, events, loop_fut) = chat_core::coordinator::build(node, storage);
56
57                    // Check tab lock
58                    let lock_path = data_dir.join("app.lock");
59                    if chat_platform_native::tab_lock::TabLock::try_acquire(&lock_path).is_none() {
60                        tab_lock_acquired.set(false);
61                        return;
62                    }
63
64                    // Spawn the coordinator loop
65                    spawn(loop_fut.run());
66
67                    coordinator_handle.set(Some(handle.clone()));
68
69                    // Shared event loop
70                    run_chat_event_loop(events, signals).await;
71                }
72                Err(e) => {
73                    error_messages.set(vec![format!("Failed to create node: {}", e)]);
74                }
75            }
76        });
77    });
78
79    rsx! {
80        style { dangerous_inner_html: CSS }
81        ChatApp { signals, on_room_left: None }
82    }
83}