diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index 353c11d..304f8e3 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -118,6 +118,11 @@ pub fn App(cx: Scope) -> Element { on_join_room: move |x: BareJid| { coroutine.send(NetworkCommand::JoinRoom { room: x }); }, + on_logout: move |_| { + connection_status.set(LoginStatus::LoggedOut); + current_room.set(None); + coroutine.send(NetworkCommand::Logout); + }, } // The current room. diff --git a/src/widgets/sidebar.rs b/src/widgets/sidebar.rs index 414fa5a..241e4c7 100644 --- a/src/widgets/sidebar.rs +++ b/src/widgets/sidebar.rs @@ -18,19 +18,19 @@ use crate::widgets::room_join_widget::RoomJoinWidget; use crate::widgets::room_list::RoomList; use dioxus::core::{Element, Scope}; use dioxus::core_macro::Props; +use dioxus::html::text; use dioxus::prelude::*; use jid::BareJid; -#[derive(Props)] -pub struct SideBarProps<'a> { - pub rooms: Vec, - pub on_room_picked: EventHandler<'a, BareJid>, - pub on_room_left: EventHandler<'a, BareJid>, - pub on_join_room: EventHandler<'a, BareJid>, -} - /// A widget that combines the RoomList, RoomJoinWidget, and current user info into a sidebar. -pub fn SideBar<'a>(cx: Scope<'a, SideBarProps>) -> Element<'a> { +#[component] +pub fn SideBar<'a>(cx: Scope<'a, SideBarProps>, + rooms: Vec, + on_room_picked: EventHandler<'a, BareJid>, + on_room_left: EventHandler<'a, BareJid>, + on_join_room: EventHandler<'a, BareJid>, + on_logout: EventHandler<'a, ()>) -> Element<'a> { + render! { div { padding: "5mm", @@ -42,6 +42,11 @@ pub fn SideBar<'a>(cx: Scope<'a, SideBarProps>) -> Element<'a> { div { border_bottom: "1px solid lightgray", "Mizah" + + button { + onclick: move |_| on_logout.call(()), + "Log out", + } } // The list of rooms. diff --git a/src/xmpp_interface.rs b/src/xmpp_interface.rs index 5bf0613..ced1b88 100644 --- a/src/xmpp_interface.rs +++ b/src/xmpp_interface.rs @@ -43,6 +43,8 @@ pub enum NetworkCommand { /// Send a message to a recipient. SendMessage { recipient: BareJid, message: String }, + + Logout, } async fn handle_event( @@ -142,6 +144,10 @@ pub fn xmpp_mainloop<'a>( NetworkCommand::TryLogin { credentials: _ } => { panic!("Already logged in."); }, + NetworkCommand::Logout => { + agent.disconnect().await; + break; + } } } else { info!("Command channel closed"); @@ -195,31 +201,32 @@ pub async fn run_xmpp_toplevel( mut commands: UnboundedReceiver, ) { // Await a login attempt: + loop { + let cmd = commands.next().await; - let cmd = commands.next().await; + if let Some(NetworkCommand::TryLogin { credentials }) = cmd { + println!("Received credentials: {:?}", credentials); - if let Some(NetworkCommand::TryLogin { credentials }) = cmd { - println!("Received credentials: {:?}", credentials); + connection_status.set(LoginStatus::LoggingIn); - connection_status.set(LoginStatus::LoggingIn); + let mut agent = ClientBuilder::new(credentials.username, &credentials.password.0) + .set_client(ClientType::Pc, "dergchat") + .build(); - let mut agent = ClientBuilder::new(credentials.username, &credentials.password.0) - .set_client(ClientType::Pc, "dergchat") - .build(); + match await_online(&mut agent).await { + Ok(_) => { + connection_status.set(LoginStatus::LoggedIn); + info!("Connected"); - match await_online(&mut agent).await { - Ok(_) => { - connection_status.set(LoginStatus::LoggedIn); - info!("Connected"); - - xmpp_mainloop(&mut agent, &mut messages, &mut commands).await; - } - Err(e) => { - error!("Failed to connect: {}", e); - connection_status.set(LoginStatus::Error("Failed to connect".to_string())); + xmpp_mainloop(&mut agent, &mut messages, &mut commands).await; + } + Err(e) => { + error!("Failed to connect: {}", e); + connection_status.set(LoginStatus::Error("Failed to connect".to_string())); + } } + } else { + panic!("Expected TryLogin command"); } - } else { - panic!("Expected TryLogin command"); } }