2 Commits

Author SHA1 Message Date
22ef914304 First try of making reactive state external using UseRw 2023-08-09 22:54:32 +02:00
2bbee1633f 🎨 Merge app_settings.rs and base.rs files 2023-08-09 22:40:11 +02:00
6 changed files with 75 additions and 70 deletions

View File

@@ -19,6 +19,7 @@ tracing-subscriber = "0.3.17"
dioxus-free-icons = { version = "0.7.0", features = ["material-design-icons-navigation", "ionicons"] } dioxus-free-icons = { version = "0.7.0", features = ["material-design-icons-navigation", "ionicons"] }
thiserror = "1.0.44" thiserror = "1.0.44"
turf = "0.5.0" turf = "0.5.0"
dioxus-std = { version = "0.4.0", features = ["utils"] }
[build] [build]
target = "x86_64-unknown-linux-gnu" target = "x86_64-unknown-linux-gnu"

View File

@@ -1,31 +0,0 @@
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use crate::base::Store;
use crate::matrix_client::Requester;
#[derive(Debug, Clone)]
pub struct AppSettings {
// pub matrix_client: Option<Arc<Mutex<MatrixClient>>>,
// pub matrix_client: Arc<MatrixClient>,
// pub matrix_client: Rc<RefCell<MatrixClient>>,
// pub matrix_client: Arc<MatrixClient>,
//pub matrix_client: Arc<Mutex<MatrixClient>>,
pub requester: Option<Arc<Requester>>,
pub store: Store,
}
impl AppSettings {
pub fn new() -> Self {
Self {
// 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())),
}
}
}

View File

@@ -1,13 +1,25 @@
use std::sync::Arc;
use crate::matrix_client::Requester;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct Store { pub struct Store {
pub is_logged: bool, pub is_logged: bool,
} }
// pub type ProgramStore = Store<Info>;
// pub type AsyncProgramStore = Arc<AsyncMutex<ProgramStore>>;
impl Store { impl Store {
pub fn new() -> Self { pub fn new() -> Self {
Self { is_logged: false } Self { is_logged: false }
} }
} }
#[derive(Clone)]
pub struct AppSettings {
pub requester: Option<Arc<Requester>>,
}
impl AppSettings {
pub fn new() -> Self {
Self { requester: None }
}
}

View File

