✨ First try of making reactive state external using UseRw
This commit is contained in:
@@ -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"
|
||||
|
@@ -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));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
14
src/main.rs
14
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<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})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -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(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user