Skip to content
This repository has been archived by the owner on Aug 24, 2024. It is now read-only.

Commit

Permalink
Login Smart Input (#47)
Browse files Browse the repository at this point in the history
* fix: identify base_url

* feat: get homeserver from URL

* chore: minor nitpick
  • Loading branch information
b-avb authored Feb 25, 2024
1 parent a54e0d0 commit a6c4807
Show file tree
Hide file tree
Showing 21 changed files with 331 additions and 176 deletions.
6 changes: 0 additions & 6 deletions .vscode/settings.json

This file was deleted.

2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ log = "0.4.17"
matrix-sdk = { version = "0.6.2", default-features = false, features = ["js", "native-tls", "e2e-encryption", "indexeddb", "experimental-timeline"] }
tokio = "1.27.0"
url = "2.3.1"
web-sys = {version = "0.3.61", features = ["Document", "Element", "HtmlElement", "HtmlBodyElement", "Node", "NodeList", "Window", "console", "CssStyleDeclaration"]}
web-sys = {version = "0.3.61", features = ["Document", "Element", "HtmlElement", "HtmlBodyElement", "Node", "NodeList", "Window", "console", "CssStyleDeclaration", "Location"]}
time = "0.3.22"
anyhow = "1"
serde = { version = "1.0.96", features = ["derive"]}
serde = { version = "1.0.96", features = ["derive"] }
mime = "0.3.17"
js-sys = "0.3.64"
wasm-bindgen = "0.2.55"
Expand All @@ -31,3 +31,5 @@ infer = "0.15.0"
ruma = { version = "0.7.4", features = ["unstable-sanitize", "unstable-msc2677", "unstable-msc3440", "client"] }
uuid = "0.8"
unic-langid = "0.9.1"
reqwest = "0.11"
http = "0.2"
16 changes: 11 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -224,26 +224,32 @@
<section class="login-form">
<div class="login-form__avatar">
<div class="login-form__avatar__content">
🛰️
👋
</div>
</div>
<h2 class="login-form__title">
Ingresa un servidor
Completa tu información
</h2>
<p class="login-form__description">
Únete a un servidor, por defecto puedes utilizar https://matrix.org
Crea un mundo, construye tu futuro
</p>

<div class="login-form__form__head">
<section class="input__wrapper">
<div class="input-wrapper">
<input type="text" class="input" placeholder="https://matrix.org">
<input type="text" class="input" placeholder="@user:matrix.org">
</div>
</section>

<section class="input__wrapper">
<div class="input-wrapper">
<input type="text" class="input" placeholder="Contrasena">
</div>
</section>
</div>

<div class="login-form__cta--filled">
<button class="button button--primary">Confirmar servidor</button>
<button class="button button--primary">Desbloquear</button>
</div>

<div class="login-form__cta--action">
Expand Down
11 changes: 9 additions & 2 deletions public/login.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@
padding: 0 8px;
}

.button:active:not(:disabled) {
opacity: 0.7;
.button--tertiary {
border: none;
color: var(--text-loud);
border-radius: 0;
padding: 0 8px;
}

.button--loading {
opacity: 0.8;
}


Expand Down
37 changes: 29 additions & 8 deletions src/components/atoms/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub struct ButtonProps<'a> {
#[props(default = false)]
disabled: bool,
on_click: EventHandler<'a, MouseEvent>,
#[props(!optional)]
status: Option<String>,
}

pub fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element<'a> {
Expand All @@ -27,12 +29,31 @@ pub fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element<'a> {
""
};

cx.render(rsx!(
button {
class: "button {variant} {disabled}",
disabled: cx.props.disabled,
onclick: move |event| cx.props.on_click.call(event),
"{cx.props.text}"
}
))
let loading = if cx.props.status.is_some() {
"button--loading"
} else {
""
};

