From 22ef9143048a0ce4c82a1e27a3e2b855940e95ba Mon Sep 17 00:00:00 2001 From: Adrien Date: Wed, 9 Aug 2023 22:54:32 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20First=20try=20of=20making=20reactiv?= =?UTF-8?q?e=20state=20external=20using=20UseRw?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 1 + src/components/login.rs | 26 ++++++++++--------- src/main.rs | 14 +++++------ src/matrix_client.rs | 55 ++++++++++++++++++++++++++++------------- 4 files changed, 60 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index da622d1..41d2a62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ tracing-subscriber = "0.3.17" dioxus-free-icons = { version = "0.7.0", features = ["material-design-icons-navigation", "ionicons"] } thiserror = "1.0.44" turf = "0.5.0" +dioxus-std = { version = "0.4.0", features = ["utils"] } [build] target = "x86_64-unknown-linux-gnu" diff --git a/src/components/login.rs b/src/components/login.rs index 4849b01..0b74f05 100644 --- a/src/components/login.rs +++ b/src/components/login.rs @@ -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::(cx).unwrap(); +#[derive(Props)] +pub struct LoginProps<'a> { + pub store: &'a mut UseRw, +} +pub fn Login<'a>(cx: Scope<'a, LoginProps<'a>>) -> Element<'a> { + let app_context = use_shared_state::(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)); } }); }; diff --git a/src/main.rs b/src/main.rs index 778a61f..07947c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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) -> Element { use_shared_state_provider(cx, || cx.props.clone()); - let app_context = use_shared_state::(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}) } }) } diff --git a/src/matrix_client.rs b/src/matrix_client.rs index 44eb6a0..294c9e9 100644 --- a/src/matrix_client.rs +++ b/src/matrix_client.rs @@ -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() -> (ClientReply, ClientResponse) { #[derive(Debug)] pub struct Requester { pub client: Client, - // pub matrix_client: MatrixClient, pub tx: UnboundedSender, } @@ -105,18 +104,17 @@ impl Requester { } } -#[derive(Debug)] pub struct MatrixClient { initialized: bool, - // client: Client, client: Option>, - sync_token: Option, - load_handle: Option>, + // sync_token: Option, + // load_handle: Option>, sync_handle: Option>, + store: UseRw, } impl MatrixClient { - pub async fn spawn(homeserver_url: String) -> Requester { + pub async fn spawn(homeserver_url: String, store: UseRw) -> Requester { let (tx, rx) = unbounded_channel::(); 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(()) }