First try of making reactive state external using UseRw

This commit is contained in:
2023-08-09 22:54:32 +02:00
parent 2bbee1633f
commit 22ef914304
4 changed files with 60 additions and 36 deletions

View File

@@ -1,20 +1,27 @@
use dioxus::prelude::*;
use std::str::FromStr;
use std::sync::Arc;
use crate::app_settings::AppSettings;
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");
pub fn Login(cx: Scope) -> Element {
let app_context = use_shared_state::<AppSettings>(cx).unwrap();
#[derive(Props)]
pub struct LoginProps<'a> {
pub store: &'a mut UseRw<Store>,
}
pub fn Login<'a>(cx: Scope<'a, LoginProps<'a>>) -> Element<'a> {
let app_context = use_shared_state::<AppSettings>(cx).unwrap();
let invalid_login = use_state(cx, || false);
let login = use_ref(cx, || Login::new());
let invalid_login = use_state(cx, || false);
let store = cx.props.store.clone();
let empty_placeholder = String::from("");
@@ -26,22 +33,19 @@ pub fn Login(cx: Scope) -> Element {
let run_matrix_client = move |_| {
cx.spawn({
to_owned![app_context, invalid_login, login];
to_owned![app_context, invalid_login, login, store];
let homeserver_url = login.read().homeserver_url.clone().unwrap();
let username = login.read().email.clone().unwrap();
let password = login.read().password.clone().unwrap();
async move {
let mut context = app_context.write();
let requester = MatrixClient::spawn(homeserver_url).await;
let requester = MatrixClient::spawn(homeserver_url, store).await;
requester.init();
match requester.login(LoginStyle::Password(username, password)) {
Ok(_) => {
println!("successfully logged");
context.store.is_logged = true;
}
Err(err) => {
println!("Error during login: {err}");
@@ -49,7 +53,7 @@ pub fn Login(cx: Scope) -> Element {
}
}
context.requester = Some(Arc::new(requester));
app_context.write().requester = Some(Arc::new(requester));
}
});
};

View File

@@ -1,12 +1,12 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_desktop::Config;
use dioxus_std::utils::rw::use_rw;
pub mod app_settings;
pub mod components;
pub mod matrix_client;
use crate::app_settings::AppSettings;
use crate::base::{AppSettings, Store};
use crate::components::contacts_window::ContactWindow;
use crate::components::login::Login;
@@ -15,18 +15,16 @@ mod base;
fn App(cx: Scope<AppSettings>) -> Element {
use_shared_state_provider(cx, || cx.props.clone());
let app_context = use_shared_state::<AppSettings>(cx).unwrap();
let store = use_rw(cx, || Store::new());
// let window = dioxus_desktop::use_window(cx);
// let dom = VirtualDom::new(ControlWindow);
// window.new_window(dom, cx.props.clone());
let is_logged = store.read().unwrap().is_logged;
cx.render(rsx! {
if app_context.read().store.is_logged {
if is_logged {
rsx!(ContactWindow {})
}
else {
rsx!(Login {})
rsx!(Login {store: store})
}
})
}

View File

@@ -2,18 +2,18 @@ use std::fmt::{Debug, Formatter};
use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use std::sync::Arc;
use dioxus_std::utils::rw::UseRw;
use matrix_sdk::{
config::SyncSettings,
room::Room,
ruma::events::room::{
member::StrippedRoomMemberEvent,
message::{OriginalSyncRoomMessageEvent, RoomMessageEventContent, SyncRoomMessageEvent},
},
Client, Error as MatrixError,
room::Room as MatrixRoom,
ruma::events::{presence::PresenceEvent, typing::SyncTypingEvent},
Client,
};
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
use tokio::task::JoinHandle;
use crate::base::Store;
#[derive(Debug)]
pub enum LoginStyle {
// SessionRestore(Session),
@@ -79,7 +79,6 @@ fn oneshot<T>() -> (ClientReply<T>, ClientResponse<T>) {
#[derive(Debug)]
pub struct Requester {
pub client: Client,
// pub matrix_client: MatrixClient,
pub tx: UnboundedSender<WorkerTask>,
}
@@ -105,18 +104,17 @@ impl Requester {
}
}
#[derive(Debug)]
pub struct MatrixClient {
initialized: bool,
// client: Client,
client: Option<Arc<Client>>,
sync_token: Option<String>,
load_handle: Option<JoinHandle<()>>,
// sync_token: Option<String>,
// load_handle: Option<JoinHandle<()>>,
sync_handle: Option<JoinHandle<()>>,
store: UseRw<Store>,
}
impl MatrixClient {
pub async fn spawn(homeserver_url: String) -> Requester {
pub async fn spawn(homeserver_url: String, store: UseRw<Store>) -> Requester {
let (tx, rx) = unbounded_channel::<WorkerTask>();
let client = Client::builder()
@@ -128,9 +126,10 @@ impl MatrixClient {
let mut matrix_client = MatrixClient {
client: None,
initialized: false,
sync_token: None,
load_handle: None,
// sync_token: None,
// load_handle: None,
sync_handle: None,
store: store,
};
matrix_client.client = Some(Arc::new(client.clone()));
@@ -177,8 +176,23 @@ impl MatrixClient {
}
}
async fn on_sync_event(_ev: SyncTypingEvent, room: MatrixRoom) {
println!("== on_sync_event ==");
let room_id = room.room_id().to_owned();
dbg!(room_id);
}
async fn on_presence_event(_ev: PresenceEvent) {
println!("== on_presence_event ==");
}
async fn init(&mut self) {
self.initialized = true;
let client = self.client.clone().unwrap();
let _ = client.add_event_handler(MatrixClient::on_sync_event);
let _ = client.add_event_handler(MatrixClient::on_presence_event);
}
async fn login_and_sync(&mut self, style: LoginStyle) -> anyhow::Result<()> {
@@ -186,26 +200,33 @@ impl MatrixClient {
match style {
LoginStyle::Password(username, password) => {
let resp = client
let _resp = client
.matrix_auth()
.login_username(&username, &password)
.initial_device_display_name("TODO")
.send()
.await
.map_err(MatrixClientError::from)?;
dbg!(resp);
}
}
self.sync_handle = tokio::spawn(async move {
// Sync once so we receive the client state and old messages
let _ret = client.sync_once(SyncSettings::default()).await;
let _rooms = client.rooms();
loop {
let settings = SyncSettings::default();
let _ = client.sync(settings).await;
}
})
.into();
let mut store = self.store.read().unwrap().to_owned();
store.is_logged = true;
let _ = self.store.write(store).unwrap();
println!("User connected to the homeserver");
Ok(())
}