From 61edd8cd24e28aea8269e552cc0caf3d7d5c8334 Mon Sep 17 00:00:00 2001 From: Tiago Batista Cardoso Date: Sun, 25 Jan 2026 01:31:15 +0100 Subject: [PATCH] [feature] server selection --- client-gui/src/gui_app.rs | 165 ++++++++++++++++++++++++++++++++------ 1 file changed, 139 insertions(+), 26 deletions(-) diff --git a/client-gui/src/gui_app.rs b/client-gui/src/gui_app.rs index ae916af..1aafbf4 100644 --- a/client-gui/src/gui_app.rs +++ b/client-gui/src/gui_app.rs @@ -46,8 +46,6 @@ pub struct P2PClientApp { server_status: ServerStatus, - show_network_popup: bool, // gérer selon besoin - error_message: Option<(String, String)>, // Some(message) -> afficher, None -> rien success_message: Option<(String, String)>, // Some(message) -> afficher, None -> rien active_server: String, @@ -55,6 +53,8 @@ pub struct P2PClientApp { current_downloading_file_map: MerkleTree, remaining_chunks: HashSet<[u8; 32]>, root_downloading_file: String, + show_network_window: bool, + show_choose_server_window: bool, } impl P2PClientApp { @@ -80,7 +80,6 @@ impl P2PClientApp { loaded_fs, active_peer: None, server_status: ServerStatus::NotConnected, - show_network_popup: false, error_message: None, success_message: None, connect_name_input: "bob".to_string(), @@ -89,6 +88,8 @@ impl P2PClientApp { current_downloading_file_map: current_downloading_file_map, root_downloading_file: "".to_string(), remaining_chunks: HashSet::new(), + show_network_window: false, + show_choose_server_window: false, } } pub fn show_error(&mut self, msg: impl Into, peer_username: impl Into) { @@ -241,6 +242,7 @@ impl eframe::App for P2PClientApp { NetworkEvent::Connected(ip) => { self.server_status = ServerStatus::Connected; self.connected_address = ip.clone(); + self.show_choose_server_window = true; let _ = self.network_cmd_tx.send(NetworkCommand::FetchPeerList( self.connected_address.clone(), )); @@ -341,6 +343,68 @@ impl eframe::App for P2PClientApp { } } + if self.show_choose_server_window { + egui::Window::new("Choose the server") + .resizable(false) + .show(ctx, |ui| { + ScrollArea::vertical() + .auto_shrink([false; 2]) + .show(ui, |ui| { + ui.style_mut().visuals.widgets.inactive.bg_fill = + ui.style().visuals.widgets.inactive.bg_fill; // no-op to get mutable borrow + if self.known_peers.is_empty() { + ui.add_space(10.0); + ui.label("No active peers."); + } else { + for peer in &self.known_peers { + let is_active = + self.active_peer.as_ref().map_or(false, |id| id == &peer.0); // if peer.id == self.active_peer_id + + // place spinner to the right of the label + ui.horizontal(|ui| { + // Use same width for the label widget as the selectable we already created: + // Recreate selectable inline so both label and spinner share the same row. + let resp = if &self.active_server == &peer.0 { + // draw with frame inline + let frame = Frame { + fill: Color32::DARK_BLUE, + stroke: Stroke::default(), + corner_radius: CornerRadius::from(0.5), + ..Default::default() + }; + frame + .show(ui, |ui| { + ui.selectable_label( + is_active, + format!("{}", peer.0), + ) + }) + .inner + } else { + ui.selectable_label(is_active, format!("{}", peer.0)) + }; + + ui.add_space(4.0); // small gap + + // use resp (click handling etc.) + if resp.clicked() { + self.active_server = peer.0.to_string(); + let res = self.network_cmd_tx.send( + NetworkCommand::ServerHandshake( + peer.0.to_string(), + self.connected_address.clone(), + ), + ); + ui.close(); + self.show_choose_server_window = false; + } + }); + } + } + }); + }); + } + // 2. Menu Bar TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::MenuBar::new().ui(ui, |ui| { @@ -355,7 +419,55 @@ impl eframe::App for P2PClientApp { } }); - ui.menu_button("Network", |ui| { + //ui.menu_button("Network", |ui| { + // match self.server_status { + // ServerStatus::Connected | ServerStatus::ConnectedHandshake => { + // let desired = egui::vec2(300.0, 0.0); // width 300, auto-height if 0 + // ui.set_min_size(desired); + // ui.vertical(|ui| { + // if ui.button("Disconnect").clicked() { + // println!("Disconnecting..."); + // let _ = self.network_cmd_tx.send(NetworkCommand::Disconnect()); + // self.server_status = ServerStatus::NotConnected; + // self.remaining = std::time::Duration::from_secs(0); + // self.timer_started = false; + // ui.close(); + // } + // }); + // } + // ServerStatus::NotConnected => { + // let desired = egui::vec2(0.0, 0.0); // width 300, auto-height if 0 + // ui.set_min_size(desired); + // ui.vertical(|ui| { + // ui.horizontal(|ui| { + // ui.label("Server IP:"); + // ui.text_edit_singleline(&mut self.connect_address_input); + // }); + // ui.horizontal(|ui| { + // ui.label("Name:"); + // ui.text_edit_singleline(&mut self.connect_name_input); + // }); + // if ui.button("Connect").clicked() { + // let addr = self.connect_address_input.clone(); + // let name = self.connect_name_input.clone(); + // let _ = self + // .network_cmd_tx + // .send(NetworkCommand::ConnectToServerPut(addr, name)); + // self.server_status = ServerStatus::Loading; + // ui.close(); + // } + // }); + // } + // _ => {} + // } + //}); + // open trigger (e.g., in a menu bar) + + if ui.button("Network").clicked() { + self.show_network_window = true; + } + + if self.show_network_window { match self.server_status { ServerStatus::Connected | ServerStatus::ConnectedHandshake => { let desired = egui::vec2(300.0, 0.0); // width 300, auto-height if 0 @@ -367,36 +479,37 @@ impl eframe::App for P2PClientApp { self.server_status = ServerStatus::NotConnected; self.remaining = std::time::Duration::from_secs(0); self.timer_started = false; - ui.close(); + self.show_network_window = false; } }); } ServerStatus::NotConnected => { - let desired = egui::vec2(0.0, 0.0); // width 300, auto-height if 0 - ui.set_min_size(desired); - ui.vertical(|ui| { - ui.horizontal(|ui| { - ui.label("Server IP:"); - ui.text_edit_singleline(&mut self.connect_address_input); + egui::Window::new("Network") + .resizable(false) + .show(ctx, |ui| { + ui.horizontal(|ui| { + ui.label("Server IP:"); + ui.text_edit_singleline(&mut self.connect_address_input); + }); + ui.horizontal(|ui| { + ui.label("Name:"); + ui.text_edit_singleline(&mut self.connect_name_input); + }); + if ui.button("Connect").clicked() { + let addr = self.connect_address_input.clone(); + let name = self.connect_name_input.clone(); + let _ = self + .network_cmd_tx + .send(NetworkCommand::ConnectToServerPut(addr, name)); + self.server_status = ServerStatus::Loading; + ui.close(); + self.show_network_window = false; + } }); - ui.horizontal(|ui| { - ui.label("Name:"); - ui.text_edit_singleline(&mut self.connect_name_input); - }); - if ui.button("Connect").clicked() { - let addr = self.connect_address_input.clone(); - let name = self.connect_name_input.clone(); - let _ = self - .network_cmd_tx - .send(NetworkCommand::ConnectToServerPut(addr, name)); - self.server_status = ServerStatus::Loading; - ui.close(); - } - }); } _ => {} } - }); + } }); });