mirror of
https://gitea.mizah.xyz/mizah/dergchat
synced 2024-11-21 14:05:00 -05:00
Cleaned up and documented the login screen code.
This commit is contained in:
parent
640db8e166
commit
d7292505a5
@ -28,6 +28,10 @@ pub enum LoginStatus {
|
|||||||
Error(String),
|
Error(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A struct that represents a login attempt, containing a username, a default nick, and a password.
|
||||||
|
/// None are validated in any way.
|
||||||
|
///
|
||||||
|
/// Warning: this struct contains the user's password; keep it in memory only as short as possible.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct LoginAttempt {
|
pub struct LoginAttempt {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
@ -45,6 +49,11 @@ impl Debug for LoginAttempt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The props for the login screen widget, including:
|
||||||
|
/// * The xmpp address to pre-fill in the username field.
|
||||||
|
/// * The default nick to pre-fill in the default nick field.
|
||||||
|
/// * The current login state, which will change as the user attempts to log in.
|
||||||
|
/// * The event handler for when the user clicks the login button.
|
||||||
#[derive(Props)]
|
#[derive(Props)]
|
||||||
pub struct LoginScreenProps<'a> {
|
pub struct LoginScreenProps<'a> {
|
||||||
cached_username: String,
|
cached_username: String,
|
||||||
@ -53,10 +62,32 @@ pub struct LoginScreenProps<'a> {
|
|||||||
on_login_attempt: EventHandler<'a, LoginAttempt>,
|
on_login_attempt: EventHandler<'a, LoginAttempt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A login screen widget.
|
||||||
|
///
|
||||||
|
/// This widget is used to query the user for their login credentials, namely:
|
||||||
|
/// * Username (XMPP address/Jid)
|
||||||
|
/// * Default nick
|
||||||
|
/// * Password
|
||||||
|
///
|
||||||
|
/// The default nick and username may be pre-filled from the cache.
|
||||||
|
///
|
||||||
|
/// The widget itself only contains the UI, and does not know how to validate the credentials
|
||||||
|
/// or log the user in; the parent context is responsible for that.
|
||||||
|
///
|
||||||
|
/// As a small UX improvement, the widget will automatically fill in the default nick
|
||||||
|
/// based on the username, if the user has not changed the default nick.
|
||||||
pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> {
|
pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> {
|
||||||
|
|
||||||
|
// The username.
|
||||||
let username = use_state(cx, || cx.props.cached_username.clone());
|
let username = use_state(cx, || cx.props.cached_username.clone());
|
||||||
|
|
||||||
|
// The default nick.
|
||||||
let default_nick = use_state(cx, || cx.props.cached_nick.clone());
|
let default_nick = use_state(cx, || cx.props.cached_nick.clone());
|
||||||
|
|
||||||
|
// The password.
|
||||||
let password = use_state(cx, || "".to_string());
|
let password = use_state(cx, || "".to_string());
|
||||||
|
|
||||||
|
// Track whether the default nick was directly changed by the user.
|
||||||
let default_nick_was_changed = use_state(cx, || false);
|
let default_nick_was_changed = use_state(cx, || false);
|
||||||
|
|
||||||
render! {
|
render! {
|
||||||
@ -64,13 +95,17 @@ pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> {
|
|||||||
div {
|
div {
|
||||||
class: "login-form",
|
class: "login-form",
|
||||||
|
|
||||||
|
// The username input.
|
||||||
input {
|
input {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
placeholder: "Username",
|
placeholder: "XMPP Address",
|
||||||
value: "{username}",
|
value: "{username}",
|
||||||
oninput: move |x| {
|
oninput: move |x| {
|
||||||
|
|
||||||
|
// Set the username state variable.
|
||||||
username.set(x.value.clone());
|
username.set(x.value.clone());
|
||||||
|
|
||||||
|
// If the default nick was not changed by the user, set it to the part before the @.
|
||||||
if !default_nick_was_changed.get() {
|
if !default_nick_was_changed.get() {
|
||||||
if let Some(before_at) = x.value.split('@').next() {
|
if let Some(before_at) = x.value.split('@').next() {
|
||||||
default_nick.set(before_at.to_string());
|
default_nick.set(before_at.to_string());
|
||||||
@ -79,16 +114,21 @@ pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The default nick input.
|
||||||
input {
|
input {
|
||||||
placeholder: "Default nick",
|
placeholder: "Default nick",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
value: "{default_nick}",
|
value: "{default_nick}",
|
||||||
oninput: move |x| {
|
oninput: move |x| {
|
||||||
|
// Store the nick in the state variable.
|
||||||
default_nick.set(x.value.clone());
|
default_nick.set(x.value.clone());
|
||||||
|
|
||||||
|
// Mark the nick as changed, so that it won't be overwritten by the username.
|
||||||
default_nick_was_changed.set(true);
|
default_nick_was_changed.set(true);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The password input.
|
||||||
input {
|
input {
|
||||||
placeholder: "Password",
|
placeholder: "Password",
|
||||||
"type": "password",
|
"type": "password",
|
||||||
@ -109,11 +149,11 @@ pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> {
|
|||||||
rsx! {
|
rsx! {
|
||||||
button {
|
button {
|
||||||
|
|
||||||
class: match cx.props.login_state {
|
disabled: match cx.props.login_state {
|
||||||
LoginStatus::LoggedOut => "login-button logged-out",
|
LoginStatus::LoggedIn => true,
|
||||||
LoginStatus::LoggingIn => "login-button logging-in",
|
LoginStatus::LoggedOut => false,
|
||||||
LoginStatus::LoggedIn => "login-button logged-in",
|
LoginStatus::LoggingIn => true,
|
||||||
LoginStatus::Error(_) => "error",
|
LoginStatus::Error(_) => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
onclick: move |_| {
|
onclick: move |_| {
|
||||||
@ -124,7 +164,12 @@ pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
"Login"
|
match cx.props.login_state {
|
||||||
|
LoginStatus::LoggedOut => "Log in",
|
||||||
|
LoginStatus::LoggingIn => "Logging in...",
|
||||||
|
LoginStatus::LoggedIn => "Logged in",
|
||||||
|
LoginStatus::Error(_) => "Log in",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user