From fdae149c4ac34b1e5fac9122a0b91e7cc4c21139 Mon Sep 17 00:00:00 2001 From: Adrien Date: Fri, 17 May 2024 22:41:35 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20Add=20Avatar=20management=20and?= =?UTF-8?q?=20refresh=20the=20Matrix=20client=20part?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/domain/model/messaging_interface.rs | 4 +- src/infrastructure/messaging/matrix/client.rs | 642 ++++++++++-------- .../messaging/matrix/requester.rs | 31 +- .../messaging/matrix/room_event.rs | 27 +- .../messaging/matrix/worker_tasks.rs | 6 +- 5 files changed, 399 insertions(+), 311 deletions(-) diff --git a/src/domain/model/messaging_interface.rs b/src/domain/model/messaging_interface.rs index 7e70b51..7f3ce4e 100644 --- a/src/domain/model/messaging_interface.rs +++ b/src/domain/model/messaging_interface.rs @@ -5,8 +5,8 @@ use tokio::sync::broadcast::Receiver; use super::{ common::{Avatar, UserId}, - room_member::RoomMember, room::{Invitation, Room, RoomId}, + room_member::{AvatarUrl, RoomMember}, space::Space, }; use crate::infrastructure::messaging::matrix::account_event::AccountEvent; @@ -35,6 +35,7 @@ pub trait RoomMessagingConsumerInterface { async fn on_new_topic(&self, _topic: Option) {} async fn on_new_name(&self, _name: Option) {} + async fn on_new_avatar(&self, _url: Option) {} #[allow(dead_code)] async fn on_membership(&self, _member: RoomMember) {} @@ -63,5 +64,6 @@ pub trait MemberMessagingProviderInterface { &self, room_id: &RoomId, user_id: &UserId, + avatar_url: &Option, ) -> anyhow::Result>; } diff --git a/src/infrastructure/messaging/matrix/client.rs b/src/infrastructure/messaging/matrix/client.rs index 295b909..cfba798 100644 --- a/src/infrastructure/messaging/matrix/client.rs +++ b/src/infrastructure/messaging/matrix/client.rs @@ -9,20 +9,22 @@ use dioxus::prelude::Task; use matrix_sdk::{ config::SyncSettings, event_handler::Ctx, - media::{MediaFormat, MediaThumbnailSize}, - room::{Room, RoomMember}, + media::{MediaFormat, MediaRequest, MediaThumbnailSize}, + room::{ParentSpace, Room, RoomMember}, ruma::{ api::client::media::get_content_thumbnail::v3::Method, events::{ room::{ - member::{ - OriginalSyncRoomMemberEvent, RoomMemberEventContent, StrippedRoomMemberEvent, - }, - topic::RoomTopicEventContent, + avatar::{RoomAvatarEventContent, StrippedRoomAvatarEvent}, + create::{RoomCreateEventContent, StrippedRoomCreateEvent}, + member::{MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent}, + name::{RoomNameEventContent, StrippedRoomNameEvent}, + topic::{RoomTopicEventContent, StrippedRoomTopicEvent}, + MediaSource, }, SyncStateEvent, }, - uint, OwnedRoomId, RoomId, UserId, + uint, OwnedMxcUri, OwnedRoomId, OwnedUserId, RoomId, UserId, }, Client as MatrixClient, RoomMemberships, RoomState, }; @@ -68,21 +70,29 @@ impl Senders { room_senders.contains_key(room_id) } - fn send(&self, room_id: &RoomId, event: RoomEvent) -> Result> { + fn send(&self, room_id: &RoomId, event: RoomEvent) -> Result<(), SendError> { let room_senders = self.room_events_senders.lock().unwrap(); + if let Some(room_sender) = room_senders.get(room_id) { - room_sender.send(event) + if let Err(err) = room_sender.send(event) { + error!("Unable to send event to the {room_id} room: {err}"); + return Err(err); + } } else { - error!("No sender found for \"{}\" room id", room_id); - Ok(0) + warn!("No sender found for {room_id} room"); + // TODO: Return error } + Ok(()) } fn add_room(&self, room_id: &OwnedRoomId) -> Option { let mut senders = self.room_events_senders.lock().unwrap(); if !senders.contains_key(room_id) { let (room_sender, room_receiver) = broadcast::channel(32); + senders.insert(room_id.clone(), room_sender); + debug!("Create sender for {room_id} room"); + Some(RoomEventsReceiver::new(room_receiver)) } else { None @@ -109,45 +119,43 @@ impl Client { async fn create_space( senders: &Ctx, - room_id: OwnedRoomId, + room_id: &OwnedRoomId, room: Option<&Room>, ) -> anyhow::Result<(), SendError> { - let mut name = None; - let mut topic = None; - - if let Some(room) = room { - name = room.name(); - topic = room.topic(); - } - if let Some(receiver) = senders.add_room(&room_id) { + let mut name = None; + let mut topic = None; + if let Some(room) = room { + name = room.name(); + topic = room.topic(); + } + let (reply, mut response) = oneshot::(); - let event = AccountEvent::NewSpace(room_id.clone(), name, topic, receiver, reply); + let event = AccountEvent::NewSpace( + room_id.clone(), + name.clone(), + topic.clone(), + receiver, + reply, + ); if let Err(err) = senders.account_events_sender.send(event) { - error!( - "Unable to publish the new room with \"{}\" id: {}", - room_id, err - ); return Err(err); } // We're expecting a response indicating that the client is able to compute the next RoomEvent response.recv().await; - } else { + let events = vec![RoomEvent::NewTopic(topic), RoomEvent::NewName(name)]; for event in events { - if let Err(err) = senders.send(&room_id, event.clone()) { - error!( - "Unable to publish the {:?} event to the \"{}\" room: {}", - event, room_id, err - ); - // return Err(err); + if let Err(_err) = senders.send(&room_id, event.clone()) { + // TODO: Return an error } } } + Ok(()) } @@ -163,24 +171,25 @@ impl Client { let is_direct = match room.is_direct().await { Ok(is_direct) => Some(is_direct), Err(err) => { - error!("Unable to know if the room \"{room_id}\" is direct: {err}"); + error!("Unable to know if the {room_id} room is direct: {err}"); None } }; let mut parents = vec![]; - // TODO: Remove unwrap - let mut spaces = room.parent_spaces().await.unwrap(); - while let Some(parent) = spaces.next().await { - match parent { - Ok(parent) => match parent { - matrix_sdk::room::ParentSpace::Reciprocal(parent) => { - parents.push(parent.room_id().to_owned()); + + if let Ok(mut spaces) = room.parent_spaces().await { + while let Some(parent) = spaces.next().await { + match parent { + Ok(parent) => match parent { + ParentSpace::Reciprocal(parent) => { + parents.push(parent.room_id().to_owned()); + } + _ => todo!(), + }, + Err(err) => { + error!("{err}"); } - _ => todo!(), - }, - Err(err) => { - error!("{}", err); } } } @@ -197,11 +206,6 @@ impl Client { ); if let Err(err) = senders.account_events_sender.send(event) { - error!( - "Unable to publish the new room with \"{}\" id: {}", - room.room_id(), - err - ); return Err(err); } @@ -218,255 +222,283 @@ impl Client { let room_id = room.room_id().to_owned(); if room.is_space() { - Self::create_space(senders, room_id, Some(room)).await + Self::create_space(senders, &room_id, Some(room)).await } else { - let ret = Self::create_room(senders, room).await; - let mut parents = vec![]; - // TODO: Remove unwrap - let mut spaces = room.parent_spaces().await.unwrap(); - while let Some(parent) = spaces.next().await { - match parent { - Ok(parent) => match parent { - matrix_sdk::room::ParentSpace::Reciprocal(parent) => { - parents.push(parent.room_id().to_owned()); + + if let Ok(mut spaces) = room.parent_spaces().await { + while let Some(parent) = spaces.next().await { + match parent { + Ok(parent) => match parent { + ParentSpace::Reciprocal(parent) => { + parents.push(parent.room_id().to_owned()); + } + _ => { + warn!( + "Only ParentSpace::Reciprocal taken into account, skip {:?}", + parent + ); + } + }, + Err(err) => { + error!("{err}"); } - _ => { - warn!( - "Only ParentSpace::Reciprocal taken into account, skip {:?}", - parent - ); - } - }, - Err(err) => { - error!("{}", err); } } } - error!("parents={:?}", &parents); for parent in parents { // Create a minimal space to make the relation consistent... its content will be sync later. if !senders.contains(&parent) { - let _ = Self::create_space(senders, parent.clone(), None).await; + let _ = Self::create_space(senders, &parent, None).await; } let event = RoomEvent::NewChild(room_id.clone()); - if let Err(err) = senders.send(parent.as_ref(), event.clone()) { - error!( - "Unable to send the {:?} event to the \"{}\": {:?}", - event, parent, err - ); + if let Err(_err) = senders.send(&parent, event) { + // TODO: Return an error } } - ret + Self::create_room(senders, room).await } } - // async fn on_sync_typing_event(_ev: SyncTypingEvent, room: Room) { - // debug!("== on_sync_typing_event =="); - // let room_id = room.room_id().to_owned(); - // dbg!(room_id); - // } + async fn on_stripped_room_create_event( + _ev: StrippedRoomCreateEvent, + room: Room, + senders: Ctx, + ) { + let _ = Self::add_room(&senders, &room).await; + } - // async fn on_presence_event(_ev: PresenceEvent) { - // debug!("== on_presence_event =="); - // dbg!(_ev); - // } + // SyncStateEvent: A possibly-redacted state event without a room_id. + async fn on_sync_room_create_event( + _ev: SyncStateEvent, + room: Room, + senders: Ctx, + ) { + let _ = Self::add_room(&senders, &room).await; + } - // async fn on_sync_state_event(ev: SyncStateEvent, _room: Room) { - // error!("== on_sync_state_event =="); - // if let SyncStateEvent::Original(ev) = ev { - // dbg!(ev); - // } - // } + fn on_invite_room_member_event( + user_id: OwnedUserId, + inviter_id: OwnedUserId, + room: &Room, + matrix_client: &MatrixClient, + senders: &Ctx, + ) { + if let Some(client_user_id) = matrix_client.user_id() { + let is_account_user = user_id == client_user_id; + let room_id = room.room_id(); - // async fn on_original_sync_room_message_event( - // ev: OriginalSyncRoomMessageEvent, - // _room: Room, - // _senders: Ctx, - // ) { - // error!("== on_original_sync_room_message_event =="); - // error!("ev={:?}", ev.content); + debug!( + "{} (account user: {is_account_user}) invited by {} to join the {} room", + &user_id, &inviter_id, &room_id + ); + let event = RoomEvent::Invitation(user_id, inviter_id, is_account_user); + + if let Err(_err) = senders.send(room_id, event) { + // TODO: Return an error + } + } + } + + fn on_join_room_member_event( + user_id: OwnedUserId, + displayname: Option, + avatar_url: Option, + room: &Room, + matrix_client: &MatrixClient, + senders: &Ctx, + ) { + if let Some(client_user_id) = matrix_client.user_id() { + let is_account_user = user_id == client_user_id; + let room_id = room.room_id(); + + error!("{} has joined the {} room", &user_id, &room_id); + + let event = RoomEvent::Join(user_id, displayname, avatar_url, is_account_user); + + if let Err(_err) = senders.send(room_id, event) { + // TODO: Return an error + } + } + } + + // This function is called on each m.room.member event for an invited room preview (room not already joined). + // async fn on_stripped_room_member_event( async fn on_stripped_room_member_event( ev: StrippedRoomMemberEvent, matrix_client: MatrixClient, room: Room, senders: Ctx, ) { - error!("*** on_stripped_room_member_event ***"); - // error!("ev={:?}", ev); + match room.state() { + RoomState::Invited => { + let user_id = &ev.state_key; - if ev.state_key == matrix_client.user_id().unwrap() - && room.state() == RoomState::Invited - && Self::add_room(&senders, &room).await.is_ok() - { - let room_id = room.room_id(); - - let event = RoomEvent::Invitation(); - if let Err(err) = senders.send(room_id, event) { - error!( - "Unable to publish the room \"{}\" invitation: {}", - room.room_id(), - err - ); + match ev.content.membership { + MembershipState::Invite => Self::on_invite_room_member_event( + user_id.clone(), + ev.sender, + &room, + &matrix_client, + &senders, + ), + MembershipState::Join => Self::on_join_room_member_event( + ev.sender, + ev.content.displayname, + ev.content.avatar_url, + &room, + &matrix_client, + &senders, + ), + _ => { + error!("TODO: {:?}", ev); + } + } + } + _ => { + error!("TODO: {:?}", ev); } } } - async fn on_room_topic_event( + // SyncStateEvent: A possibly-redacted state event without a room_id. + // RoomMemberEventContent: The content of an m.room.member event. + async fn on_sync_room_member_event( + ev: SyncStateEvent, + matrix_client: MatrixClient, + room: Room, + senders: Ctx, + ) { + if let SyncStateEvent::Original(ev) = ev { + match ev.content.membership { + MembershipState::Invite => { + let invitee_id = ev.state_key; + + Self::on_invite_room_member_event( + invitee_id, + ev.sender, + &room, + &matrix_client, + &senders, + ) + // .await + } + MembershipState::Join => { + Self::on_join_room_member_event( + ev.sender, + ev.content.displayname, + ev.content.avatar_url, + &room, + &matrix_client, + &senders, + ) + // .await + } + _ => error!("TODO"), + } + } + } + + async fn on_room_avatar_event(room: &Room, senders: &Ctx) { + let room_id = room.room_id(); + let avatar = match room + .avatar(MediaFormat::Thumbnail(MediaThumbnailSize { + method: Method::Scale, + width: uint!(256), + height: uint!(256), + })) + .await + { + Ok(avatar) => avatar, + Err(err) => { + error!("Unable to fetch avatar for {}: {err}", &room_id); + None + } + }; + + let event = RoomEvent::NewAvatar(avatar); + + if let Err(_err) = senders.send(room_id, event) { + // TODO: Return an error + } + } + + async fn on_stripped_room_avatar_event( + _ev: StrippedRoomAvatarEvent, + room: Room, + senders: Ctx, + ) { + Self::on_room_avatar_event(&room, &senders).await; + } + + async fn on_sync_room_avatar_event( + ev: SyncStateEvent, + room: Room, + senders: Ctx, + ) { + if let SyncStateEvent::Original(_ev) = ev { + dioxus::prelude::spawn(async move { + Self::on_room_avatar_event(&room, &senders).await; + }); + } + } + + fn on_room_name_event(name: Option, room: &Room, senders: &Ctx) { + let event = RoomEvent::NewName(name); + + if let Err(_err) = senders.send(room.room_id(), event) { + // TODO: Return an error + } + } + + async fn on_stripped_room_name_event( + ev: StrippedRoomNameEvent, + room: Room, + senders: Ctx, + ) { + Self::on_room_name_event(ev.content.name, &room, &senders); + } + + async fn on_sync_room_name_event( + ev: SyncStateEvent, + room: Room, + senders: Ctx, + ) { + if let SyncStateEvent::Original(ev) = ev { + Self::on_room_name_event(Some(ev.content.name), &room, &senders); + } + } + + fn on_room_topic_event(topic: Option, room: &Room, senders: &Ctx) { + let event = RoomEvent::NewTopic(topic); + + if let Err(_err) = senders.send(room.room_id(), event) { + // TODO: Return an error + } + } + + async fn on_stripped_room_topic_event( + ev: StrippedRoomTopicEvent, + room: Room, + senders: Ctx, + ) { + Self::on_room_topic_event(ev.content.topic, &room, &senders); + } + + async fn on_sync_room_topic_event( ev: SyncStateEvent, room: Room, senders: Ctx, ) { - error!("*** on_room_topic_event ***"); - // error!("ev={:?}", ev); - if let SyncStateEvent::Original(ev) = ev { - let _ = Self::add_room(&senders, &room).await; - - let room_id = room.room_id(); - let event = RoomEvent::NewTopic(Some(ev.content.topic)); - if let Err(err) = senders.send(room_id, event) { - error!( - "Unable to publish the room \"{}\" topic: {}", - room.room_id(), - err - ); - } + Self::on_room_topic_event(Some(ev.content.topic), &room, &senders); } } - async fn on_room_member_event( - ev: SyncStateEvent, - room: Room, - senders: Ctx, - ) { - error!("*** on_room_member_event ***"); - // error!("ev={:?}", ev); - - if let SyncStateEvent::Original(_ev) = ev { - if Self::add_room(&senders, &room).await.is_ok() { - // let room_id = room.room_id(); - // // TODO: Client shall only manage Matrix object... not BG92 ones. - // let event = RoomEvent::Membership(RoomMember::new(ev.sender, room_id)); - // if let Some(result) = senders.send(room_id, event) { - // if let Err(err) = result { - // error!( - // "Unable to publish the room \"{}\" membership: {}", - // room.room_id(), - // err - // ); - // } - // } - } - } - } - - // async fn on_sync_message_like_room_message_event( - // ev: SyncMessageLikeEvent, - // _room: Room, - // _client: MatrixClient, - // ) { - // debug!("== on_sync_message_like_room_message_event =="); - // dbg!(ev); - // } - - // async fn on_sync_message_like_reaction_event( - // ev: SyncMessageLikeEvent, - // _room: Room, - // ) { - // debug!("== on_sync_message_like_reaction_event =="); - // dbg!(ev); - // } - - // async fn on_original_sync_room_redaction_event( - // ev: OriginalSyncRoomRedactionEvent, - // _room: Room, - // ) { - // debug!("== on_original_sync_room_redaction_event =="); - // dbg!(ev); - // } - - async fn on_original_sync_room_member_event( - _ev: OriginalSyncRoomMemberEvent, - _room: Room, - _client: MatrixClient, - ) { - // debug!("== on_original_sync_room_member_event =="); - // error!("room={:?}", room); - // let mut store = store_ctx.read().unwrap().to_owned(); - // dbg!(store.rooms.keys()); - // let is_direct = room.is_direct().await.ok(); - // store.rooms.insert( - // OwnedRoomId::from(room_id), - // Arc::new(RwLock::new(Room::new(Arc::new(room), None, is_direct))), - // ); - // let _ = store_ctx.write(store); - } - - // async fn on_original_sync_key_verif_start_event( - // ev: OriginalSyncKeyVerificationStartEvent, - // _client: MatrixClient, - // ) { - // debug!("== on_original_sync_key_verif_start_event =="); - // dbg!(ev); - // } - - // async fn on_original_sync_key_verif_key_event( - // ev: OriginalSyncKeyVerificationKeyEvent, - // _client: MatrixClient, - // ) { - // debug!("== on_original_sync_key_verif_key_event =="); - // dbg!(ev); - // } - - // async fn on_original_sync_key_verif_done_event( - // ev: OriginalSyncKeyVerificationDoneEvent, - // _client: MatrixClient, - // ) { - // debug!("== on_original_sync_key_verif_done_event =="); - // dbg!(ev); - // } - - // async fn on_device_key_verif_req_event( - // ev: ToDeviceKeyVerificationRequestEvent, - // _client: MatrixClient, - // ) { - // debug!("== on_device_key_verif_req_event =="); - // dbg!(ev); - // } - - // async fn on_device_key_verif_start_event( - // ev: ToDeviceKeyVerificationStartEvent, - // _client: MatrixClient, - // ) { - // debug!("== on_device_key_verif_start_event =="); - // dbg!(ev); - // } - - // 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: MatrixClient, - // ) { - // debug!("== on_device_key_verif_done_event =="); - // dbg!(ev); - // } - - // async fn on_room_event(ev: SomeEvent, _senders: Ctx) { - // debug!("== on_room_event({}) ==", ev.) - // } - pub async fn spawn(homeserver_url: String) -> (Requester, Receiver) { let matrix_client = Arc::new( MatrixClient::builder() @@ -494,28 +526,20 @@ impl Client { // TODO: Remove clone? client.add_event_handler_context(self.senders.clone()); + let _ = client.add_event_handler(Client::on_stripped_room_create_event); + let _ = client.add_event_handler(Client::on_sync_room_create_event); + let _ = client.add_event_handler(Client::on_stripped_room_member_event); - let _ = client.add_event_handler(Client::on_room_topic_event); - let _ = client.add_event_handler(Client::on_room_member_event); + let _ = client.add_event_handler(Client::on_sync_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_original_sync_room_message_event); + let _ = client.add_event_handler(Client::on_stripped_room_avatar_event); + let _ = client.add_event_handler(Client::on_sync_room_avatar_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_stripped_room_name_event); + let _ = client.add_event_handler(Client::on_sync_room_name_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_stripped_room_topic_event); + let _ = client.add_event_handler(Client::on_sync_room_topic_event); self.initialized = true; } @@ -625,27 +649,64 @@ impl Client { } } + // TODO: Share MediaRequest with other media requests + async fn get_thumbnail(&self, media_url: OwnedMxcUri) -> anyhow::Result> { + let client = self.client.as_ref().unwrap(); + let media = client.media(); + + let request = MediaRequest { + source: MediaSource::Plain(media_url), + format: MediaFormat::Thumbnail(MediaThumbnailSize { + method: Method::Scale, + width: uint!(256), + height: uint!(256), + }), + }; + + let res = media.get_media_content(&request, true).await; + + Ok(res?) + } + async fn get_room_member_avatar( &self, room_id: &RoomId, user_id: &UserId, + avatar_url: &Option, ) -> anyhow::Result>> { let client = self.client.as_ref().unwrap(); if let Some(room) = client.get_room(room_id) { - if let Ok(Some(room_member)) = room.get_member(user_id).await { - let res = match room_member - .avatar(MediaFormat::Thumbnail(MediaThumbnailSize { - method: Method::Scale, - width: uint!(256), - height: uint!(256), - })) - .await - { - Ok(avatar) => Ok(avatar), - Err(err) => Err(err.into()), - }; - return res; + // TODO: Check if we can get member before fetching the data and received an error... + + match room.get_member(user_id).await { + Ok(room_member) => match room_member { + Some(room_member) => { + let res = match room_member + .avatar(MediaFormat::Thumbnail(MediaThumbnailSize { + method: Method::Scale, + width: uint!(256), + height: uint!(256), + })) + .await + { + Ok(avatar) => Ok(avatar), + Err(err) => Err(err.into()), + }; + return res; + } + // TODO: Error msg + None => (), + }, + Err(err) => { + error!("Unable to get room member {user_id}: {err}"); + if let Some(avatar_url) = avatar_url { + let thumbnail = self.get_thumbnail(avatar_url.clone()).await; + return Ok(Some(thumbnail?)); + } else { + error!("No avatar url set for the {room_id} room"); + } + } } } Ok(None) @@ -691,9 +752,12 @@ impl Client { reply.send(self.get_room_members(&id).await).await; } - WorkerTask::GetRoomMemberAvatar(room_id, user_id, reply) => { + WorkerTask::GetRoomMemberAvatar(room_id, user_id, avatar_url, reply) => { reply - .send(self.get_room_member_avatar(&room_id, &user_id).await) + .send( + self.get_room_member_avatar(&room_id, &user_id, &avatar_url) + .await, + ) .await; } } diff --git a/src/infrastructure/messaging/matrix/requester.rs b/src/infrastructure/messaging/matrix/requester.rs index a1307cd..fc0e394 100644 --- a/src/infrastructure/messaging/matrix/requester.rs +++ b/src/infrastructure/messaging/matrix/requester.rs @@ -1,7 +1,6 @@ use std::{collections::HashMap, rc::Rc}; use async_trait::async_trait; -use futures::future::join_all; use tokio::{ select, sync::{broadcast::Receiver, mpsc::UnboundedSender}, @@ -23,8 +22,8 @@ use crate::{ RoomMessagingProviderInterface, SpaceMessagingConsumerInterface, SpaceMessagingProviderInterface, }, - room::{Room, RoomId}, - room_member::RoomMember, + room::{Invitation, Room, RoomId}, + room_member::{AvatarUrl, RoomMember}, space::Space, }, utils::oneshot, @@ -182,19 +181,29 @@ impl AccountMessagingProviderInterface for Requester { if let Ok(room_event) = room_event { if let Some(consumer) = room_events_consumers.get(&room_id) { match room_event { - RoomEvent::Invitation() => { - consumer.on_invitation().await; + RoomEvent::Invitation(user_id, sender_id, is_account_user) => { + let invitation = Invitation::new(user_id, sender_id, is_account_user); + consumer.on_invitation(invitation).await; + }, + RoomEvent::Join(user_id, user_name, avatar_url, is_account_user) => { + let member = RoomMember::new( + UserId::from(user_id), + user_name, + avatar_url, + room_id, + is_account_user, + client.clone()); + consumer.on_membership(member).await; }, - // RoomEvent::Membership(user_id, is_account_user) => { - // let member = RoomMember::new(UserId::from(user_id), room_id, is_account_user); - // consumer.on_membership(member).await; - // }, RoomEvent::NewTopic(topic) => { consumer.on_new_topic(topic).await; }, RoomEvent::NewName(name) => { consumer.on_new_name(name).await; }, + RoomEvent::NewAvatar(avatar) => { + consumer.on_new_avatar(avatar).await; + } _ => {} } } else { @@ -256,12 +265,14 @@ impl MemberMessagingProviderInterface for Requester { &self, room_id: &RoomId, user_id: &UserId, + avatar_url: &Option, ) -> anyhow::Result> { request_to_worker!( self, WorkerTask::GetRoomMemberAvatar, room_id.clone(), - user_id.clone() + user_id.clone(), + avatar_url.clone() ) } } diff --git a/src/infrastructure/messaging/matrix/room_event.rs b/src/infrastructure/messaging/matrix/room_event.rs index ca6690e..97b9df1 100644 --- a/src/infrastructure/messaging/matrix/room_event.rs +++ b/src/infrastructure/messaging/matrix/room_event.rs @@ -1,34 +1,43 @@ use std::fmt::{Debug, Formatter}; -use matrix_sdk::ruma::{OwnedRoomId, OwnedUserId}; +use matrix_sdk::ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId}; use tokio::sync::broadcast::Receiver; +use crate::domain::model::common::Avatar; + #[derive(Clone)] pub enum RoomEvent { - Invitation(), - - #[allow(dead_code)] - Membership(OwnedUserId, bool), + Invitation(OwnedUserId, OwnedUserId, bool), + Join(OwnedUserId, Option, Option, bool), NewTopic(Option), NewName(Option), + NewAvatar(Option), NewChild(OwnedRoomId), } impl Debug for RoomEvent { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { match self { - Self::Invitation() => f + Self::Invitation(invitee_id, sender_id, is_account_user) => f .debug_tuple("RoomEvent::Invitation") - .field(&format_args!("_")) + .field(invitee_id) + .field(sender_id) + .field(is_account_user) .finish(), - Self::Membership(user_id, is_account_user) => f - .debug_tuple("RoomEvent::Membership") + Self::Join(user_id, user_name, avatar_url, is_account_user) => f + .debug_tuple("RoomEvent::Join") .field(user_id) + .field(user_name) + .field(avatar_url) .field(is_account_user) .finish(), Self::NewTopic(topic) => f.debug_tuple("RoomEvent::NewTopic").field(topic).finish(), Self::NewName(name) => f.debug_tuple("RoomEvent::NewName").field(name).finish(), + Self::NewAvatar(avatar) => f + .debug_tuple("RoomEvent::NewAvatar") + .field(&format!("is_some: {}", &avatar.is_some())) + .finish(), Self::NewChild(room_id) => f .debug_tuple("SpaceEvent::NewChild") .field(room_id) diff --git a/src/infrastructure/messaging/matrix/worker_tasks.rs b/src/infrastructure/messaging/matrix/worker_tasks.rs index 0c0494a..380d15a 100644 --- a/src/infrastructure/messaging/matrix/worker_tasks.rs +++ b/src/infrastructure/messaging/matrix/worker_tasks.rs @@ -2,7 +2,7 @@ use std::fmt::{Debug, Formatter}; use matrix_sdk::{ room::RoomMember, - ruma::{OwnedRoomId, OwnedUserId}, + ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId}, }; use crate::utils::Sender; @@ -25,6 +25,7 @@ pub enum WorkerTask { GetRoomMemberAvatar( OwnedRoomId, OwnedUserId, + Option, Sender>>>, ), } @@ -64,10 +65,11 @@ impl Debug for WorkerTask { .field(id) .finish(), - WorkerTask::GetRoomMemberAvatar(room_id, user_id, _) => f + WorkerTask::GetRoomMemberAvatar(room_id, user_id, avatar_url, _) => f .debug_tuple("WorkerTask::GetRoomMemberAvatar") .field(room_id) .field(user_id) + .field(avatar_url) .finish(), } }