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

View File

@ -75,37 +75,14 @@ pub fn App(cx: Scope) -> Element {
render! {
// If not logged in, show a login screen.
if connection_status.get() != &LoginStatus::LoggedIn {
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 {
if let LoginStatus::LoggedIn(user) = connection_status.get() {
// We're logged in; show a sidebar and a room view.
rsx!{
// Sidebar.
SideBar {
current_user: user.clone(),
rooms: messages.read().keys().cloned().collect(),
on_room_picked: move |x: BareJid| {
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 jid::BareJid;
/// The props for the room view widget, including:
/// * The room identifier (BareJid) to display.
/// * The list of messages to display.
/// * The event handler for when the user sends a message.
#[derive(Props)]
pub struct RoomViewProps<'a> {
room: BareJid,
messages: Vec<Message>,
on_message_sent: EventHandler<'a, String>,
}
/// 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());
#[component]
pub fn RoomView<'a>(cx: Scope<'a>,
room: BareJid,
messages: Vec<Message>,
on_message_sent: EventHandler<'a, String>) -> Element<'a> {
render! {
div {

View File

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

View File

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