Added name of current logged-in account to the sidebar.

RoomView now uses #[component]
This commit is contained in:
Werner Kroneman 2023-12-10 21:02:31 +01:00
parent 05ed0316e3
commit d11daee5df
5 changed files with 46 additions and 45 deletions

View File

@ -29,7 +29,7 @@ use std::str::FromStr;
pub enum LoginStatus { pub enum LoginStatus {
LoggedOut, LoggedOut,
LoggingIn, LoggingIn,
LoggedIn, LoggedIn(BareJid),
Error(String), Error(String),
} }
@ -180,7 +180,7 @@ pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> {
button { button {
disabled: match cx.props.login_state { disabled: match cx.props.login_state {
LoginStatus::LoggedIn => true, LoginStatus::LoggedIn(_) => true,
LoginStatus::LoggedOut => false, LoginStatus::LoggedOut => false,
LoginStatus::LoggingIn => true, LoginStatus::LoggingIn => true,
LoginStatus::Error(_) => false, LoginStatus::Error(_) => false,
@ -197,7 +197,7 @@ pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> {
match cx.props.login_state { match cx.props.login_state {
LoginStatus::LoggedOut => "Log in", LoginStatus::LoggedOut => "Log in",
LoginStatus::LoggingIn => "Logging in...", LoginStatus::LoggingIn => "Logging in...",
LoginStatus::LoggedIn => "Logged in", LoginStatus::LoggedIn(_) => "Logged in",
LoginStatus::Error(_) => "Log in", LoginStatus::Error(_) => "Log in",
} }
} }

View File

@ -75,37 +75,14 @@ pub fn App(cx: Scope) -> Element {
render! { render! {
// If not logged in, show a login screen. // If not logged in, show a login screen.
if connection_status.get() != &LoginStatus::LoggedIn { if let LoginStatus::LoggedIn(user) = connection_status.get() {
rsx! {
LoginScreen {
cached_username: config.read().stored_username.clone().map(|x| x.to_string()).unwrap_or("".to_string()),
cached_nick: config.read().stored_default_nick.clone().unwrap_or("".to_string()),
login_state: connection_status.current().as_ref().clone(),
on_login_attempt: move |x: LoginAttempt| {
// Validate the login attempt.
match validate_login_attempt(x) {
Ok(x) => {
config.with_mut(|c| {
store_login_details(x.username.clone(), x.default_nick.clone(), &x.password, c);
});
coroutine.send(NetworkCommand::TryLogin { credentials: x });
},
Err(e) => {
error!("Invalid login attempt: {}", e);
}
}
},
}
}
} else {
// We're logged in; show a sidebar and a room view. // We're logged in; show a sidebar and a room view.
rsx!{ rsx!{
// Sidebar. // Sidebar.
SideBar { SideBar {
current_user: user.clone(),
rooms: messages.read().keys().cloned().collect(), rooms: messages.read().keys().cloned().collect(),
on_room_picked: move |x: BareJid| { on_room_picked: move |x: BareJid| {
current_room.set(Some(x.clone())); current_room.set(Some(x.clone()));
@ -144,6 +121,28 @@ pub fn App(cx: Scope) -> Element {
} }
} }
} }
} else {
rsx! {
LoginScreen {
cached_username: config.read().stored_username.clone().map(|x| x.to_string()).unwrap_or("".to_string()),
cached_nick: config.read().stored_default_nick.clone().unwrap_or("".to_string()),
login_state: connection_status.current().as_ref().clone(),
on_login_attempt: move |x: LoginAttempt| {
// Validate the login attempt.
match validate_login_attempt(x) {
Ok(x) => {
config.with_mut(|c| {
store_login_details(x.username.clone(), x.default_nick.clone(), &x.password, c);
});
coroutine.send(NetworkCommand::TryLogin { credentials: x });
},
Err(e) => {
error!("Invalid login attempt: {}", e);
}
}
},
}
}
} }
} }
} }

View File

@ -22,20 +22,12 @@ use dioxus::hooks::use_state;
use dioxus::prelude::*; use dioxus::prelude::*;
use jid::BareJid; use jid::BareJid;
/// The props for the room view widget, including: /// A widget that shows a room, including a list of messages and a widget to send new messages.
/// * The room identifier (BareJid) to display. #[component]
/// * The list of messages to display. pub fn RoomView<'a>(cx: Scope<'a>,
/// * The event handler for when the user sends a message.
#[derive(Props)]
pub struct RoomViewProps<'a> {
room: BareJid, room: BareJid,
messages: Vec<Message>, messages: Vec<Message>,
on_message_sent: EventHandler<'a, String>, on_message_sent: EventHandler<'a, String>) -> Element<'a> {
}
/// A widget that shows a room, including a list of messages and a widget to send new messages.
pub fn RoomView<'a>(cx: Scope<'a, RoomViewProps>) -> Element<'a> {
let _message = use_state(cx, || "".to_owned());
render! { render! {
div { div {

View File

@ -25,6 +25,7 @@ use jid::BareJid;
/// A widget that combines the RoomList, RoomJoinWidget, and current user info into a sidebar. /// A widget that combines the RoomList, RoomJoinWidget, and current user info into a sidebar.
#[component] #[component]
pub fn SideBar<'a>(cx: Scope<'a, SideBarProps>, pub fn SideBar<'a>(cx: Scope<'a, SideBarProps>,
current_user: BareJid,
rooms: Vec<BareJid>, rooms: Vec<BareJid>,
on_room_picked: EventHandler<'a, BareJid>, on_room_picked: EventHandler<'a, BareJid>,
on_room_left: EventHandler<'a, BareJid>, on_room_left: EventHandler<'a, BareJid>,
@ -41,7 +42,8 @@ pub fn SideBar<'a>(cx: Scope<'a, SideBarProps>,
// The name of the current user (TODO: make this actually reflect the current user). // The name of the current user (TODO: make this actually reflect the current user).
div { div {
border_bottom: "1px solid lightgray", border_bottom: "1px solid lightgray",
"Mizah"
"{current_user}",
button { button {
onclick: move |_| on_logout.call(()), onclick: move |_| on_logout.call(()),

View File

@ -145,7 +145,9 @@ pub fn xmpp_mainloop<'a>(
panic!("Already logged in."); panic!("Already logged in.");
}, },
NetworkCommand::Logout => { NetworkCommand::Logout => {
agent.disconnect().await; if let Err(e) = agent.disconnect().await {
error!("Error while disconnecting: {}", e);
}
break; break;
} }
} }
@ -207,15 +209,21 @@ pub async fn run_xmpp_toplevel(
if let Some(NetworkCommand::TryLogin { credentials }) = cmd { if let Some(NetworkCommand::TryLogin { credentials }) = cmd {
println!("Received credentials: {:?}", credentials); println!("Received credentials: {:?}", credentials);
let LoginCredentials {
username,
default_nick,
password,
} = credentials;
connection_status.set(LoginStatus::LoggingIn); connection_status.set(LoginStatus::LoggingIn);
let mut agent = ClientBuilder::new(credentials.username, &credentials.password.0) let mut agent = ClientBuilder::new(username.clone(), &password.0)
.set_client(ClientType::Pc, "dergchat") .set_client(ClientType::Pc, "dergchat")
.build(); .build();
match await_online(&mut agent).await { match await_online(&mut agent).await {
Ok(_) => { Ok(_) => {
connection_status.set(LoginStatus::LoggedIn); connection_status.set(LoginStatus::LoggedIn(username.clone()));
info!("Connected"); info!("Connected");
xmpp_mainloop(&mut agent, &mut messages, &mut commands).await; xmpp_mainloop(&mut agent, &mut messages, &mut commands).await;