@@ -1,20 +1,27 @@
use dioxus::prelude::*;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; 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::avatar_selector::AvatarSelector;
use crate::components::header::Header; use crate::components::header::Header;
use crate::matrix_client::{LoginStyle, MatrixClient}; use crate::matrix_client::{LoginStyle, MatrixClient};
turf::style_sheet!("src/components/login.scss"); turf::style_sheet!("src/components/login.scss");
pub fn Login(cx: Scope) -> Element { #[derive(Props)]
let app_context = use_shared_state::<AppSettings>(cx).unwrap(); 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 login = use_ref(cx, || Login::new());
let invalid_login = use_state(cx, || false); let store = cx.props.store.clone();
let empty_placeholder = String::from(""); let empty_placeholder = String::from("");
@@ -26,22 +33,19 @@ pub fn Login(cx: Scope) -> Element {
let run_matrix_client = move |_| { let run_matrix_client = move |_| {
cx.spawn({ 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 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();
async move { async move {
let mut context = app_context.write(); let requester = MatrixClient::spawn(homeserver_url, store).await;
let requester = MatrixClient::spawn(homeserver_url).await;
requester.init(); requester.init();
match requester.login(LoginStyle::Password(username, password)) { match requester.login(LoginStyle::Password(username, password)) {
Ok(_) => { Ok(_) => {
println!("successfully logged"); println!("successfully logged");
context.store.is_logged = true;
} }
Err(err) => { Err(err) => {
println!("Error during login: {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)] #![allow(non_snake_case)]
use dioxus::prelude::*; use dioxus::prelude::*;
use dioxus_desktop::Config; use dioxus_desktop::Config;
use dioxus_std::utils::rw::use_rw;
pub mod app_settings;
pub mod components; pub mod components;
pub mod matrix_client; pub mod matrix_client;
use crate::app_settings::AppSettings; use crate::base::{AppSettings, Store};
use crate::components::contacts_window::ContactWindow; use crate::components::contacts_window::ContactWindow;
use crate::components::login::Login; use crate::components::login::Login;
@@ -15,18 +15,16 @@ 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(); let store = use_rw(cx, || Store::new());
// let window = dioxus_desktop::use_window(cx); let is_logged = store.read().unwrap().is_logged;
// let dom = VirtualDom::new(ControlWindow);
// window.new_window(dom, cx.props.clone());
cx.render(rsx! { cx.render(rsx! {
if app_context.read().store.is_logged { if is_logged {
rsx!(ContactWindow {}) rsx!(ContactWindow {})
} }
else { 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::mpsc::{sync_channel, Receiver, SyncSender};
use std::sync::Arc; use std::sync::Arc;
use dioxus_std::utils::rw::UseRw;
use matrix_sdk::{ use matrix_sdk::{
config::SyncSettings, config::SyncSettings,
room::Room, room::Room as MatrixRoom,
ruma::events::room::{ ruma::events::{presence::PresenceEvent, typing::SyncTypingEvent},
member::StrippedRoomMemberEvent, Client,
message::{OriginalSyncRoomMessageEvent, RoomMessageEventContent, SyncRoomMessageEvent},
},
Client, Error as MatrixError,
}; };
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 crate::base::Store;
#[derive(Debug)] #[derive(Debug)]
pub enum LoginStyle { pub enum LoginStyle {
// SessionRestore(Session), // SessionRestore(Session),
@@ -79,7 +79,6 @@ fn oneshot<T>() -> (ClientReply<T>, ClientResponse<T>) {
#[derive(Debug)] #[derive(Debug)]
pub struct Requester { pub struct Requester {
pub client: Client, pub client: Client,
// pub matrix_client: MatrixClient,
pub tx: UnboundedSender<WorkerTask>, pub tx: UnboundedSender<WorkerTask>,
} }
@@ -105,18 +104,17 @@ impl Requester {
} }
} }
#[derive(Debug)]
pub struct MatrixClient { pub struct MatrixClient {
initialized: bool, initialized: bool,
// client: Client,
client: Option<Arc<Client>>, client: Option<Arc<Client>>,
sync_token: Option<String>, // sync_token: Option<String>,
load_handle: Option<JoinHandle<()>>, // load_handle: Option<JoinHandle<()>>,
sync_handle: Option<JoinHandle<()>>, sync_handle: Option<JoinHandle<()>>,
store: UseRw<Store>,
} }
impl MatrixClient { 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 (tx, rx) = unbounded_channel::<WorkerTask>();
let client = Client::builder() let client = Client::builder()
@@ -128,9 +126,10 @@ impl MatrixClient {
let mut matrix_client = MatrixClient { let mut matrix_client = MatrixClient {
client: None, client: None,
initialized: false, initialized: false,
sync_token: None, // sync_token: None,
load_handle: None, // load_handle: None,
sync_handle: None, sync_handle: None,
store: store,
}; };
matrix_client.client = Some(Arc::new(client.clone())); 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) { async fn init(&mut self) {
self.initialized = true; 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<()> { async fn login_and_sync(&mut self, style: LoginStyle) -> anyhow::Result<()> {
@@ -186,26 +200,33 @@ impl MatrixClient {
match style { match style {
LoginStyle::Password(username, password) => { LoginStyle::Password(username, password) => {
let resp = client let _resp = client
.matrix_auth() .matrix_auth()
.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)?; .map_err(MatrixClientError::from)?;
dbg!(resp);
} }
} }
self.sync_handle = tokio::spawn(async move { 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 { loop {
let settings = SyncSettings::default(); let settings = SyncSettings::default();
let _ = client.sync(settings).await; let _ = client.sync(settings).await;
} }
}) })
.into(); .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"); println!("User connected to the homeserver");
Ok(()) Ok(())
} }