diff --git a/src/domain/model/messaging_interface.rs b/src/domain/model/messaging_interface.rs index 0d7e4ef..ea26778 100644 --- a/src/domain/model/messaging_interface.rs +++ b/src/domain/model/messaging_interface.rs @@ -44,6 +44,7 @@ pub trait RoomMessagingConsumerInterface { #[async_trait(?Send)] pub trait RoomMessagingProviderInterface { async fn get_avatar(&self, id: &RoomId) -> anyhow::Result>; + async fn join(&self, room_id: &RoomId) -> anyhow::Result; } #[async_trait(?Send)] diff --git a/src/domain/model/room.rs b/src/domain/model/room.rs index 119d8e5..91ce56a 100644 --- a/src/domain/model/room.rs +++ b/src/domain/model/room.rs @@ -314,4 +314,10 @@ impl RoomStoreConsumerInterface for Room { fn spaces(&self) -> &Vec { &self.spaces } + + async fn join(&self) { + if let Some(messaging_provider) = &self.messaging_provider { + let _ = messaging_provider.join(&self.id).await; + } + } } diff --git a/src/domain/model/store_interface.rs b/src/domain/model/store_interface.rs index 10aad7a..4a30354 100644 --- a/src/domain/model/store_interface.rs +++ b/src/domain/model/store_interface.rs @@ -29,11 +29,11 @@ pub trait RoomStoreConsumerInterface { fn is_direct(&self) -> Option; fn name(&self) -> Option; fn topic(&self) -> Option; + fn spaces(&self) -> &Vec; #[allow(dead_code)] async fn avatar(&self) -> Option; - - fn spaces(&self) -> &Vec; + async fn join(&self); } pub trait RoomStoreProviderInterface { diff --git a/src/infrastructure/messaging/matrix/client.rs b/src/infrastructure/messaging/matrix/client.rs index 7942580..a49a675 100644 --- a/src/infrastructure/messaging/matrix/client.rs +++ b/src/infrastructure/messaging/matrix/client.rs @@ -776,6 +776,19 @@ impl Client { Ok(None) } + async fn join_room(&self, room_id: &RoomId) -> anyhow::Result { + let client = self.client.as_ref().unwrap(); + + if let Some(room) = client.get_room(room_id) { + return match room.join().await { + Ok(_) => Ok(true), + Err(err) => Err(err.into()), + }; + } + + Ok(false) + } + async fn work(&mut self, mut rx: UnboundedReceiver) { while let Some(task) = rx.recv().await { self.run(task).await; @@ -820,6 +833,9 @@ impl Client { ) .await; } + WorkerTask::JoinRoom(id, reply) => { + reply.send(self.join_room(&id).await).await; + } } } } diff --git a/src/infrastructure/messaging/matrix/requester.rs b/src/infrastructure/messaging/matrix/requester.rs index 85f7f29..232cb10 100644 --- a/src/infrastructure/messaging/matrix/requester.rs +++ b/src/infrastructure/messaging/matrix/requester.rs @@ -362,6 +362,10 @@ impl RoomMessagingProviderInterface for Requester { async fn get_avatar(&self, room_id: &RoomId) -> anyhow::Result> { request_to_worker!(self, WorkerTask::GetRoomAvatar, room_id.clone()) } + + async fn join(&self, room_id: &RoomId) -> anyhow::Result { + request_to_worker!(self, WorkerTask::JoinRoom, room_id.clone()) + } } #[async_trait(?Send)] diff --git a/src/infrastructure/messaging/matrix/worker_tasks.rs b/src/infrastructure/messaging/matrix/worker_tasks.rs index e8bb291..85be9fc 100644 --- a/src/infrastructure/messaging/matrix/worker_tasks.rs +++ b/src/infrastructure/messaging/matrix/worker_tasks.rs @@ -23,6 +23,7 @@ pub enum WorkerTask { OwnedUserId, Sender>>>, ), + JoinRoom(OwnedRoomId, Sender>), } impl Debug for WorkerTask { @@ -61,6 +62,10 @@ impl Debug for WorkerTask { .field(room_id) .field(user_id) .finish(), + WorkerTask::JoinRoom(room_id, _) => f + .debug_tuple("WorkerTask::JoinRoom") + .field(room_id) + .finish(), } } } diff --git a/src/ui/components/conversations.rs b/src/ui/components/conversations.rs index 2ea9917..ee71bdd 100644 --- a/src/ui/components/conversations.rs +++ b/src/ui/components/conversations.rs @@ -2,6 +2,7 @@ use std::{rc::Rc, time::Duration}; use base64::{engine::general_purpose, Engine as _}; use dioxus::prelude::*; +use futures_util::StreamExt; use tracing::{debug, warn}; use super::{button::Button, icons::SearchIcon, text_input::TextInput}; @@ -431,11 +432,16 @@ pub fn Search() -> Element { } } +#[derive(PartialEq)] +enum ConversationOptionsMenuActions { + Join(RoomId), + Close, +} + #[component] fn ConversationOptionsMenu( room_id: RoomId, - on_close: EventHandler, - on_join: EventHandler, + callbacks: Coroutine, ) -> Element { let room = STORE.read().rooms().get(&room_id).unwrap().signal(); @@ -450,7 +456,7 @@ fn ConversationOptionsMenu( div { class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_AVATAR, - ConversationAvatar { room_id } + ConversationAvatar { room_id: room_id.clone() } } div { @@ -477,7 +483,9 @@ fn ConversationOptionsMenu( div { class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_CLOSE_BUTTON, RejectButton { - onclick: move |_| on_close(()) + onclick: move |_| { + callbacks.send(ConversationOptionsMenuActions::Close); + } } } @@ -485,8 +493,8 @@ fn ConversationOptionsMenu( class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_JOIN_BUTTON, JoinButton { onclick: move |_| { - on_join(()); - on_close(()); + callbacks.send(ConversationOptionsMenuActions::Join(room_id.clone())); + callbacks.send(ConversationOptionsMenuActions::Close); } } } @@ -498,26 +506,33 @@ fn ConversationOptionsMenu( pub fn Conversations() -> Element { let mut room_id = use_signal(|| None::); - let on_menu_close = move |_| { - room_id.set(None); - }; - - let on_menu_join = move |_| async move { - let rooms = STORE.read().rooms(); - if let Some(room_id) = room_id.read().to_owned() { - if let Some(room) = rooms.get(&room_id) {} - } - }; - let on_pressed_conversation = move |id: RoomId| { room_id.set(Some(id)); }; + let callbacks = use_coroutine( + move |mut rx: UnboundedReceiver| async move { + while let Some(action) = rx.next().await { + match action { + ConversationOptionsMenuActions::Join(room_id) => { + let rooms = STORE.read().rooms(); + if let Some(room) = rooms.get(&room_id) { + room.join().await; + } + } + ConversationOptionsMenuActions::Close => { + room_id.set(None); + } + } + } + }, + ); + let menu = match room_id.read().as_ref() { Some(room_id) => { let room_id = room_id.clone(); rsx! { - ConversationOptionsMenu { room_id, on_close: on_menu_close, on_join: on_menu_join } + ConversationOptionsMenu { room_id, callbacks } } } None => VNode::empty(), diff --git a/src/ui/store/room.rs b/src/ui/store/room.rs index f65e37d..6d9145e 100644 --- a/src/ui/store/room.rs +++ b/src/ui/store/room.rs @@ -33,7 +33,6 @@ pub struct Store { pub struct Room { store: RefCell, - #[allow(dead_code)] domain: Rc, } @@ -57,6 +56,10 @@ impl Room { } } + pub async fn join(&self) { + self.domain.join().await; + } + #[allow(dead_code)] pub async fn get_avatar(&self) -> Option { self.domain.avatar().await @@ -81,6 +84,11 @@ impl RoomStoreProviderInterface for Room { fn on_new_member(&self, member: RoomMember) { let mut store = self.store.borrow_mut(); + + if member.is_account_user() { + store.is_invited.set(false); + } + store.members.write().push(member); }