diff --git a/crates/lanspread-peer/src/lib.rs b/crates/lanspread-peer/src/lib.rs index 3570e47..b5f9a53 100644 --- a/crates/lanspread-peer/src/lib.rs +++ b/crates/lanspread-peer/src/lib.rs @@ -128,6 +128,7 @@ pub enum PeerEvent { PeerDisconnected(SocketAddr), PeerDiscovered(SocketAddr), PeerLost(SocketAddr), + PeerCountUpdated(usize), } #[derive(Clone, Debug)] @@ -560,6 +561,7 @@ pub enum PeerCommand { file_descriptions: Vec, }, SetGameDir(String), + GetPeerCount, } async fn initial_peer_alive_check(conn: &mut Connection) -> bool { @@ -1312,6 +1314,9 @@ pub async fn run_peer( PeerCommand::SetGameDir(game_dir) => { handle_set_game_dir_command(&ctx, game_dir).await; } + PeerCommand::GetPeerCount => { + handle_get_peer_count_command(&ctx, &tx_notify_ui).await; + } } } @@ -1605,6 +1610,14 @@ async fn handle_set_game_dir_command(ctx: &Ctx, game_dir: String) { }); } +async fn handle_get_peer_count_command(ctx: &Ctx, tx_notify_ui: &UnboundedSender) { + log::info!("GetPeerCount command received"); + let peer_count = { ctx.peer_game_db.read().await.get_peer_addresses().len() }; + if let Err(e) = tx_notify_ui.send(PeerEvent::PeerCountUpdated(peer_count)) { + log::error!("Failed to send PeerCountUpdated event: {e}"); + } +} + async fn handle_peer_connection( mut connection: Connection, ctx: PeerCtx, @@ -1836,6 +1849,15 @@ async fn run_peer_discovery( log::error!("Failed to send PeerDiscovered event: {e}"); } + // Send updated peer count + let current_peer_count = + { peer_game_db.read().await.get_peer_addresses().len() }; + if let Err(e) = + tx_notify_ui.send(PeerEvent::PeerCountUpdated(current_peer_count)) + { + log::error!("Failed to send PeerCountUpdated event: {e}"); + } + // Request games from this peer let tx_notify_ui_clone = tx_notify_ui.clone(); let peer_game_db_clone = peer_game_db.clone(); @@ -2014,6 +2036,15 @@ async fn run_ping_service( { log::error!("Failed to send PeerLost event: {e}"); } + + // Send updated peer count + let current_peer_count = + { peer_game_db_clone.read().await.get_peer_addresses().len() }; + if let Err(e) = tx_notify_ui_clone + .send(PeerEvent::PeerCountUpdated(current_peer_count)) + { + log::error!("Failed to send PeerCountUpdated event: {e}"); + } } } } @@ -2028,6 +2059,15 @@ async fn run_ping_service( { log::error!("Failed to send PeerLost event: {e}"); } + + // Send updated peer count + let current_peer_count = + { peer_game_db_clone.read().await.get_peer_addresses().len() }; + if let Err(e) = tx_notify_ui_clone + .send(PeerEvent::PeerCountUpdated(current_peer_count)) + { + log::error!("Failed to send PeerCountUpdated event: {e}"); + } } } } @@ -2048,6 +2088,12 @@ async fn run_ping_service( if let Err(e) = tx_notify_ui.send(PeerEvent::PeerLost(stale_addr)) { log::error!("Failed to send PeerLost event: {e}"); } + + // Send updated peer count + let current_peer_count = { peer_game_db.read().await.get_peer_addresses().len() }; + if let Err(e) = tx_notify_ui.send(PeerEvent::PeerCountUpdated(current_peer_count)) { + log::error!("Failed to send PeerCountUpdated event: {e}"); + } } } } diff --git a/crates/lanspread-tauri-deno-ts/src-tauri/src/lib.rs b/crates/lanspread-tauri-deno-ts/src-tauri/src/lib.rs index af7f97a..f191f20 100644 --- a/crates/lanspread-tauri-deno-ts/src-tauri/src/lib.rs +++ b/crates/lanspread-tauri-deno-ts/src-tauri/src/lib.rs @@ -208,6 +208,23 @@ async fn update_game(id: String, state: tauri::State<'_, LanSpreadState>) -> tau } } +#[tauri::command] +async fn get_peer_count(state: tauri::State<'_, LanSpreadState>) -> tauri::Result { + let peer_ctrl_arc = state.inner().peer_ctrl.clone(); + let peer_ctrl = peer_ctrl_arc.read().await.clone(); + + if let Some(peer_ctrl) = peer_ctrl { + // Send a request to get peer count + if let Err(e) = peer_ctrl.send(PeerCommand::GetPeerCount) { + log::error!("Failed to send GetPeerCount message to peer: {e:?}"); + } + } + + // For now, we'll return 0 and rely on the event-based updates + // The UI will get the actual count through peer-count-updated events + Ok(0) +} + #[cfg(target_os = "windows")] fn run_as_admin(file: &str, params: &str, dir: &str) -> bool { use std::{ffi::OsStr, os::windows::ffi::OsStrExt}; @@ -602,7 +619,8 @@ pub fn run() { install_game, run_game, update_game_directory, - update_game + update_game, + get_peer_count ]) .manage(lanspread_state) .setup({ @@ -847,6 +865,12 @@ pub fn run() { log::error!("Failed to emit peer-lost event: {e}"); } } + PeerEvent::PeerCountUpdated(count) => { + log::info!("Peer count updated: {count}"); + if let Err(e) = app_handle.emit("peer-count-updated", Some(count)) { + log::error!("Failed to emit peer-count-updated event: {e}"); + } + } } } }); diff --git a/crates/lanspread-tauri-deno-ts/src/App.css b/crates/lanspread-tauri-deno-ts/src/App.css index 5146aa0..df12a4a 100644 --- a/crates/lanspread-tauri-deno-ts/src/App.css +++ b/crates/lanspread-tauri-deno-ts/src/App.css @@ -284,3 +284,10 @@ h1.align-center { font-weight: bold; color: #4866b9; } + +.top-left-peer-count { + position: absolute; + top: 20px; + left: 20px; + z-index: 1001; +} diff --git a/crates/lanspread-tauri-deno-ts/src/App.tsx b/crates/lanspread-tauri-deno-ts/src/App.tsx index 77ad5f9..cc3f5c2 100644 --- a/crates/lanspread-tauri-deno-ts/src/App.tsx +++ b/crates/lanspread-tauri-deno-ts/src/App.tsx @@ -44,6 +44,7 @@ const App = () => { const [searchTerm, setSearchTerm] = useState(''); const [gameDir, setGameDir] = useState(''); const [currentFilter, setCurrentFilter] = useState('available'); + const [totalPeerCount, setTotalPeerCount] = useState(0); const checkingPeersTimeouts = useRef>>({}); const getFilteredGames = (games: Game[], filter: GameFilter): Game[] => { @@ -154,6 +155,17 @@ const App = () => { setupDownloadFailedListener(); setupNoPeersListener(); + + const setupPeerCountListener = async () => { + const unlisten = await listen('peer-count-updated', (event) => { + const count = event.payload as number; + console.log(`🗲 peer-count-updated ${count} event received`); + setTotalPeerCount(count); + }); + return unlisten; + }; + + setupPeerCountListener(); }, [gameDir]); useEffect(() => { @@ -427,6 +439,13 @@ const App = () => { return (
+
+ {totalPeerCount > 0 && ( + + 👥 {totalPeerCount} + + )} +

SoftLAN Launcher

{gameDir ? (