Compare commits
2 Commits
cbe32c250e
...
fdae149c4a
Author | SHA1 | Date | |
---|---|---|---|
fdae149c4a
|
|||
0b898dce52
|
@@ -5,8 +5,8 @@ use tokio::sync::broadcast::Receiver;
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
common::{Avatar, UserId},
|
common::{Avatar, UserId},
|
||||||
room::{Room, RoomId},
|
room::{Invitation, Room, RoomId},
|
||||||
room_member::RoomMember,
|
room_member::{AvatarUrl, RoomMember},
|
||||||
space::Space,
|
space::Space,
|
||||||
};
|
};
|
||||||
use crate::infrastructure::messaging::matrix::account_event::AccountEvent;
|
use crate::infrastructure::messaging::matrix::account_event::AccountEvent;
|
||||||
@@ -31,10 +31,11 @@ pub trait AccountMessagingProviderInterface {
|
|||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
pub trait RoomMessagingConsumerInterface {
|
pub trait RoomMessagingConsumerInterface {
|
||||||
async fn on_invitation(&self) {}
|
async fn on_invitation(&self, _invitation: Invitation) {}
|
||||||
|
|
||||||
async fn on_new_topic(&self, _topic: Option<String>) {}
|
async fn on_new_topic(&self, _topic: Option<String>) {}
|
||||||
async fn on_new_name(&self, _name: Option<String>) {}
|
async fn on_new_name(&self, _name: Option<String>) {}
|
||||||
|
async fn on_new_avatar(&self, _url: Option<Avatar>) {}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
async fn on_membership(&self, _member: RoomMember) {}
|
async fn on_membership(&self, _member: RoomMember) {}
|
||||||
@@ -63,5 +64,6 @@ pub trait MemberMessagingProviderInterface {
|
|||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
|
avatar_url: &Option<AvatarUrl>,
|
||||||
) -> anyhow::Result<Option<Avatar>>;
|
) -> anyhow::Result<Option<Avatar>>;
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,9 @@
|
|||||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
|
collections::HashMap,
|
||||||
|
fmt::{Debug, Formatter},
|
||||||
|
rc::Rc,
|
||||||
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use futures::future::{join, join_all};
|
use futures::future::{join, join_all};
|
||||||
@@ -11,26 +16,58 @@ use super::{
|
|||||||
messaging_interface::{RoomMessagingConsumerInterface, RoomMessagingProviderInterface},
|
messaging_interface::{RoomMessagingConsumerInterface, RoomMessagingProviderInterface},
|
||||||
room_member::RoomMember,
|
room_member::RoomMember,
|
||||||
space::SpaceId,
|
space::SpaceId,
|
||||||
store_interface::RoomStoreProviderInterface,
|
store_interface::{RoomStoreConsumerInterface, RoomStoreProviderInterface},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::infrastructure::services::mozaik_builder::create_mozaik;
|
use crate::infrastructure::services::mozaik_builder::create_mozaik;
|
||||||
|
|
||||||
pub type RoomId = OwnedRoomId;
|
pub type RoomId = OwnedRoomId;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone)]
|
||||||
|
pub struct Invitation {
|
||||||
|
invitee_id: UserId,
|
||||||
|
sender_id: UserId,
|
||||||
|
is_account_user: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Invitation {
|
||||||
|
pub fn new(invitee_id: UserId, sender_id: UserId, is_account_user: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
invitee_id,
|
||||||
|
sender_id,
|
||||||
|
is_account_user,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_account_user(&self) -> bool {
|
||||||
|
self.is_account_user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Invitation {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
|
f.debug_tuple("Invitation")
|
||||||
|
.field(&self.invitee_id)
|
||||||
|
.field(&self.sender_id)
|
||||||
|
.field(&self.is_account_user)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Room {
|
pub struct Room {
|
||||||
id: RoomId,
|
id: RoomId,
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
spaces: Vec<SpaceId>,
|
|
||||||
|
|
||||||
name: RefCell<Option<String>>,
|
name: RefCell<Option<String>>,
|
||||||
topic: Option<String>,
|
topic: Option<String>,
|
||||||
is_direct: Option<bool>,
|
is_direct: Option<bool>,
|
||||||
state: Option<MatrixRoomState>,
|
state: Option<MatrixRoomState>,
|
||||||
avatar: RefCell<Option<Avatar>>,
|
avatar: RefCell<Option<Avatar>>,
|
||||||
|
|
||||||
|
invitations: RefCell<HashMap<UserId, Invitation>>,
|
||||||
members: RefCell<HashMap<UserId, RoomMember>>,
|
members: RefCell<HashMap<UserId, RoomMember>>,
|
||||||
|
|
||||||
|
spaces: Vec<SpaceId>,
|
||||||
|
|
||||||
messaging_provider: Option<Rc<dyn RoomMessagingProviderInterface>>,
|
messaging_provider: Option<Rc<dyn RoomMessagingProviderInterface>>,
|
||||||
store: RefCell<Option<Rc<dyn RoomStoreProviderInterface>>>,
|
store: RefCell<Option<Rc<dyn RoomStoreProviderInterface>>>,
|
||||||
}
|
}
|
||||||
@@ -53,14 +90,17 @@ impl Room {
|
|||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
|
|
||||||
spaces,
|
|
||||||
name: RefCell::new(name),
|
name: RefCell::new(name),
|
||||||
topic,
|
topic,
|
||||||
is_direct,
|
is_direct,
|
||||||
state,
|
state,
|
||||||
avatar: RefCell::new(None),
|
avatar: RefCell::new(None),
|
||||||
|
|
||||||
|
invitations: RefCell::new(HashMap::new()),
|
||||||
members: RefCell::new(HashMap::new()),
|
members: RefCell::new(HashMap::new()),
|
||||||
|
|
||||||
|
spaces,
|
||||||
|
|
||||||
messaging_provider: None,
|
messaging_provider: None,
|
||||||
store: RefCell::new(None),
|
store: RefCell::new(None),
|
||||||
}
|
}
|
||||||
@@ -110,11 +150,17 @@ impl Room {
|
|||||||
self.state.map(|state| state == MatrixRoomState::Invited)
|
self.state.map(|state| state == MatrixRoomState::Invited)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
fn add_invitation(&self, invitation: Invitation) {
|
||||||
fn add_member(&self, member: RoomMember) {
|
self.members.borrow_mut().remove(&invitation.invitee_id);
|
||||||
self.members
|
|
||||||
|
self.invitations
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.insert(member.id().clone(), member);
|
.insert(invitation.invitee_id.clone(), invitation.clone());
|
||||||
|
|
||||||
|
if let Some(store) = self.store.borrow().as_ref() {
|
||||||
|
store.on_invitation(invitation);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_avatar(&self) -> Option<Avatar> {
|
pub async fn get_avatar(&self) -> Option<Avatar> {
|
||||||
@@ -194,8 +240,8 @@ impl Room {
|
|||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
impl RoomMessagingConsumerInterface for Room {
|
impl RoomMessagingConsumerInterface for Room {
|
||||||
async fn on_invitation(&self) {
|
async fn on_invitation(&self, invitation: Invitation) {
|
||||||
trace!("Room::on_invitation");
|
self.add_invitation(invitation);
|
||||||
}
|
}
|
||||||
async fn on_membership(&self, member: RoomMember) {
|
async fn on_membership(&self, member: RoomMember) {
|
||||||
trace!("Room::on_membership({:?})", member);
|
trace!("Room::on_membership({:?})", member);
|
||||||
|
@@ -9,20 +9,22 @@ use dioxus::prelude::Task;
|
|||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
config::SyncSettings,
|
config::SyncSettings,
|
||||||
event_handler::Ctx,
|
event_handler::Ctx,
|
||||||
media::{MediaFormat, MediaThumbnailSize},
|
media::{MediaFormat, MediaRequest, MediaThumbnailSize},
|
||||||
room::{Room, RoomMember},
|
room::{ParentSpace, Room, RoomMember},
|
||||||
ruma::{
|
ruma::{
|
||||||
api::client::media::get_content_thumbnail::v3::Method,
|
api::client::media::get_content_thumbnail::v3::Method,
|
||||||
events::{
|
events::{
|
||||||
room::{
|
room::{
|
||||||
member::{
|
avatar::{RoomAvatarEventContent, StrippedRoomAvatarEvent},
|
||||||
OriginalSyncRoomMemberEvent, RoomMemberEventContent, StrippedRoomMemberEvent,
|
create::{RoomCreateEventContent, StrippedRoomCreateEvent},
|
||||||
},
|
member::{MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent},
|
||||||
topic::RoomTopicEventContent,
|
name::{RoomNameEventContent, StrippedRoomNameEvent},
|
||||||
|
topic::{RoomTopicEventContent, StrippedRoomTopicEvent},
|
||||||
|
MediaSource,
|
||||||
},
|
},
|
||||||
SyncStateEvent,
|
SyncStateEvent,
|
||||||
},
|
},
|
||||||
uint, OwnedRoomId, RoomId, UserId,
|
uint, OwnedMxcUri, OwnedRoomId, OwnedUserId, RoomId, UserId,
|
||||||
},
|
},
|
||||||
Client as MatrixClient, RoomMemberships, RoomState,
|
Client as MatrixClient, RoomMemberships, RoomState,
|
||||||
};
|
};
|
||||||
@@ -68,21 +70,29 @@ impl Senders {
|
|||||||
room_senders.contains_key(room_id)
|
room_senders.contains_key(room_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send(&self, room_id: &RoomId, event: RoomEvent) -> Result<usize, SendError<RoomEvent>> {
|
fn send(&self, room_id: &RoomId, event: RoomEvent) -> Result<(), SendError<RoomEvent>> {
|
||||||
let room_senders = self.room_events_senders.lock().unwrap();
|
let room_senders = self.room_events_senders.lock().unwrap();
|
||||||
|
|
||||||
if let Some(room_sender) = room_senders.get(room_id) {
|
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 {
|
} else {
|
||||||
error!("No sender found for \"{}\" room id", room_id);
|
warn!("No sender found for {room_id} room");
|
||||||
Ok(0)
|
// TODO: Return error
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_room(&self, room_id: &OwnedRoomId) -> Option<RoomEventsReceiver> {
|
fn add_room(&self, room_id: &OwnedRoomId) -> Option<RoomEventsReceiver> {
|
||||||
let mut senders = self.room_events_senders.lock().unwrap();
|
let mut senders = self.room_events_senders.lock().unwrap();
|
||||||
if !senders.contains_key(room_id) {
|
if !senders.contains_key(room_id) {
|
||||||
let (room_sender, room_receiver) = broadcast::channel(32);
|
let (room_sender, room_receiver) = broadcast::channel(32);
|
||||||
|
|
||||||
senders.insert(room_id.clone(), room_sender);
|
senders.insert(room_id.clone(), room_sender);
|
||||||
|
debug!("Create sender for {room_id} room");
|
||||||
|
|
||||||
Some(RoomEventsReceiver::new(room_receiver))
|
Some(RoomEventsReceiver::new(room_receiver))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -109,45 +119,43 @@ impl Client {
|
|||||||
|
|
||||||
async fn create_space(
|
async fn create_space(
|
||||||
senders: &Ctx<Senders>,
|
senders: &Ctx<Senders>,
|
||||||
room_id: OwnedRoomId,
|
room_id: &OwnedRoomId,
|
||||||
room: Option<&Room>,
|
room: Option<&Room>,
|
||||||
) -> anyhow::Result<(), SendError<AccountEvent>> {
|
) -> anyhow::Result<(), SendError<AccountEvent>> {
|
||||||
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) {
|
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::<bool>();
|
let (reply, mut response) = oneshot::<bool>();
|
||||||
|
|
||||||
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) {
|
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);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're expecting a response indicating that the client is able to compute the next RoomEvent
|
// We're expecting a response indicating that the client is able to compute the next RoomEvent
|
||||||
response.recv().await;
|
response.recv().await;
|
||||||
} else {
|
|
||||||
let events = vec![RoomEvent::NewTopic(topic), RoomEvent::NewName(name)];
|
let events = vec![RoomEvent::NewTopic(topic), RoomEvent::NewName(name)];
|
||||||
|
|
||||||
for event in events {
|
for event in events {
|
||||||
if let Err(err) = senders.send(&room_id, event.clone()) {
|
if let Err(_err) = senders.send(&room_id, event.clone()) {
|
||||||
error!(
|
// TODO: Return an error
|
||||||
"Unable to publish the {:?} event to the \"{}\" room: {}",
|
|
||||||
event, room_id, err
|
|
||||||
);
|
|
||||||
// return Err(err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,24 +171,25 @@ impl Client {
|
|||||||
let is_direct = match room.is_direct().await {
|
let is_direct = match room.is_direct().await {
|
||||||
Ok(is_direct) => Some(is_direct),
|
Ok(is_direct) => Some(is_direct),
|
||||||
Err(err) => {
|
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
|
None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parents = vec![];
|
let mut parents = vec![];
|
||||||
// TODO: Remove unwrap
|
|
||||||
let mut spaces = room.parent_spaces().await.unwrap();
|
if let Ok(mut spaces) = room.parent_spaces().await {
|
||||||
while let Some(parent) = spaces.next().await {
|
while let Some(parent) = spaces.next().await {
|
||||||
match parent {
|
match parent {
|
||||||
Ok(parent) => match parent {
|
Ok(parent) => match parent {
|
||||||
matrix_sdk::room::ParentSpace::Reciprocal(parent) => {
|
ParentSpace::Reciprocal(parent) => {
|
||||||
parents.push(parent.room_id().to_owned());
|
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) {
|
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);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,255 +222,283 @@ impl Client {
|
|||||||
let room_id = room.room_id().to_owned();
|
let room_id = room.room_id().to_owned();
|
||||||
|
|
||||||
if room.is_space() {
|
if room.is_space() {
|
||||||
Self::create_space(senders, room_id, Some(room)).await
|
Self::create_space(senders, &room_id, Some(room)).await
|
||||||
} else {
|
} else {
|
||||||
let ret = Self::create_room(senders, room).await;
|
|
||||||
|
|
||||||
let mut parents = vec![];
|
let mut parents = vec![];
|
||||||
// TODO: Remove unwrap
|
|
||||||
let mut spaces = room.parent_spaces().await.unwrap();
|
if let Ok(mut spaces) = room.parent_spaces().await {
|
||||||
while let Some(parent) = spaces.next().await {
|
while let Some(parent) = spaces.next().await {
|
||||||
match parent {
|
match parent {
|
||||||
Ok(parent) => match parent {
|
Ok(parent) => match parent {
|
||||||
matrix_sdk::room::ParentSpace::Reciprocal(parent) => {
|
ParentSpace::Reciprocal(parent) => {
|
||||||
parents.push(parent.room_id().to_owned());
|
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 {
|
for parent in parents {
|
||||||
// Create a minimal space to make the relation consistent... its content will be sync later.
|
// Create a minimal space to make the relation consistent... its content will be sync later.
|
||||||
if !senders.contains(&parent) {
|
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());
|
let event = RoomEvent::NewChild(room_id.clone());
|
||||||
if let Err(err) = senders.send(parent.as_ref(), event.clone()) {
|
if let Err(_err) = senders.send(&parent, event) {
|
||||||
error!(
|
// TODO: Return an error
|
||||||
"Unable to send the {:?} event to the \"{}\": {:?}",
|
|
||||||
event, parent, err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
Self::create_room(senders, room).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// async fn on_sync_typing_event(_ev: SyncTypingEvent, room: Room) {
|
async fn on_stripped_room_create_event(
|
||||||
// debug!("== on_sync_typing_event ==");
|
_ev: StrippedRoomCreateEvent,
|
||||||
// let room_id = room.room_id().to_owned();
|
room: Room,
|
||||||
// dbg!(room_id);
|
senders: Ctx<Senders>,
|
||||||
// }
|
) {
|
||||||
|
let _ = Self::add_room(&senders, &room).await;
|
||||||
|
}
|
||||||
|
|
||||||
// async fn on_presence_event(_ev: PresenceEvent) {
|
// SyncStateEvent: A possibly-redacted state event without a room_id.
|
||||||
// debug!("== on_presence_event ==");
|
async fn on_sync_room_create_event(
|
||||||
// dbg!(_ev);
|
_ev: SyncStateEvent<RoomCreateEventContent>,
|
||||||
// }
|
room: Room,
|
||||||
|
senders: Ctx<Senders>,
|
||||||
|
) {
|
||||||
|
let _ = Self::add_room(&senders, &room).await;
|
||||||
|
}
|
||||||
|
|
||||||
// async fn on_sync_state_event(ev: SyncStateEvent<RoomNameEventContent>, _room: Room) {
|
fn on_invite_room_member_event(
|
||||||
// error!("== on_sync_state_event ==");
|
user_id: OwnedUserId,
|
||||||
// if let SyncStateEvent::Original(ev) = ev {
|
inviter_id: OwnedUserId,
|
||||||
// dbg!(ev);
|
room: &Room,
|
||||||
// }
|
matrix_client: &MatrixClient,
|
||||||
// }
|
senders: &Ctx<Senders>,
|
||||||
|
) {
|
||||||
|
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(
|
debug!(
|
||||||
// ev: OriginalSyncRoomMessageEvent,
|
"{} (account user: {is_account_user}) invited by {} to join the {} room",
|
||||||
// _room: Room,
|
&user_id, &inviter_id, &room_id
|
||||||
// _senders: Ctx<Senders>,
|
);
|
||||||
// ) {
|
|
||||||
// error!("== on_original_sync_room_message_event ==");
|
|
||||||
// error!("ev={:?}", ev.content);
|
|
||||||
|
|
||||||
|
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<String>,
|
||||||
|
avatar_url: Option<OwnedMxcUri>,
|
||||||
|
room: &Room,
|
||||||
|
matrix_client: &MatrixClient,
|
||||||
|
senders: &Ctx<Senders>,
|
||||||
|
) {
|
||||||
|
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(
|
async fn on_stripped_room_member_event(
|
||||||
ev: StrippedRoomMemberEvent,
|
ev: StrippedRoomMemberEvent,
|
||||||
matrix_client: MatrixClient,
|
matrix_client: MatrixClient,
|
||||||
room: Room,
|
room: Room,
|
||||||
senders: Ctx<Senders>,
|
senders: Ctx<Senders>,
|
||||||
) {
|
) {
|
||||||
error!("*** on_stripped_room_member_event ***");
|
match room.state() {
|
||||||
// error!("ev={:?}", ev);
|
RoomState::Invited => {
|
||||||
|
let user_id = &ev.state_key;
|
||||||
|
|
||||||
if ev.state_key == matrix_client.user_id().unwrap()
|
match ev.content.membership {
|
||||||
&& room.state() == RoomState::Invited
|
MembershipState::Invite => Self::on_invite_room_member_event(
|
||||||
&& Self::add_room(&senders, &room).await.is_ok()
|
user_id.clone(),
|
||||||
{
|
ev.sender,
|
||||||
let room_id = room.room_id();
|
&room,
|
||||||
|
&matrix_client,
|
||||||
let event = RoomEvent::Invitation();
|
&senders,
|
||||||
if let Err(err) = senders.send(room_id, event) {
|
),
|
||||||
error!(
|
MembershipState::Join => Self::on_join_room_member_event(
|
||||||
"Unable to publish the room \"{}\" invitation: {}",
|
ev.sender,
|
||||||
room.room_id(),
|
ev.content.displayname,
|
||||||
err
|
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<RoomMemberEventContent>,
|
||||||
|
matrix_client: MatrixClient,
|
||||||
|
room: Room,
|
||||||
|
senders: Ctx<Senders>,
|
||||||
|
) {
|
||||||
|
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<Senders>) {
|
||||||
|
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<Senders>,
|
||||||
|
) {
|
||||||
|
Self::on_room_avatar_event(&room, &senders).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_sync_room_avatar_event(
|
||||||
|
ev: SyncStateEvent<RoomAvatarEventContent>,
|
||||||
|
room: Room,
|
||||||
|
senders: Ctx<Senders>,
|
||||||
|
) {
|
||||||
|
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<String>, room: &Room, senders: &Ctx<Senders>) {
|
||||||
|
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<Senders>,
|
||||||
|
) {
|
||||||
|
Self::on_room_name_event(ev.content.name, &room, &senders);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_sync_room_name_event(
|
||||||
|
ev: SyncStateEvent<RoomNameEventContent>,
|
||||||
|
room: Room,
|
||||||
|
senders: Ctx<Senders>,
|
||||||
|
) {
|
||||||
|
if let SyncStateEvent::Original(ev) = ev {
|
||||||
|
Self::on_room_name_event(Some(ev.content.name), &room, &senders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_room_topic_event(topic: Option<String>, room: &Room, senders: &Ctx<Senders>) {
|
||||||
|
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<Senders>,
|
||||||
|
) {
|
||||||
|
Self::on_room_topic_event(ev.content.topic, &room, &senders);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_sync_room_topic_event(
|
||||||
ev: SyncStateEvent<RoomTopicEventContent>,
|
ev: SyncStateEvent<RoomTopicEventContent>,
|
||||||
room: Room,
|
room: Room,
|
||||||
senders: Ctx<Senders>,
|
senders: Ctx<Senders>,
|
||||||
) {
|
) {
|
||||||
error!("*** on_room_topic_event ***");
|
|
||||||
// error!("ev={:?}", ev);
|
|
||||||
|
|
||||||
if let SyncStateEvent::Original(ev) = ev {
|
if let SyncStateEvent::Original(ev) = ev {
|
||||||
let _ = Self::add_room(&senders, &room).await;
|
Self::on_room_topic_event(Some(ev.content.topic), &room, &senders);
|
||||||
|
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_room_member_event(
|
|
||||||
ev: SyncStateEvent<RoomMemberEventContent>,
|
|
||||||
room: Room,
|
|
||||||
senders: Ctx<Senders>,
|
|
||||||
) {
|
|
||||||
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<RoomMessageEventContent>,
|
|
||||||
// _room: Room,
|
|
||||||
// _client: MatrixClient,
|
|
||||||
// ) {
|
|
||||||
// debug!("== on_sync_message_like_room_message_event ==");
|
|
||||||
// dbg!(ev);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async fn on_sync_message_like_reaction_event(
|
|
||||||
// ev: SyncMessageLikeEvent<ReactionEventContent>,
|
|
||||||
// _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<Senders>) {
|
|
||||||
// debug!("== on_room_event({}) ==", ev.)
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub async fn spawn(homeserver_url: String) -> (Requester, Receiver<AccountEvent>) {
|
pub async fn spawn(homeserver_url: String) -> (Requester, Receiver<AccountEvent>) {
|
||||||
let matrix_client = Arc::new(
|
let matrix_client = Arc::new(
|
||||||
MatrixClient::builder()
|
MatrixClient::builder()
|
||||||
@@ -494,28 +526,20 @@ impl Client {
|
|||||||
// TODO: Remove clone?
|
// TODO: Remove clone?
|
||||||
client.add_event_handler_context(self.senders.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_stripped_room_member_event);
|
||||||
let _ = client.add_event_handler(Client::on_room_topic_event);
|
let _ = client.add_event_handler(Client::on_sync_room_member_event);
|
||||||
let _ = client.add_event_handler(Client::on_room_member_event);
|
|
||||||
|
|
||||||
// let _ = client.add_event_handler(Client::on_sync_typing_event);
|
let _ = client.add_event_handler(Client::on_stripped_room_avatar_event);
|
||||||
// let _ = client.add_event_handler(Client::on_presence_event);
|
let _ = client.add_event_handler(Client::on_sync_room_avatar_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_sync_message_like_room_message_event);
|
let _ = client.add_event_handler(Client::on_stripped_room_name_event);
|
||||||
// let _ = client.add_event_handler(Client::on_sync_message_like_reaction_event);
|
let _ = client.add_event_handler(Client::on_sync_room_name_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_stripped_room_topic_event);
|
||||||
|
let _ = client.add_event_handler(Client::on_sync_room_topic_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);
|
|
||||||
|
|
||||||
self.initialized = true;
|
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<Vec<u8>> {
|
||||||
|
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(
|
async fn get_room_member_avatar(
|
||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
|
avatar_url: &Option<OwnedMxcUri>,
|
||||||
) -> anyhow::Result<Option<Vec<u8>>> {
|
) -> anyhow::Result<Option<Vec<u8>>> {
|
||||||
let client = self.client.as_ref().unwrap();
|
let client = self.client.as_ref().unwrap();
|
||||||
|
|
||||||
if let Some(room) = client.get_room(room_id) {
|
if let Some(room) = client.get_room(room_id) {
|
||||||
if let Ok(Some(room_member)) = room.get_member(user_id).await {
|
// TODO: Check if we can get member before fetching the data and received an error...
|
||||||
let res = match room_member
|
|
||||||
.avatar(MediaFormat::Thumbnail(MediaThumbnailSize {
|
match room.get_member(user_id).await {
|
||||||
method: Method::Scale,
|
Ok(room_member) => match room_member {
|
||||||
width: uint!(256),
|
Some(room_member) => {
|
||||||
height: uint!(256),
|
let res = match room_member
|
||||||
}))
|
.avatar(MediaFormat::Thumbnail(MediaThumbnailSize {
|
||||||
.await
|
method: Method::Scale,
|
||||||
{
|
width: uint!(256),
|
||||||
Ok(avatar) => Ok(avatar),
|
height: uint!(256),
|
||||||
Err(err) => Err(err.into()),
|
}))
|
||||||
};
|
.await
|
||||||
return res;
|
{
|
||||||
|
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)
|
Ok(None)
|
||||||
@@ -691,9 +752,12 @@ impl Client {
|
|||||||
reply.send(self.get_room_members(&id).await).await;
|
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
|
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;
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
use std::{collections::HashMap, rc::Rc};
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use futures::future::join_all;
|
|
||||||
use tokio::{
|
use tokio::{
|
||||||
select,
|
select,
|
||||||
sync::{broadcast::Receiver, mpsc::UnboundedSender},
|
sync::{broadcast::Receiver, mpsc::UnboundedSender},
|
||||||
@@ -23,8 +22,8 @@ use crate::{
|
|||||||
RoomMessagingProviderInterface, SpaceMessagingConsumerInterface,
|
RoomMessagingProviderInterface, SpaceMessagingConsumerInterface,
|
||||||
SpaceMessagingProviderInterface,
|
SpaceMessagingProviderInterface,
|
||||||
},
|
},
|
||||||
room::{Room, RoomId},
|
room::{Invitation, Room, RoomId},
|
||||||
room_member::RoomMember,
|
room_member::{AvatarUrl, RoomMember},
|
||||||
space::Space,
|
space::Space,
|
||||||
},
|
},
|
||||||
utils::oneshot,
|
utils::oneshot,
|
||||||
@@ -182,19 +181,29 @@ impl AccountMessagingProviderInterface for Requester {
|
|||||||
if let Ok(room_event) = room_event {
|
if let Ok(room_event) = room_event {
|
||||||
if let Some(consumer) = room_events_consumers.get(&room_id) {
|
if let Some(consumer) = room_events_consumers.get(&room_id) {
|
||||||
match room_event {
|
match room_event {
|
||||||
RoomEvent::Invitation() => {
|
RoomEvent::Invitation(user_id, sender_id, is_account_user) => {
|
||||||
consumer.on_invitation().await;
|
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) => {
|
RoomEvent::NewTopic(topic) => {
|
||||||
consumer.on_new_topic(topic).await;
|
consumer.on_new_topic(topic).await;
|
||||||
},
|
},
|
||||||
RoomEvent::NewName(name) => {
|
RoomEvent::NewName(name) => {
|
||||||
consumer.on_new_name(name).await;
|
consumer.on_new_name(name).await;
|
||||||
},
|
},
|
||||||
|
RoomEvent::NewAvatar(avatar) => {
|
||||||
|
consumer.on_new_avatar(avatar).await;
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -256,12 +265,14 @@ impl MemberMessagingProviderInterface for Requester {
|
|||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
|
avatar_url: &Option<AvatarUrl>,
|
||||||
) -> anyhow::Result<Option<Avatar>> {
|
) -> anyhow::Result<Option<Avatar>> {
|
||||||
request_to_worker!(
|
request_to_worker!(
|
||||||
self,
|
self,
|
||||||
WorkerTask::GetRoomMemberAvatar,
|
WorkerTask::GetRoomMemberAvatar,
|
||||||
room_id.clone(),
|
room_id.clone(),
|
||||||
user_id.clone()
|
user_id.clone(),
|
||||||
|
avatar_url.clone()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,34 +1,43 @@
|
|||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
use matrix_sdk::ruma::{OwnedRoomId, OwnedUserId};
|
use matrix_sdk::ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId};
|
||||||
use tokio::sync::broadcast::Receiver;
|
use tokio::sync::broadcast::Receiver;
|
||||||
|
|
||||||
|
use crate::domain::model::common::Avatar;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum RoomEvent {
|
pub enum RoomEvent {
|
||||||
Invitation(),
|
Invitation(OwnedUserId, OwnedUserId, bool),
|
||||||
|
Join(OwnedUserId, Option<String>, Option<OwnedMxcUri>, bool),
|
||||||
#[allow(dead_code)]
|
|
||||||
Membership(OwnedUserId, bool),
|
|
||||||
|
|
||||||
NewTopic(Option<String>),
|
NewTopic(Option<String>),
|
||||||
NewName(Option<String>),
|
NewName(Option<String>),
|
||||||
|
NewAvatar(Option<Avatar>),
|
||||||
NewChild(OwnedRoomId),
|
NewChild(OwnedRoomId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for RoomEvent {
|
impl Debug for RoomEvent {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::Invitation() => f
|
Self::Invitation(invitee_id, sender_id, is_account_user) => f
|
||||||
.debug_tuple("RoomEvent::Invitation")
|
.debug_tuple("RoomEvent::Invitation")
|
||||||
.field(&format_args!("_"))
|
.field(invitee_id)
|
||||||
|
.field(sender_id)
|
||||||
|
.field(is_account_user)
|
||||||
.finish(),
|
.finish(),
|
||||||
Self::Membership(user_id, is_account_user) => f
|
Self::Join(user_id, user_name, avatar_url, is_account_user) => f
|
||||||
.debug_tuple("RoomEvent::Membership")
|
.debug_tuple("RoomEvent::Join")
|
||||||
.field(user_id)
|
.field(user_id)
|
||||||
|
.field(user_name)
|
||||||
|
.field(avatar_url)
|
||||||
.field(is_account_user)
|
.field(is_account_user)
|
||||||
.finish(),
|
.finish(),
|
||||||
Self::NewTopic(topic) => f.debug_tuple("RoomEvent::NewTopic").field(topic).finish(),
|
Self::NewTopic(topic) => f.debug_tuple("RoomEvent::NewTopic").field(topic).finish(),
|
||||||
Self::NewName(name) => f.debug_tuple("RoomEvent::NewName").field(name).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
|
Self::NewChild(room_id) => f
|
||||||
.debug_tuple("SpaceEvent::NewChild")
|
.debug_tuple("SpaceEvent::NewChild")
|
||||||
.field(room_id)
|
.field(room_id)
|
||||||
|
@@ -2,7 +2,7 @@ use std::fmt::{Debug, Formatter};
|
|||||||
|
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
room::RoomMember,
|
room::RoomMember,
|
||||||
ruma::{OwnedRoomId, OwnedUserId},
|
ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::Sender;
|
use crate::utils::Sender;
|
||||||
@@ -25,6 +25,7 @@ pub enum WorkerTask {
|
|||||||
GetRoomMemberAvatar(
|
GetRoomMemberAvatar(
|
||||||
OwnedRoomId,
|
OwnedRoomId,
|
||||||
OwnedUserId,
|
OwnedUserId,
|
||||||
|
Option<OwnedMxcUri>,
|
||||||
Sender<anyhow::Result<Option<Vec<u8>>>>,
|
Sender<anyhow::Result<Option<Vec<u8>>>>,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@@ -64,10 +65,11 @@ impl Debug for WorkerTask {
|
|||||||
.field(id)
|
.field(id)
|
||||||
.finish(),
|
.finish(),
|
||||||
|
|
||||||
WorkerTask::GetRoomMemberAvatar(room_id, user_id, _) => f
|
WorkerTask::GetRoomMemberAvatar(room_id, user_id, avatar_url, _) => f
|
||||||
.debug_tuple("WorkerTask::GetRoomMemberAvatar")
|
.debug_tuple("WorkerTask::GetRoomMemberAvatar")
|
||||||
.field(room_id)
|
.field(room_id)
|
||||||
.field(user_id)
|
.field(user_id)
|
||||||
|
.field(avatar_url)
|
||||||
.finish(),
|
.finish(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user