diff --git a/src/base.rs b/src/base.rs index f447f2a..8802cfb 100644 --- a/src/base.rs +++ b/src/base.rs @@ -7,7 +7,7 @@ use matrix_sdk::{ ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId}, }; -use crate::matrix_client::Requester; +use crate::matrix_interface::requester::Requester; #[derive(Clone, Debug)] pub struct UserInfo { diff --git a/src/components/login.rs b/src/components/login.rs index d9078ff..e6f1a0d 100644 --- a/src/components/login.rs +++ b/src/components/login.rs @@ -7,7 +7,8 @@ use tracing::{debug, error}; use crate::base::APP_SETTINGS; use crate::components::avatar_selector::AvatarSelector; use crate::components::header::Header; -use crate::matrix_client::{LoginStyle, MatrixClient}; +use crate::matrix_interface::client::Client; +use crate::matrix_interface::worker_tasks::LoginStyle; turf::style_sheet!("src/components/login.scss"); @@ -37,7 +38,7 @@ pub fn Login(cx: Scope) -> Element { let password = login_ref.password.clone().unwrap(); async move { - let new_matrix_client = MatrixClient::spawn(homeserver_url).await; + let new_matrix_client = Client::spawn(homeserver_url).await; new_matrix_client.init(); diff --git a/src/main.rs b/src/main.rs index 9143c36..13ef0b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use fermi::*; use tracing::{debug, Level}; pub mod components; -pub mod matrix_client; +pub mod matrix_interface; use crate::base::APP_SETTINGS; use crate::components::chats_window::chats_window::ChatsWindow; diff --git a/src/matrix_client.rs b/src/matrix_interface/client.rs similarity index 67% rename from src/matrix_client.rs rename to src/matrix_interface/client.rs index bf3aebc..e53b8b5 100644 --- a/src/matrix_client.rs +++ b/src/matrix_interface/client.rs @@ -1,7 +1,4 @@ // TODO: make a choice: mpsc vs flume. - -use std::fmt::{Debug, Formatter}; -use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::sync::Arc; use std::time::Duration; @@ -34,104 +31,29 @@ use matrix_sdk::{ typing::SyncTypingEvent, SyncMessageLikeEvent, SyncStateEvent, }, - Client, + Client as MatrixClient, }; +use super::requester::Requester; +use super::worker_tasks::{LoginStyle, WorkerTask}; use crate::base::Room; -#[derive(Debug)] -pub enum LoginStyle { - // SessionRestore(Session), - Password(String, String), -} - -pub struct ClientResponse(Receiver); -pub struct ClientReply(SyncSender); - -impl ClientResponse { - fn recv(self) -> T { - self.0 - .recv() - .expect("failed to receive response from client thread") - } -} - -impl ClientReply { - fn send(self, t: T) { - self.0.send(t).unwrap(); - } -} - #[derive(thiserror::Error, Debug)] -pub enum MatrixClientError { +pub enum ClientError { #[error("Matrix client error: {0}")] Matrix(#[from] matrix_sdk::Error), } -pub enum WorkerTask { - // Init(AsyncProgramStore, ClientReply<()>), - // Init(ClientReply<()>), - Init(ClientReply<()>), - //Login(LoginStyle, ClientReply), - Login(LoginStyle, ClientReply>), -} - -impl Debug for WorkerTask { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { - match self { - WorkerTask::Init(_) => f - .debug_tuple("WorkerTask::Init") - .field(&format_args!("_")) - // .field(&format_args!("_")) - .finish(), - WorkerTask::Login(style, _) => f - .debug_tuple("WorkerTask::Login") - .field(style) - // .field(&format_args!("_")) - .finish(), - } - } -} - -fn oneshot() -> (ClientReply, ClientResponse) { - let (tx, rx) = sync_channel(1); - let reply = ClientReply(tx); - let response = ClientResponse(rx); - - return (reply, response); -} - -#[derive(Debug)] -pub struct Requester { - pub client: Arc, - pub tx: UnboundedSender, - pub rooms_receiver: flume::Receiver, -} - -impl Requester { - pub fn init(&self) { - let (reply, response) = oneshot(); - self.tx.send(WorkerTask::Init(reply)).unwrap(); - return response.recv(); - } - - pub fn login(&self, style: LoginStyle) -> anyhow::Result<()> { - let (reply, response) = oneshot(); - self.tx.send(WorkerTask::Login(style, reply)).unwrap(); - return response.recv(); - } -} - -pub struct MatrixClient { +pub struct Client { initialized: bool, - client: Option>, + client: Option>, load_handle: Option>, sync_handle: Option>, rooms_sender: Option>, } -impl MatrixClient { - pub fn new(client: Arc, rooms_sender: flume::Sender) -> Self { +impl Client { + pub fn new(client: Arc, rooms_sender: flume::Sender) -> Self { Self { initialized: false, client: Some(client), @@ -157,7 +79,7 @@ impl MatrixClient { dbg!(_ev); } - async fn on_room_topic_event(ev: SyncStateEvent, _room: MatrixRoom) { + async fn on_room_topic_event(ev: SyncStateEvent, room: MatrixRoom) { debug!("== on_room_topic_event =="); dbg!(&ev); // if let SyncStateEvent::Original(ev) = ev { @@ -187,7 +109,7 @@ impl MatrixClient { async fn on_sync_message_like_room_message_event( ev: SyncMessageLikeEvent, _room: MatrixRoom, - _client: Client, + _client: MatrixClient, ) { debug!("== on_sync_message_like_room_message_event =="); dbg!(ev); @@ -212,7 +134,7 @@ impl MatrixClient { async fn on_original_sync_room_member_event( ev: OriginalSyncRoomMemberEvent, room: MatrixRoom, - _client: Client, + _client: MatrixClient, ) { debug!("== on_original_sync_room_member_event =="); dbg!(ev); @@ -231,7 +153,7 @@ impl MatrixClient { async fn on_original_sync_key_verif_start_event( ev: OriginalSyncKeyVerificationStartEvent, - _client: Client, + _client: MatrixClient, ) { debug!("== on_original_sync_key_verif_start_event =="); dbg!(ev); @@ -239,7 +161,7 @@ impl MatrixClient { async fn on_original_sync_key_verif_key_event( ev: OriginalSyncKeyVerificationKeyEvent, - _client: Client, + _client: MatrixClient, ) { debug!("== on_original_sync_key_verif_key_event =="); dbg!(ev); @@ -247,7 +169,7 @@ impl MatrixClient { async fn on_original_sync_key_verif_done_event( ev: OriginalSyncKeyVerificationDoneEvent, - _client: Client, + _client: MatrixClient, ) { debug!("== on_original_sync_key_verif_done_event =="); dbg!(ev); @@ -255,7 +177,7 @@ impl MatrixClient { async fn on_device_key_verif_req_event( ev: ToDeviceKeyVerificationRequestEvent, - _client: Client, + _client: MatrixClient, ) { debug!("== on_device_key_verif_req_event =="); dbg!(ev); @@ -263,18 +185,24 @@ impl MatrixClient { async fn on_device_key_verif_start_event( ev: ToDeviceKeyVerificationStartEvent, - _client: Client, + _client: MatrixClient, ) { debug!("== on_device_key_verif_start_event =="); dbg!(ev); } - async fn on_device_key_verif_key_event(ev: ToDeviceKeyVerificationKeyEvent, _client: Client) { + async fn on_device_key_verif_key_event( + ev: ToDeviceKeyVerificationKeyEvent, + _client: MatrixClient, + ) { debug!("== on_device_key_verif_key_event =="); dbg!(ev); } - async fn on_device_key_verif_done_event(ev: ToDeviceKeyVerificationDoneEvent, _client: Client) { + async fn on_device_key_verif_done_event( + ev: ToDeviceKeyVerificationDoneEvent, + _client: MatrixClient, + ) { debug!("== on_device_key_verif_done_event =="); dbg!(ev); } @@ -283,24 +211,24 @@ impl MatrixClient { let (tx, rx) = unbounded_channel::(); let (rooms_sender, rooms_receiver) = unbounded::(); - let client = Arc::new( - Client::builder() + let matrix_client = Arc::new( + MatrixClient::builder() .homeserver_url(&homeserver_url) .build() .await .unwrap(), ); - let mut matrix_client = MatrixClient::new(client.clone(), rooms_sender); + let mut client = Client::new(matrix_client.clone(), rooms_sender); tokio::spawn({ async move { - matrix_client.work(rx).await; + client.work(rx).await; } }); Requester { - client, + matrix_client, tx, rooms_receiver, } @@ -311,30 +239,31 @@ impl MatrixClient { // let store = self.store.clone(); // client.add_event_handler_context(store); + // client.add_event_handler_context(self); - let _ = client.add_event_handler(MatrixClient::on_sync_typing_event); - let _ = client.add_event_handler(MatrixClient::on_presence_event); - let _ = client.add_event_handler(MatrixClient::on_sync_state_event); - let _ = client.add_event_handler(MatrixClient::on_sync_message_like_room_message_event); - let _ = client.add_event_handler(MatrixClient::on_sync_message_like_reaction_event); - let _ = client.add_event_handler(MatrixClient::on_original_sync_room_redaction_event); - let _ = client.add_event_handler(MatrixClient::on_original_sync_room_member_event); - let _ = client.add_event_handler(MatrixClient::on_original_sync_key_verif_start_event); - let _ = client.add_event_handler(MatrixClient::on_original_sync_key_verif_key_event); - let _ = client.add_event_handler(MatrixClient::on_original_sync_key_verif_done_event); - let _ = client.add_event_handler(MatrixClient::on_device_key_verif_req_event); - let _ = client.add_event_handler(MatrixClient::on_device_key_verif_start_event); - let _ = client.add_event_handler(MatrixClient::on_device_key_verif_key_event); - let _ = client.add_event_handler(MatrixClient::on_device_key_verif_done_event); - let _ = client.add_event_handler(MatrixClient::on_room_topic_event); - let _ = client.add_event_handler(MatrixClient::on_room_member_event); + let _ = client.add_event_handler(Client::on_sync_typing_event); + let _ = client.add_event_handler(Client::on_presence_event); + let _ = client.add_event_handler(Client::on_sync_state_event); + let _ = client.add_event_handler(Client::on_sync_message_like_room_message_event); + let _ = client.add_event_handler(Client::on_sync_message_like_reaction_event); + let _ = client.add_event_handler(Client::on_original_sync_room_redaction_event); + let _ = client.add_event_handler(Client::on_original_sync_room_member_event); + let _ = client.add_event_handler(Client::on_original_sync_key_verif_start_event); + let _ = client.add_event_handler(Client::on_original_sync_key_verif_key_event); + let _ = client.add_event_handler(Client::on_original_sync_key_verif_done_event); + let _ = client.add_event_handler(Client::on_device_key_verif_req_event); + let _ = client.add_event_handler(Client::on_device_key_verif_start_event); + let _ = client.add_event_handler(Client::on_device_key_verif_key_event); + let _ = client.add_event_handler(Client::on_device_key_verif_done_event); + let _ = client.add_event_handler(Client::on_room_topic_event); + let _ = client.add_event_handler(Client::on_room_member_event); self.initialized = true; } - async fn refresh_rooms(client: &Client, rooms_sender: &Sender) { - let joined_matrix_rooms_ref = &client.joined_rooms(); - let invited_matrix_rooms_ref = &client.invited_rooms(); + async fn refresh_rooms(matrix_client: &MatrixClient, rooms_sender: &Sender) { + let joined_matrix_rooms_ref = &matrix_client.joined_rooms(); + let invited_matrix_rooms_ref = &matrix_client.invited_rooms(); for matrix_rooms in vec![joined_matrix_rooms_ref, invited_matrix_rooms_ref] { for matrix_room in matrix_rooms.iter() { @@ -350,16 +279,14 @@ impl MatrixClient { } } - async fn refresh_rooms_forever(client: &Client, rooms_channel: &Sender) { + async fn refresh_rooms_forever(matrix_client: &MatrixClient, rooms_channel: &Sender) { // TODO: Add interval to config let mut interval = tokio::time::interval(Duration::from_secs(5)); loop { - Self::refresh_rooms(client, rooms_channel).await; + Self::refresh_rooms(matrix_client, rooms_channel).await; - error!("== Interval tick BEG =="); interval.tick().await; - error!("== Interval tick END =="); } } @@ -374,7 +301,7 @@ impl MatrixClient { .initial_device_display_name("TODO") .send() .await - .map_err(MatrixClientError::from)?; + .map_err(ClientError::from)?; } } diff --git a/src/matrix_interface/mod.rs b/src/matrix_interface/mod.rs new file mode 100644 index 0000000..e239b70 --- /dev/null +++ b/src/matrix_interface/mod.rs @@ -0,0 +1,3 @@ +pub mod client; +pub mod requester; +pub mod worker_tasks; diff --git a/src/matrix_interface/requester.rs b/src/matrix_interface/requester.rs new file mode 100644 index 0000000..5c37d45 --- /dev/null +++ b/src/matrix_interface/requester.rs @@ -0,0 +1,28 @@ +use std::sync::Arc; + +use matrix_sdk::Client as MatrixClient; +use tokio::sync::mpsc::UnboundedSender; + +use super::worker_tasks::{oneshot, LoginStyle, WorkerTask}; +use crate::base::Room; + +#[derive(Debug)] +pub struct Requester { + pub matrix_client: Arc, + pub tx: UnboundedSender, + pub rooms_receiver: flume::Receiver, +} + +impl Requester { + pub fn init(&self) { + let (reply, response) = oneshot(); + self.tx.send(WorkerTask::Init(reply)).unwrap(); + return response.recv(); + } + + pub fn login(&self, style: LoginStyle) -> anyhow::Result<()> { + let (reply, response) = oneshot(); + self.tx.send(WorkerTask::Login(style, reply)).unwrap(); + return response.recv(); + } +} diff --git a/src/matrix_interface/worker_tasks.rs b/src/matrix_interface/worker_tasks.rs new file mode 100644 index 0000000..ff38ae3 --- /dev/null +++ b/src/matrix_interface/worker_tasks.rs @@ -0,0 +1,59 @@ +use std::fmt::{Debug, Formatter}; + +use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; + +pub struct ClientResponse(Receiver); +pub struct ClientReply(SyncSender); + +impl ClientResponse { + pub(super) fn recv(self) -> T { + self.0 + .recv() + .expect("failed to receive response from client thread") + } +} + +impl ClientReply { + pub(super) fn send(self, t: T) { + self.0.send(t).unwrap(); + } +} + +pub(super) fn oneshot() -> (ClientReply, ClientResponse) { + let (tx, rx) = sync_channel(1); + let reply = ClientReply(tx); + let response = ClientResponse(rx); + + return (reply, response); +} + +#[derive(Debug)] +pub enum LoginStyle { + // SessionRestore(Session), + Password(String, String), +} + +pub enum WorkerTask { + // Init(AsyncProgramStore, ClientReply<()>), + // Init(ClientReply<()>), + Init(ClientReply<()>), + //Login(LoginStyle, ClientReply), + Login(LoginStyle, ClientReply>), +} + +impl Debug for WorkerTask { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { + match self { + WorkerTask::Init(_) => f + .debug_tuple("WorkerTask::Init") + .field(&format_args!("_")) + // .field(&format_args!("_")) + .finish(), + WorkerTask::Login(style, _) => f + .debug_tuple("WorkerTask::Login") + .field(style) + // .field(&format_args!("_")) + .finish(), + } + } +}