This commit is contained in:
Tiago Batista Cardoso
2025-11-30 14:49:16 +01:00
parent 85e78447a7
commit 721d52a028
5 changed files with 111 additions and 45 deletions

View File

@@ -4,11 +4,17 @@ use client_network::{
};
use crossbeam_channel::{Receiver, Sender};
use egui::{
Align, Button, CentralPanel, CollapsingHeader, Context, Layout, ScrollArea, SidePanel,
TopBottomPanel, Ui, ViewportCommand,
Align, Align2, Button, CentralPanel, CollapsingHeader, Context, Id, LayerId, Layout, Order,
Popup, ScrollArea, SidePanel, TopBottomPanel, Ui, ViewportCommand,
};
use std::collections::HashMap;
enum ServerStatus {
Loading,
NotConnected,
Connected,
}
// --- Main Application Struct ---
pub struct P2PClientApp {
// Communication channels
@@ -25,6 +31,8 @@ pub struct P2PClientApp {
// Current peer tree displayed
active_peer: Option<String>,
server_status: ServerStatus,
}
impl P2PClientApp {
@@ -43,6 +51,7 @@ impl P2PClientApp {
connect_address_input: "127.0.0.1:8080".to_string(),
loaded_fs,
active_peer: None,
server_status: ServerStatus::Loading,
}
}
}
@@ -89,8 +98,12 @@ impl eframe::App for P2PClientApp {
// root_hash,
// ));
}
// Handle other events like Disconnect, Error, etc.
_ => {}
NetworkEvent::Connected() => {
self.server_status = ServerStatus::Connected;
}
NetworkEvent::Disconnected() => todo!(),
NetworkEvent::Error() => todo!(),
NetworkEvent::DataReceived(_, merkle_node) => todo!(),
}
}
@@ -98,6 +111,10 @@ impl eframe::App for P2PClientApp {
TopBottomPanel::top("top_panel").show(ctx, |ui| {
egui::MenuBar::new().ui(ui, |ui| {
ui.menu_button("File", |ui| {
if ui.button("Settings").clicked() {
//show settings
}
if ui.button("Quit").clicked() {
// Use ViewportCommand to request a close
ctx.send_viewport_cmd(ViewportCommand::Close);
@@ -106,11 +123,14 @@ impl eframe::App for P2PClientApp {
ui.menu_button("Network", |ui| {
ui.horizontal(|ui| {
ui.label("Connect to:");
ui.label("Server IP:");
ui.text_edit_singleline(&mut self.connect_address_input);
if ui.button("Connect").clicked() {
let addr = self.connect_address_input.clone();
let _ = self.network_cmd_tx.send(NetworkCommand::ConnectPeer(addr));
let _ = self
.network_cmd_tx
.send(NetworkCommand::ConnectToServer(addr));
self.server_status = ServerStatus::Loading;
ui.close();
}
});
@@ -118,12 +138,44 @@ impl eframe::App for P2PClientApp {
});
});
// 3. Right-sided Panel (Known Peers)
TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| {
ui.horizontal(|ui| {
match self.server_status {
ServerStatus::Loading => {
ui.spinner();
}
ServerStatus::Connected => {
ui.label("📡");
}
ServerStatus::NotConnected => {
ui.label("No connection..");
}
}
ui.add_space(ui.available_width() - 30.0);
ui.label("30:00");
});
});
SidePanel::right("right_panel")
.resizable(true)
.resizable(false)
.min_width(180.0)
.show(ctx, |ui| {
ui.heading("🌐 Known Peers");
ui.horizontal(|ui| {
ui.heading("🌐 Known Peers");
ui.add_space(20.0);
if ui.button("🔄").clicked() {
let res = self.network_cmd_tx.send(NetworkCommand::FetchPeerList(
self.connect_address_input.clone(),
));
if let Some(error) = res.err() {
println!(
"[GUI] Error while sending crossbeam message to Network: {}",
error.to_string()
);
}
}
});
ui.separator();
ScrollArea::vertical().show(ui, |ui| {
if self.known_peers.is_empty() {
@@ -157,16 +209,14 @@ impl eframe::App for P2PClientApp {
});
});
// 4. Central Panel (Filesystem Tree)
let heading = {
if let Some(peer) = &self.active_peer {
format!("📂 {}'s tree", peer)
} else {
"📂 p2p-merkel client".to_string()
}
};
CentralPanel::default().show(ctx, |ui| {
ui.heading(heading);
ui.heading({
if let Some(peer) = &self.active_peer {
format!("📂 {}'s tree", peer)
} else {
"📂 p2p-merkel client".to_string()
}
});
ui.separator();
if let Some(active_peer) = &self.active_peer {
@@ -284,4 +334,3 @@ impl P2PClientApp {
}
}
}

View File

@@ -1,5 +1,5 @@
use client_network::{start_p2p_executor, NetworkCommand, NetworkEvent};
use crate::gui_app::P2PClientApp;
use client_network::{NetworkCommand, NetworkEvent, start_p2p_executor};
mod gui_app;
@@ -16,8 +16,9 @@ async fn main() -> eframe::Result<()> {
// 3. Configure and Run the Eframe/Egui GUI
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_inner_size([1000.0, 700.0])
.with_inner_size([700.0, 500.0])
.with_min_inner_size([700.0, 500.0])
.with_resizable(false)
.with_icon(
eframe::icon_data::from_png_bytes(include_bytes!("../assets/icon.png"))
.expect("Failed to load icon"),
@@ -33,4 +34,4 @@ async fn main() -> eframe::Result<()> {
Ok(Box::new(app))
}),
)
}
}