diff --git a/Cargo.toml b/Cargo.toml index 4771c13..ad7851f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ dirs = "5.0.1" ctrlc-async = "3.2.2" tracing-subscriber = "0.3.17" dioxus-free-icons = { version = "0.6.0", features = ["material-design-icons-navigation", "ionicons"] } +thiserror = "1.0.44" [build] target = "x86_64-unknown-linux-gnu" diff --git a/src/app_settings.rs b/src/app_settings.rs index b0122ca..255bf7e 100644 --- a/src/app_settings.rs +++ b/src/app_settings.rs @@ -2,7 +2,7 @@ use std::cell::RefCell; use std::rc::Rc; use std::sync::{Arc, Mutex}; -use crate::matrix_client::MatrixClient; +use crate::base::Store; use crate::matrix_client::Requester; #[derive(Debug, Clone)] @@ -13,6 +13,7 @@ pub struct AppSettings { // pub matrix_client: Arc, //pub matrix_client: Arc>, pub requester: Option>, + pub store: Store, } impl AppSettings { @@ -21,6 +22,7 @@ impl AppSettings { // matrix_client: Arc::new(MatrixClient::new()), //matrix_client: Arc::new(Mutex::new(MatrixClient::new())), requester: None, + store: Store::new(), // matrix_client: Arc::new(Mutex::new(MatrixClient::new())), // matrix_client: Arc::new(MatrixClient::new()), // matrix_client: Rc::new(RefCell::new(MatrixClient::new())), diff --git a/src/base.rs b/src/base.rs index adcb1f6..125e2c8 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1,5 +1,13 @@ #[derive(Clone, Debug, Eq, PartialEq)] -pub enum Info {} +pub struct Store { + pub is_logged: bool, +} // pub type ProgramStore = Store; // pub type AsyncProgramStore = Arc>; + +impl Store { + pub fn new() -> Self { + Self { is_logged: false } + } +} diff --git a/src/components/login.rs b/src/components/login.rs index dd857dd..e26e774 100644 --- a/src/components/login.rs +++ b/src/components/login.rs @@ -10,10 +10,11 @@ use crate::matrix_client::{LoginStyle, MatrixClient}; pub fn Login(cx: Scope) -> Element { let app_context = use_shared_state::(cx).unwrap(); - println!("app_context={:?}", app_context.read()); let login = use_ref(cx, || Login::new()); + let invalid_login = use_state(cx, || false); + let empty_placeholder = String::from(""); let root = css!( @@ -71,21 +72,44 @@ pub fn Login(cx: Scope) -> Element { " ); + let invalid_input_css = css!( + " + border-color: red; + " + ); + let password_class = if **invalid_login { + invalid_input_css + } else { + "" + }; + let run_matrix_client = move |_| { - to_owned![app_context, login]; + cx.spawn({ + to_owned![app_context, invalid_login, login]; - let homeserver_url = login.read().homeserver_url.clone().unwrap(); - let username = login.read().email.clone().unwrap(); - let password = login.read().password.clone().unwrap(); + let homeserver_url = login.read().homeserver_url.clone().unwrap(); + let username = login.read().email.clone().unwrap(); + let password = login.read().password.clone().unwrap(); - cx.spawn(async { - let requester = MatrixClient::spawn(homeserver_url).await; + async move { + let mut context = app_context.write(); - requester.init(); - requester.login(LoginStyle::Password(username, password)); + let requester = MatrixClient::spawn(homeserver_url).await; + requester.init(); - let context = app_context; - context.write().requester = Some(Arc::new(requester)); + match requester.login(LoginStyle::Password(username, password)) { + Ok(_) => { + println!("successfully logged"); + context.store.is_logged = true; + } + Err(err) => { + println!("Error during login: {err}"); + invalid_login.modify(|_| true); + } + } + + context.requester = Some(Arc::new(requester)); + } }); }; @@ -130,11 +154,15 @@ pub fn Login(cx: Scope) -> Element { "Password:" }, input { + class: "{password_class}", id: "login-input-password", r#type: "password", name: "Password", value: "{login.read().password.as_ref().unwrap_or(&empty_placeholder)}", - oninput: move |evt| login.write().password = Some(evt.value.clone()), + oninput: move |evt| { + login.write().password = Some(evt.value.clone()); + invalid_login.set(false); + }, }, div { diff --git a/src/main.rs b/src/main.rs index bf29218..7937ed1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,8 @@ mod base; fn App(cx: Scope) -> Element { use_shared_state_provider(cx, || cx.props.clone()); + let app_context = use_shared_state::(cx).unwrap(); + global_css!( " body { @@ -70,11 +72,17 @@ fn App(cx: Scope) -> Element { // let dom = VirtualDom::new(ControlWindow); // window.new_window(dom, cx.props.clone()); - cx.render(rsx! { - AppStyle {}, - // Login {} - ContactWindow {} - }) + if app_context.read().store.is_logged { + cx.render(rsx! { + AppStyle {}, + ContactWindow {}, + }) + } else { + cx.render(rsx! { + AppStyle {}, + Login {} + }) + } } #[tokio::main] diff --git a/src/matrix_client.rs b/src/matrix_client.rs index c5ee1df..44eb6a0 100644 --- a/src/matrix_client.rs +++ b/src/matrix_client.rs @@ -1,4 +1,7 @@ -use dirs; +use std::fmt::{Debug, Formatter}; +use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; +use std::sync::Arc; + use matrix_sdk::{ config::SyncSettings, room::Room, @@ -8,14 +11,8 @@ use matrix_sdk::{ }, Client, Error as MatrixError, }; -use std::fmt::{Debug, Formatter}; -use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; -use std::sync::{Arc, Mutex}; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}; use tokio::task::JoinHandle; -use tokio::time::{sleep, Duration}; - -use crate::base::Info; #[derive(Debug)] pub enum LoginStyle { @@ -40,12 +37,18 @@ impl ClientReply { } } +#[derive(thiserror::Error, Debug)] +pub enum MatrixClientError { + #[error("Matrix client error: {0}")] + Matrix(#[from] matrix_sdk::Error), +} + pub enum WorkerTask { // Init(AsyncProgramStore, ClientReply<()>), // Init(ClientReply<()>), Init(ClientReply<()>), //Login(LoginStyle, ClientReply), - Login(LoginStyle, ClientReply<()>), + Login(LoginStyle, ClientReply>), } impl Debug for WorkerTask { @@ -91,7 +94,7 @@ impl Requester { return response.recv(); } - pub fn login(&self, style: LoginStyle) { + pub fn login(&self, style: LoginStyle) -> anyhow::Result<()> { println!("Requester.login BEG"); let (reply, response) = oneshot(); @@ -169,7 +172,7 @@ impl MatrixClient { } WorkerTask::Login(style, reply) => { assert!(self.initialized); - reply.send(self.login_and_sync(style).await.unwrap()); + reply.send(self.login_and_sync(style).await); } } } @@ -188,7 +191,8 @@ impl MatrixClient { .login_username(&username, &password) .initial_device_display_name("TODO") .send() - .await?; + .await + .map_err(MatrixClientError::from)?; dbg!(resp); } }