match &cx.props.status {
Some(s) => {
render!(rsx!(
button {
class: "button {variant} {loading}",
disabled: true,
"{s}"
}
))
}
None => {
render!(rsx!(
button {
class: "button {variant} {disabled}",
disabled: cx.props.disabled,
onclick: move |event| cx.props.on_click.call(event),
"{cx.props.text}"
}
))
}
}
}
2 changes: 2 additions & 0 deletions src/components/molecules/attach_preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub fn AttachPreview<'a>(cx: Scope<'a, AttachPreviewProps<'a>>) -> Element<'a> {
Button {
text: "{key_attach_preview_cta_cancel}",
variant: &Variant::Secondary,
status: None,
on_click: on_handle_card
}
}
Expand Down Expand Up @@ -103,6 +104,7 @@ pub fn AttachPreview<'a>(cx: Scope<'a, AttachPreviewProps<'a>>) -> Element<'a> {
Button {
text: "{key_attach_preview_cta_cancel}",
variant: &Variant::Secondary,
status: None,
on_click: on_handle_card
}
}
Expand Down
1 change: 1 addition & 0 deletions src/components/molecules/input_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ pub fn InputMessage<'a>(cx: Scope<'a, InputMessageProps<'a>>) -> Element<'a> {
rsx!(
Button {
text: "{key_input_message_cta}",
status: None,
on_click: move |event| {
if let Some(l) = &cx.props.on_attach {
let attachment = Attachment {
Expand Down
7 changes: 5 additions & 2 deletions src/components/organisms/login_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub struct LoginFormProps<'a> {
#[props(default = false)]
clear_data: bool,
on_handle: EventHandler<'a, FormLoginEvent>,
#[props(!optional)]
status: Option<String>,
}

pub fn LoginForm<'a>(cx: Scope<'a, LoginFormProps<'a>>) -> Element<'a> {
Expand Down Expand Up @@ -53,7 +55,7 @@ pub fn LoginForm<'a>(cx: Scope<'a, LoginFormProps<'a>>) -> Element<'a> {
"{cx.props.description}"
}

div {
div {
class: "login-form__form__head",
&cx.props.body

Expand All @@ -71,12 +73,13 @@ pub fn LoginForm<'a>(cx: Scope<'a, LoginFormProps<'a>>) -> Element<'a> {
}
)
}
}
}

div {
class: "login-form__cta--filled",
Button {
text: "{cx.props.button_text}",
status: cx.props.status.clone(),
on_click: move |_| {
cx.props.on_handle.call(FormLoginEvent::FilledForm)
}
Expand Down
53 changes: 47 additions & 6 deletions src/hooks/use_auth.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use dioxus::prelude::*;
use gloo::storage::{errors::StorageError, LocalStorage};
use matrix_sdk::Client;
use ruma::api::IncomingResponse;
use serde::{Deserialize, Serialize};
use url::Url;

use ruma::api::client::discovery::discover_homeserver::Response as WellKnownResponse;

use crate::pages::login::LoggedIn;

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -13,6 +16,12 @@ pub enum AuthError {
ServerNotFound,
}

impl From<serde_json::Error> for AuthError {
fn from(_: serde_json::Error) -> Self {
AuthError::InvalidHomeserver
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheLogin {
pub server: String,
Expand Down Expand Up @@ -117,13 +126,31 @@ impl UseAuthState {

let server = server_parsed.map_err(|_| AuthError::InvalidHomeserver)?;

let request_url = format!("{}.well-known/matrix/client", server.to_string());

let res = reqwest::Client::new()
.get(&request_url)
.send()
.await
.map_err(|_| AuthError::InvalidHomeserver)?;

let body = res.text().await.map_err(|_| AuthError::InvalidHomeserver)?;

let well_response = WellKnownResponse::try_from_http_response(http::Response::new(body))
.map_err(|_| AuthError::InvalidHomeserver)?;

let url_base = Url::parse(&well_response.homeserver.base_url)
.map_err(|_| AuthError::InvalidHomeserver)?;

let result = Client::builder()
.homeserver_url(&server.as_str())
.homeserver_url(&url_base)
.build()
.await
.map(|_| server)
.map(|_| url_base)
.map_err(|_| AuthError::ServerNotFound);

log::info!("client result: {:?}", result);

match result {
Ok(server) => {
self.data.with_mut(|l| l.server(server));
Expand All @@ -138,7 +165,7 @@ impl UseAuthState {
}

pub fn set_username(&self, username: &str, parse: bool) {
let mut username_parse = username.to_owned();
let mut username_parse = username.trim().to_string();

if parse {
if !username_parse.starts_with("@") {
Expand All @@ -147,8 +174,9 @@ impl UseAuthState {

if let Some(server) = &self.data.read().server {
if let Some(domain) = server.domain() {
if !username_parse.ends_with(domain) {
username_parse = format!("{}:{}", username_parse, domain);
let domain_name = extract_domain_name(domain);
if !username_parse.ends_with(domain_name.as_str()) {
username_parse = format!("{}:{}", username_parse, domain_name);
}
}
}
Expand All @@ -161,7 +189,7 @@ impl UseAuthState {

pub fn set_password(&self, password: &str) {
self.data.with_mut(|l| {
l.password(password);
l.password(password.trim());
});
}

Expand Down Expand Up @@ -215,3 +243,16 @@ impl UseAuthState {
*self.logged_in.write() = LoggedIn(option);
}
}

fn extract_domain_name(host: &str) -> String {
let segs: Vec<&str> = host
.split('.')
.filter(|&s| !s.is_empty())
.rev()
.collect::<Vec<&str>>();

let suffix = segs[0];
let domain = segs[1];

format!("{}.{}", domain, suffix)
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub mod services {

pub mod utils {
pub mod get_element;
pub mod get_homeserver;
pub mod get_param;
pub mod i18n_get_key_value;
pub mod matrix;
pub mod nice_bytes;
Expand Down
9 changes: 8 additions & 1 deletion src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
"found": "Session found",
"restoring": "Restoring session"
}
},
"errors": {
"homeserver": {
"invalid_url": "Url isn't valid"
},
"restore": "Can't restore session"
}
},
"login": {
Expand Down Expand Up @@ -52,7 +58,8 @@
"invalid_url": "Error: Relative URL without base",
"unknown": "Error: Unknown error",
"invalid_username_password": "Error: Invalid username or password",
"not_found": "User not found"
"not_found": "User not found",
"invalid_server": "Invalid server"
},
"status": {
"loading": "We are verifying your data",
Expand Down
9 changes: 8 additions & 1 deletion src/locales/es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
"fount": "Sesión encontrada",
"restoring": "Restaurando sesión"
}
},
"errors": {
"homeserver": {
"invalid_url": "Url encontrada no es válida"
},
"restore": "No se ha podido restaurar la sesión"
}
},
"login": {
Expand Down Expand Up @@ -52,7 +58,8 @@
"invalid_url": "Error: URL relativa sin base",
"unknown": "Error: Error desconocido",
"invalid_username_password": "Error: Nombre de usuario o contraseña inválidos",
"not_found": "No se ha encontrado el usuario"
"not_found": "No se ha encontrado el usuario",
"invalid_server": "El servidor no es válido"
},
"status": {
"loading": "Estamos verificando tus datos",
Expand Down
Loading

0 comments on commit a6c4807

Please sign in to comment.