Add the capability to join a conversation

This commit is contained in:
2024-09-08 16:07:13 +02:00
parent 648be8ba72
commit 9d95bd4481
8 changed files with 76 additions and 21 deletions

View File

@@ -44,6 +44,7 @@ pub trait RoomMessagingConsumerInterface {
#[async_trait(?Send)]
pub trait RoomMessagingProviderInterface {
async fn get_avatar(&self, id: &RoomId) -> anyhow::Result<Option<Avatar>>;
async fn join(&self, room_id: &RoomId) -> anyhow::Result<bool>;
}
#[async_trait(?Send)]

View File

@@ -314,4 +314,10 @@ impl RoomStoreConsumerInterface for Room {
fn spaces(&self) -> &Vec<SpaceId> {
&self.spaces
}
async fn join(&self) {
if let Some(messaging_provider) = &self.messaging_provider {
let _ = messaging_provider.join(&self.id).await;
}
}
}

View File

@@ -29,11 +29,11 @@ pub trait RoomStoreConsumerInterface {
fn is_direct(&self) -> Option<bool>;
fn name(&self) -> Option<String>;
fn topic(&self) -> Option<String>;
fn spaces(&self) -> &Vec<SpaceId>;
#[allow(dead_code)]
async fn avatar(&self) -> Option<Avatar>;
fn spaces(&self) -> &Vec<SpaceId>;
async fn join(&self);
}
pub trait RoomStoreProviderInterface {

View File

@@ -776,6 +776,19 @@ impl Client {
Ok(None)
}
async fn join_room(&self, room_id: &RoomId) -> anyhow::Result<bool> {
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<WorkerTask>) {
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;
}
}
}
}

View File

@@ -362,6 +362,10 @@ impl RoomMessagingProviderInterface for Requester {
async fn get_avatar(&self, room_id: &RoomId) -> anyhow::Result<Option<Avatar>> {
request_to_worker!(self, WorkerTask::GetRoomAvatar, room_id.clone())
}
async fn join(&self, room_id: &RoomId) -> anyhow::Result<bool> {
request_to_worker!(self, WorkerTask::JoinRoom, room_id.clone())
}
}
#[async_trait(?Send)]

View File

@@ -23,6 +23,7 @@ pub enum WorkerTask {
OwnedUserId,
Sender<anyhow::Result<Option<Vec<u8>>>>,
),
JoinRoom(OwnedRoomId, Sender<anyhow::Result<bool>>),
}
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(),
}
}
}

View File

@@ -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<ConversationOptionsMenuActions>,
) -> 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::<RoomId>);
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<ConversationOptionsMenuActions>| 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(),

View File

@@ -33,7 +33,6 @@ pub struct Store {
pub struct Room {
store: RefCell<Store>,
#[allow(dead_code)]
domain: Rc<dyn RoomStoreConsumerInterface>,
}
@@ -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<Avatar> {
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);
}