🚧 Handle logged state + Login -> ContactsWindow transition

This commit is contained in:
2023-08-05 20:17:05 +02:00
parent 45d5eb704c
commit a380c42b03
6 changed files with 81 additions and 30 deletions

View File

@@ -18,6 +18,7 @@ dirs = "5.0.1"
ctrlc-async = "3.2.2" ctrlc-async = "3.2.2"
tracing-subscriber = "0.3.17" tracing-subscriber = "0.3.17"
dioxus-free-icons = { version = "0.6.0", features = ["material-design-icons-navigation", "ionicons"] } dioxus-free-icons = { version = "0.6.0", features = ["material-design-icons-navigation", "ionicons"] }
thiserror = "1.0.44"
[build] [build]
target = "x86_64-unknown-linux-gnu" target = "x86_64-unknown-linux-gnu"

View File

@@ -2,7 +2,7 @@ use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::matrix_client::MatrixClient; use crate::base::Store;
use crate::matrix_client::Requester; use crate::matrix_client::Requester;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -13,6 +13,7 @@ pub struct AppSettings {
// pub matrix_client: Arc<MatrixClient>, // pub matrix_client: Arc<MatrixClient>,
//pub matrix_client: Arc<Mutex<MatrixClient>>, //pub matrix_client: Arc<Mutex<MatrixClient>>,
pub requester: Option<Arc<Requester>>, pub requester: Option<Arc<Requester>>,
pub store: Store,
} }
impl AppSettings { impl AppSettings {
@@ -21,6 +22,7 @@ impl AppSettings {
// matrix_client: Arc::new(MatrixClient::new()), // matrix_client: Arc::new(MatrixClient::new()),
//matrix_client: Arc::new(Mutex::new(MatrixClient::new())), //matrix_client: Arc::new(Mutex::new(MatrixClient::new())),
requester: None, requester: None,
store: Store::new(),
// matrix_client: Arc::new(Mutex::new(MatrixClient::new())), // matrix_client: Arc::new(Mutex::new(MatrixClient::new())),
// matrix_client: Arc::new(MatrixClient::new()), // matrix_client: Arc::new(MatrixClient::new()),
// matrix_client: Rc::new(RefCell::new(MatrixClient::new())), // matrix_client: Rc::new(RefCell::new(MatrixClient::new())),

View File

@@ -1,5 +1,13 @@
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub enum Info {} pub struct Store {
pub is_logged: bool,
}
// pub type ProgramStore = Store<Info>; // pub type ProgramStore = Store<Info>;
// pub type AsyncProgramStore = Arc<AsyncMutex<ProgramStore>>; // pub type AsyncProgramStore = Arc<AsyncMutex<ProgramStore>>;
impl Store {
pub fn new() -> Self {
Self { is_logged: false }
}
}

View File

@@ -10,10 +10,11 @@ use crate::matrix_client::{LoginStyle, MatrixClient};
pub fn Login(cx: Scope) -> Element { pub fn Login(cx: Scope) -> Element {
let app_context = use_shared_state::<AppSettings>(cx).unwrap(); let app_context = use_shared_state::<AppSettings>(cx).unwrap();
println!("app_context={:?}", app_context.read());
let login = use_ref(cx, || Login::new()); let login = use_ref(cx, || Login::new());
let invalid_login = use_state(cx, || false);
let empty_placeholder = String::from(""); let empty_placeholder = String::from("");
let root = css!( 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 |_| { 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 homeserver_url = login.read().homeserver_url.clone().unwrap();
let username = login.read().email.clone().unwrap(); let username = login.read().email.clone().unwrap();
let password = login.read().password.clone().unwrap(); let password = login.read().password.clone().unwrap();
cx.spawn(async { async move {
let mut context = app_context.write();
let requester = MatrixClient::spawn(homeserver_url).await; let requester = MatrixClient::spawn(homeserver_url).await;
requester.init(); requester.init();
requester.login(LoginStyle::Password(username, password));
let context = app_context; match requester.login(LoginStyle::Password(username, password)) {
context.write().requester = Some(Arc::new(requester)); 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:" "Password:"
}, },
input { input {
class: "{password_class}",
id: "login-input-password", id: "login-input-password",
r#type: "password", r#type: "password",
name: "Password", name: "Password",
value: "{login.read().password.as_ref().unwrap_or(&empty_placeholder)}", 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 { div {

View File

@@ -17,6 +17,8 @@ mod base;
fn App(cx: Scope<AppSettings>) -> Element { fn App(cx: Scope<AppSettings>) -> Element {
use_shared_state_provider(cx, || cx.props.clone()); use_shared_state_provider(cx, || cx.props.clone());
let app_context = use_shared_state::<AppSettings>(cx).unwrap();
global_css!( global_css!(
" "
body { body {
@@ -70,11 +72,17 @@ fn App(cx: Scope<AppSettings>) -> Element {
// let dom = VirtualDom::new(ControlWindow); // let dom = VirtualDom::new(ControlWindow);
// window.new_window(dom, cx.props.clone()); // window.new_window(dom, cx.props.clone());
if app_context.read().store.is_logged {
cx.render(rsx! { cx.render(rsx! {
AppStyle {}, AppStyle {},
// Login {} ContactWindow {},
ContactWindow {}
}) })
} else {
cx.render(rsx! {
AppStyle {},
Login {}
})
}
} }
#[tokio::main] #[tokio::main]

View File

@@ -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::{ use matrix_sdk::{
config::SyncSettings, config::SyncSettings,
room::Room, room::Room,
@@ -8,14 +11,8 @@ use matrix_sdk::{
}, },
Client, Error as MatrixError, 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::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use tokio::time::{sleep, Duration};
use crate::base::Info;
#[derive(Debug)] #[derive(Debug)]
pub enum LoginStyle { pub enum LoginStyle {
@@ -40,12 +37,18 @@ impl<T> ClientReply<T> {
} }
} }
#[derive(thiserror::Error, Debug)]
pub enum MatrixClientError {
#[error("Matrix client error: {0}")]
Matrix(#[from] matrix_sdk::Error),
}
pub enum WorkerTask { pub enum WorkerTask {
// Init(AsyncProgramStore, ClientReply<()>), // Init(AsyncProgramStore, ClientReply<()>),
// Init(ClientReply<()>), // Init(ClientReply<()>),
Init(ClientReply<()>), Init(ClientReply<()>),
//Login(LoginStyle, ClientReply<EditInfo>), //Login(LoginStyle, ClientReply<EditInfo>),
Login(LoginStyle, ClientReply<()>), Login(LoginStyle, ClientReply<anyhow::Result<()>>),
} }
impl Debug for WorkerTask { impl Debug for WorkerTask {
@@ -91,7 +94,7 @@ impl Requester {
return response.recv(); return response.recv();
} }
pub fn login(&self, style: LoginStyle) { pub fn login(&self, style: LoginStyle) -> anyhow::Result<()> {
println!("Requester.login BEG"); println!("Requester.login BEG");
let (reply, response) = oneshot(); let (reply, response) = oneshot();
@@ -169,7 +172,7 @@ impl MatrixClient {
} }
WorkerTask::Login(style, reply) => { WorkerTask::Login(style, reply) => {
assert!(self.initialized); 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) .login_username(&username, &password)
.initial_device_display_name("TODO") .initial_device_display_name("TODO")
.send() .send()
.await?; .await
.map_err(MatrixClientError::from)?;
dbg!(resp); dbg!(resp);
} }
} }