use std::str::FromStr; use std::sync::Arc; use dioxus::prelude::*; use dioxus_std::utils::rw::UseRw; use crate::base::{AppSettings, Store}; use crate::components::avatar_selector::AvatarSelector; use crate::components::header::Header; use crate::matrix_client::{LoginStyle, MatrixClient}; turf::style_sheet!("src/components/login.scss"); static EMPTY_PLACEHOLDER: &str = "Tmp placeholder"; #[inline_props] pub fn Login<'a>(cx: Scope, rw_store: &'a UseRw) -> Element { let app_context = use_shared_state::(cx).unwrap(); let invalid_login = use_state(cx, || false); let login = use_ref(cx, || Login::new()); let arc_store = Arc::new(rw_store.to_owned().clone()); let password_class = if **invalid_login { ClassName::INVALID_INPUT } else { "" }; let run_matrix_client = move |_| { cx.spawn({ to_owned![app_context, invalid_login, login, arc_store]; let login_ref = login.read(); let homeserver_url = login_ref.homeserver_url.clone().unwrap(); let username = login_ref.email.clone().unwrap(); let password = login_ref.password.clone().unwrap(); async move { let requester = MatrixClient::spawn(homeserver_url, arc_store.clone()).await; requester.init(); match requester.login(LoginStyle::Password(username, password)) { Ok(_) => { println!("successfully logged"); } Err(err) => { println!("Error during login: {err}"); invalid_login.modify(|_| true); } } app_context.write().requester = Some(Arc::new(requester)); } }); }; let login_ref = login.read(); let placeholder = EMPTY_PLACEHOLDER.to_string(); let homeserver_url_value = login_ref.homeserver_url.as_ref().unwrap_or(&placeholder); let email_value = login_ref.email.as_ref().unwrap_or(&placeholder); let password_value = login_ref.password.as_ref().unwrap_or(&placeholder); cx.render(rsx! { style { STYLE_SHEET }, div { class: ClassName::ROOT, div { class: ClassName::HEADER, Header {}, }, div { class: ClassName::BODY, div { class: ClassName::AVATAR_SELECTOR, AvatarSelector {}, }, p { "Matrix homeserver:" }, input { id: "input-homeserver-url", r#type: "text", name: "homeserver URL", value: "{homeserver_url_value}", oninput: move |evt| login.write().homeserver_url = Some(evt.value.clone()), }, p { "E-mail address:" }, input { id: "login-input-email", r#type: "text", name: "email", value: "{email_value}", oninput: move |evt| login.write().email = Some(evt.value.clone()), }, p { "Password:" }, input { class: "{password_class}", id: "login-input-password", r#type: "password", name: "Password", value: "{password_value}", oninput: move |evt| { login.write().password = Some(evt.value.clone()); invalid_login.set(false); }, }, div { class: ClassName::FOOTER_BUTTONS, input { class: ClassName::BUTTON, onclick: run_matrix_client, r#type: "submit", value: "sign in", }, }, }, }, }) } #[derive(Debug)] struct Login { homeserver_url: Option, email: Option, password: Option, } impl Login { fn new() -> Self { let login = Self { homeserver_url: None, email: None, password: None, }; login } }