async_client/event_emitter: use RoomState to differentiate joined, invited and left rooms when emitting
parent
e0400bd4e6
commit
8afac39611
|
@ -1,12 +1,10 @@
|
|||
use std::sync::Arc;
|
||||
use std::{env, process::exit};
|
||||
|
||||
use matrix_sdk::{
|
||||
self,
|
||||
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||
AsyncClient, AsyncClientConfig, EventEmitter, JsonStore, Room, SyncSettings,
|
||||
AsyncClient, AsyncClientConfig, EventEmitter, JsonStore, RoomState, SyncSettings,
|
||||
};
|
||||
use tokio::sync::RwLock;
|
||||
use url::Url;
|
||||
|
||||
struct CommandBot {
|
||||
|
@ -23,37 +21,39 @@ impl CommandBot {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl EventEmitter for CommandBot {
|
||||
async fn on_room_message(&self, room: Arc<RwLock<Room>>, event: &MessageEvent) {
|
||||
let msg_body = if let MessageEvent {
|
||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||
..
|
||||
} = event
|
||||
{
|
||||
msg_body.clone()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
||||
if let RoomState::Joined(room) = room {
|
||||
let msg_body = if let MessageEvent {
|
||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||
..
|
||||
} = event
|
||||
{
|
||||
msg_body.clone()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
if msg_body.contains("!party") {
|
||||
let content = MessageEventContent::Text(TextMessageEventContent {
|
||||
body: "🎉🎊🥳 let's PARTY!! 🥳🎊🎉".to_string(),
|
||||
format: None,
|
||||
formatted_body: None,
|
||||
relates_to: None,
|
||||
});
|
||||
// we clone here to hold the lock for as little time as possible.
|
||||
let room_id = room.read().await.room_id.clone();
|
||||
if msg_body.contains("!party") {
|
||||
let content = MessageEventContent::Text(TextMessageEventContent {
|
||||
body: "🎉🎊🥳 let's PARTY!! 🥳🎊🎉".to_string(),
|
||||
format: None,
|
||||
formatted_body: None,
|
||||
relates_to: None,
|
||||
});
|
||||
// we clone here to hold the lock for as little time as possible.
|
||||
let room_id = room.read().await.room_id.clone();
|
||||
|
||||
println!("sending");
|
||||
println!("sending");
|
||||
|
||||
self.client
|
||||
// send our message to the room we found the "!party" command in
|
||||
// the last parameter is an optional Uuid which we don't care about.
|
||||
.room_send(&room_id, content, None)
|
||||
.await
|
||||
.unwrap();
|
||||
self.client
|
||||
// send our message to the room we found the "!party" command in
|
||||
// the last parameter is an optional Uuid which we don't care about.
|
||||
.room_send(&room_id, content, None)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
println!("message sent");
|
||||
println!("message sent");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
use std::sync::Arc;
|
||||
use std::{env, process::exit};
|
||||
use url::Url;
|
||||
|
||||
use matrix_sdk::{
|
||||
self,
|
||||
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||
AsyncClient, AsyncClientConfig, EventEmitter, Room, SyncSettings,
|
||||
AsyncClient, AsyncClientConfig, EventEmitter, RoomState, SyncSettings,
|
||||
};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
struct EventCallback;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EventEmitter for EventCallback {
|
||||
async fn on_room_message(&self, room: Arc<RwLock<Room>>, event: &MessageEvent) {
|
||||
if let MessageEvent {
|
||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||
sender,
|
||||
..
|
||||
} = event
|
||||
{
|
||||
let name = {
|
||||
// any reads should be held for the shortest time possible to
|
||||
// avoid dead locks
|
||||
let room = room.read().await;
|
||||
let member = room.members.get(&sender).unwrap();
|
||||
member
|
||||
.display_name
|
||||
.as_ref()
|
||||
.map(ToString::to_string)
|
||||
.unwrap_or(sender.to_string())
|
||||
};
|
||||
println!("{}: {}", name, msg_body);
|
||||
async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
||||
if let RoomState::Joined(room) = room {
|
||||
if let MessageEvent {
|
||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||
sender,
|
||||
..
|
||||
} = event
|
||||
{
|
||||
let name = {
|
||||
// any reads should be held for the shortest time possible to
|
||||
// avoid dead locks
|
||||
let room = room.read().await;
|
||||
let member = room.members.get(&sender).unwrap();
|
||||
member
|
||||
.display_name
|
||||
.as_ref()
|
||||
.map(ToString::to_string)
|
||||
.unwrap_or(sender.to_string())
|
||||
};
|
||||
println!("{}: {}", name, msg_body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ use crate::models::Room;
|
|||
use crate::session::Session;
|
||||
use crate::state::StateStore;
|
||||
use crate::VERSION;
|
||||
use crate::{Error, EventEmitter, Result};
|
||||
use crate::{Error, EventEmitter, Result, RoomStateType};
|
||||
|
||||
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
|
@ -322,6 +322,9 @@ impl AsyncClient {
|
|||
///
|
||||
/// This is a human readable room name.
|
||||
pub async fn get_room_name(&self, room_id: &RoomId) -> Option<String> {
|
||||
// TODO do we want to use the `RoomStateType` enum here or should we have
|
||||
// 3 seperate `room_name` methods. The other option is to remove this and have
|
||||
// the user get a `Room` and use `Room::calculate_name` method?
|
||||
self.base_client
|
||||
.read()
|
||||
.await
|
||||
|
@ -336,13 +339,27 @@ impl AsyncClient {
|
|||
self.base_client.read().await.calculate_room_names().await
|
||||
}
|
||||
|
||||
/// Returns the rooms this client knows about.
|
||||
/// Returns the joined rooms this client knows about.
|
||||
///
|
||||
/// A `HashMap` of room id to `matrix::models::Room`
|
||||
pub async fn get_rooms(&self) -> HashMap<RoomId, Arc<tokio::sync::RwLock<Room>>> {
|
||||
pub async fn get_joined_rooms(&self) -> HashMap<RoomId, Arc<tokio::sync::RwLock<Room>>> {
|
||||
self.base_client.read().await.joined_rooms.clone()
|
||||
}
|
||||
|
||||
/// Returns the invited rooms this client knows about.
|
||||
///
|
||||
/// A `HashMap` of room id to `matrix::models::Room`
|
||||
pub async fn get_invited_rooms(&self) -> HashMap<RoomId, Arc<tokio::sync::RwLock<Room>>> {
|
||||
self.base_client.read().await.invited_rooms.clone()
|
||||
}
|
||||
|
||||
/// Returns the left rooms this client knows about.
|
||||
///
|
||||
/// A `HashMap` of room id to `matrix::models::Room`
|
||||
pub async fn get_left_rooms(&self) -> HashMap<RoomId, Arc<tokio::sync::RwLock<Room>>> {
|
||||
self.base_client.read().await.lefted_rooms.clone()
|
||||
}
|
||||
|
||||
/// This allows `AsyncClient` to manually sync state with the provided `StateStore`.
|
||||
///
|
||||
/// Returns true when a successful `StateStore` sync has completed.
|
||||
|
@ -663,13 +680,12 @@ impl AsyncClient {
|
|||
Ok(response)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
async fn iter_joined_rooms(&self, response: &mut sync_events::Response) -> Result<bool> {
|
||||
let mut updated = false;
|
||||
for (room_id, room) in &mut response.rooms.join {
|
||||
for (room_id, joined_room) in &mut response.rooms.join {
|
||||
let matrix_room = {
|
||||
let mut client = self.base_client.write().await;
|
||||
for event in &room.state.events {
|
||||
for event in &joined_room.state.events {
|
||||
if let Ok(e) = event.deserialize() {
|
||||
if client.receive_joined_state_event(&room_id, &e).await {
|
||||
updated = true;
|
||||
|
@ -677,21 +693,26 @@ impl AsyncClient {
|
|||
}
|
||||
}
|
||||
|
||||
client.get_or_create_room(&room_id).clone()
|
||||
client.get_or_create_joined_room(&room_id).clone()
|
||||
};
|
||||
|
||||
// RoomSummary contains information for calculating room name
|
||||
matrix_room.write().await.set_room_summary(&room.summary);
|
||||
matrix_room
|
||||
.write()
|
||||
.await
|
||||
.set_room_summary(&joined_room.summary);
|
||||
|
||||
// re looping is not ideal here
|
||||
for event in &mut room.state.events {
|
||||
for event in &mut joined_room.state.events {
|
||||
if let Ok(e) = event.deserialize() {
|
||||
let client = self.base_client.read().await;
|
||||
client.emit_state_event(&room_id, &e).await;
|
||||
client
|
||||
.emit_state_event(&room_id, &e, RoomStateType::Joined)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
for mut event in &mut room.timeline.events {
|
||||
for mut event in &mut joined_room.timeline.events {
|
||||
let decrypted_event = {
|
||||
let mut client = self.base_client.write().await;
|
||||
let (decrypt_ev, timeline_update) = client
|
||||
|
@ -709,12 +730,14 @@ impl AsyncClient {
|
|||
|
||||
if let Ok(e) = event.deserialize() {
|
||||
let client = self.base_client.read().await;
|
||||
client.emit_timeline_event(&room_id, &e).await;
|
||||
client
|
||||
.emit_timeline_event(&room_id, &e, RoomStateType::Joined)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
// look at AccountData to further cut down users by collecting ignored users
|
||||
if let Some(account_data) = &room.account_data {
|
||||
if let Some(account_data) = &joined_room.account_data {
|
||||
for account_data in &account_data.events {
|
||||
{
|
||||
if let Ok(e) = account_data.deserialize() {
|
||||
|
@ -722,7 +745,9 @@ impl AsyncClient {
|
|||
if client.receive_account_data_event(&room_id, &e).await {
|
||||
updated = true;
|
||||
}
|
||||
client.emit_account_data_event(room_id, &e).await;
|
||||
client
|
||||
.emit_account_data_event(room_id, &e, RoomStateType::Joined)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -739,12 +764,14 @@ impl AsyncClient {
|
|||
updated = true;
|
||||
}
|
||||
|
||||
client.emit_presence_event(&room_id, &e).await;
|
||||
client
|
||||
.emit_presence_event(&room_id, &e, RoomStateType::Joined)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ephemeral in &mut room.ephemeral.events {
|
||||
for ephemeral in &mut joined_room.ephemeral.events {
|
||||
{
|
||||
if let Ok(e) = ephemeral.deserialize() {
|
||||
let mut client = self.base_client.write().await;
|
||||
|
@ -752,7 +779,9 @@ impl AsyncClient {
|
|||
updated = true;
|
||||
}
|
||||
|
||||
client.emit_ephemeral_event(&room_id, &e).await;
|
||||
client
|
||||
.emit_ephemeral_event(&room_id, &e, RoomStateType::Joined)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -768,16 +797,36 @@ impl AsyncClient {
|
|||
Ok(updated)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
async fn iter_left_rooms(&self, response: &mut sync_events::Response) -> Result<bool> {
|
||||
let mut updated = false;
|
||||
for (room_id, left_room) in &mut response.rooms.leave {
|
||||
let matrix_room = {
|
||||
let mut client = self.base_client.write().await;
|
||||
for event in &left_room.state.events {
|
||||
if let Ok(e) = event.deserialize() {
|
||||
if client.receive_left_state_event(&room_id, &e).await {
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.get_or_create_left_room(&room_id).clone()
|
||||
};
|
||||
|
||||
for event in &mut left_room.state.events {
|
||||
if let Ok(e) = event.deserialize() {
|
||||
let client = self.base_client.read().await;
|
||||
client
|
||||
.emit_state_event(&room_id, &e, RoomStateType::Left)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
for mut event in &mut left_room.timeline.events {
|
||||
let decrypted_event = {
|
||||
let mut client = self.base_client.write().await;
|
||||
|
||||
let (decrypt_ev, timeline_update) = client
|
||||
.receive_joined_timeline_event(room_id, &mut event)
|
||||
.receive_left_timeline_event(room_id, &mut event)
|
||||
.await;
|
||||
if timeline_update {
|
||||
updated = true;
|
||||
|
@ -791,30 +840,23 @@ impl AsyncClient {
|
|||
|
||||
if let Ok(e) = event.deserialize() {
|
||||
let client = self.base_client.read().await;
|
||||
client.emit_timeline_event(&room_id, &e).await;
|
||||
}
|
||||
}
|
||||
|
||||
// re looping is not ideal here
|
||||
for event in &mut left_room.state.events {
|
||||
if let Ok(e) = event.deserialize() {
|
||||
let client = self.base_client.read().await;
|
||||
client.emit_state_event(&room_id, &e).await;
|
||||
client
|
||||
.emit_timeline_event(&room_id, &e, RoomStateType::Left)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
if updated {
|
||||
if let Some(store) = self.base_client.read().await.state_store.as_ref() {
|
||||
let mut client = self.base_client.write().await;
|
||||
let room = client.get_or_create_room(&room_id).clone();
|
||||
store.store_room_state(room.read().await.deref()).await?;
|
||||
store
|
||||
.store_room_state(matrix_room.read().await.deref())
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(updated)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
async fn iter_invited_rooms(&self, response: &sync_events::Response) -> Result<bool> {
|
||||
let mut updated = false;
|
||||
for (room_id, invited_room) in &response.rooms.invite {
|
||||
|
@ -828,14 +870,15 @@ impl AsyncClient {
|
|||
}
|
||||
}
|
||||
|
||||
client.get_or_create_room(&room_id).clone()
|
||||
client.get_or_create_left_room(&room_id).clone()
|
||||
};
|
||||
|
||||
// re looping is not ideal here
|
||||
for event in &invited_room.invite_state.events {
|
||||
if let Ok(e) = event.deserialize() {
|
||||
let client = self.base_client.read().await;
|
||||
client.emit_stripped_state_event(&room_id, &e).await;
|
||||
client
|
||||
.emit_stripped_state_event(&room_id, &e, RoomStateType::Invited)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,58 @@ use matrix_sdk_crypto::{OlmMachine, OneTimeKeys};
|
|||
|
||||
pub type Token = String;
|
||||
|
||||
/// Signals to the `BaseClient` which `RoomState` to send to `EventEmitter`.
|
||||
pub enum RoomStateType {
|
||||
/// Represents a joined room, the `joined_rooms` HashMap will be used.
|
||||
Joined,
|
||||
/// Represents a left room, the `left_rooms` HashMap will be used.
|
||||
Left,
|
||||
/// Represents an invited room, the `invited_rooms` HashMap will be used.
|
||||
Invited,
|
||||
}
|
||||
|
||||
/// An enum that represents the state of the given `Room`.
|
||||
///
|
||||
/// If the event came from the `join`, `invite` or `leave` rooms map from the server
|
||||
/// the variant that holds the corresponding room is used.
|
||||
pub enum RoomState {
|
||||
/// A room from the `join` section of a sync response.
|
||||
Joined(Arc<RwLock<Room>>),
|
||||
/// A room from the `leave` section of a sync response.
|
||||
Left(Arc<RwLock<Room>>),
|
||||
/// A room from the `invite` section of a sync response.
|
||||
Invited(Arc<RwLock<Room>>),
|
||||
}
|
||||
|
||||
macro_rules! emit_event {
|
||||
($this:ident, $id:ident, $event:ident, $state:ident, $($variant:path => $meth:ident,)*) => {
|
||||
match &$event {
|
||||
$($variant(ev) => {
|
||||
if let Some(ee) = &$this.event_emitter {
|
||||
match $state {
|
||||
RoomStateType::Joined => {
|
||||
if let Some(room) = $this.get_joined_room(&$id) {
|
||||
ee.$meth(RoomState::Joined(Arc::clone(&room)), &ev).await;
|
||||
}
|
||||
}
|
||||
RoomStateType::Invited => {
|
||||
if let Some(room) = $this.get_invited_room(&$id) {
|
||||
ee.$meth(RoomState::Invited(Arc::clone(&room)), &ev).await;
|
||||
}
|
||||
}
|
||||
RoomStateType::Left => {
|
||||
if let Some(room) = $this.get_left_room(&$id) {
|
||||
ee.$meth(RoomState::Left(Arc::clone(&room)), &ev).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})*
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A no IO Client implementation.
|
||||
///
|
||||
/// This Client is a state machine that receives responses and events and
|
||||
|
@ -70,6 +122,10 @@ pub struct Client {
|
|||
pub sync_token: Option<Token>,
|
||||
/// A map of the rooms our user is joined in.
|
||||
pub joined_rooms: HashMap<RoomId, Arc<RwLock<Room>>>,
|
||||
/// A map of the rooms our user is invited to.
|
||||
pub invited_rooms: HashMap<RoomId, Arc<RwLock<Room>>>,
|
||||
/// A map of the rooms our user has left.
|
||||
pub lefted_rooms: HashMap<RoomId, Arc<RwLock<Room>>>,
|
||||
/// A list of ignored users.
|
||||
pub ignored_users: Vec<UserId>,
|
||||
/// The push ruleset for the logged in user.
|
||||
|
@ -120,6 +176,8 @@ impl Client {
|
|||
session,
|
||||
sync_token: None,
|
||||
joined_rooms: HashMap::new(),
|
||||
invited_rooms: HashMap::new(),
|
||||
lefted_rooms: HashMap::new(),
|
||||
ignored_users: Vec::new(),
|
||||
push_ruleset: None,
|
||||
event_emitter: None,
|
||||
|
@ -224,7 +282,7 @@ impl Client {
|
|||
res
|
||||
}
|
||||
|
||||
pub(crate) fn get_or_create_room(&mut self, room_id: &RoomId) -> &mut Arc<RwLock<Room>> {
|
||||
pub(crate) fn get_or_create_joined_room(&mut self, room_id: &RoomId) -> &mut Arc<RwLock<Room>> {
|
||||
#[allow(clippy::or_fun_call)]
|
||||
self.joined_rooms
|
||||
.entry(room_id.clone())
|
||||
|
@ -238,10 +296,49 @@ impl Client {
|
|||
))))
|
||||
}
|
||||
|
||||
pub(crate) fn get_room(&self, room_id: &RoomId) -> Option<&Arc<RwLock<Room>>> {
|
||||
pub(crate) fn get_joined_room(&self, room_id: &RoomId) -> Option<&Arc<RwLock<Room>>> {
|
||||
self.joined_rooms.get(room_id)
|
||||
}
|
||||
|
||||
pub(crate) fn get_or_create_invited_room(
|
||||
&mut self,
|
||||
room_id: &RoomId,
|
||||
) -> &mut Arc<RwLock<Room>> {
|
||||
#[allow(clippy::or_fun_call)]
|
||||
self.invited_rooms
|
||||
.entry(room_id.clone())
|
||||
.or_insert(Arc::new(RwLock::new(Room::new(
|
||||
room_id,
|
||||
&self
|
||||
.session
|
||||
.as_ref()
|
||||
.expect("Receiving events while not being logged in")
|
||||
.user_id,
|
||||
))))
|
||||
}
|
||||
|
||||
pub(crate) fn get_invited_room(&self, room_id: &RoomId) -> Option<&Arc<RwLock<Room>>> {
|
||||
self.invited_rooms.get(room_id)
|
||||
}
|
||||
|
||||
pub(crate) fn get_or_create_left_room(&mut self, room_id: &RoomId) -> &mut Arc<RwLock<Room>> {
|
||||
#[allow(clippy::or_fun_call)]
|
||||
self.lefted_rooms
|
||||
.entry(room_id.clone())
|
||||
.or_insert(Arc::new(RwLock::new(Room::new(
|
||||
room_id,
|
||||
&self
|
||||
.session
|
||||
.as_ref()
|
||||
.expect("Receiving events while not being logged in")
|
||||
.user_id,
|
||||
))))
|
||||
}
|
||||
|
||||
pub(crate) fn get_left_room(&self, room_id: &RoomId) -> Option<&Arc<RwLock<Room>>> {
|
||||
self.lefted_rooms.get(room_id)
|
||||
}
|
||||
|
||||
/// Handle a m.ignored_user_list event, updating the room state if necessary.
|
||||
///
|
||||
/// Returns true if the room name changed, false otherwise.
|
||||
|
@ -308,7 +405,7 @@ impl Client {
|
|||
}
|
||||
}
|
||||
|
||||
let mut room = self.get_or_create_room(&room_id).write().await;
|
||||
let mut room = self.get_or_create_joined_room(&room_id).write().await;
|
||||
(decrypted_event, room.receive_timeline_event(&e))
|
||||
}
|
||||
_ => (None, false),
|
||||
|
@ -317,7 +414,7 @@ impl Client {
|
|||
|
||||
/// Receive a state event for a joined room and update the client state.
|
||||
///
|
||||
/// Returns true if the membership list of the room changed, false
|
||||
/// Returns true if the state of the room changed, false
|
||||
/// otherwise.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -330,7 +427,7 @@ impl Client {
|
|||
room_id: &RoomId,
|
||||
event: &StateEvent,
|
||||
) -> bool {
|
||||
let mut room = self.get_or_create_room(room_id).write().await;
|
||||
let mut room = self.get_or_create_joined_room(room_id).write().await;
|
||||
room.receive_state_event(event)
|
||||
}
|
||||
|
||||
|
@ -349,13 +446,70 @@ impl Client {
|
|||
room_id: &RoomId,
|
||||
event: &AnyStrippedStateEvent,
|
||||
) -> bool {
|
||||
let mut room = self.get_or_create_room(room_id).write().await;
|
||||
let mut room = self.get_or_create_invited_room(room_id).write().await;
|
||||
room.receive_stripped_state_event(event)
|
||||
}
|
||||
|
||||
/// Receive a timeline event for a room the user has left and update the client state.
|
||||
///
|
||||
/// Returns a tuple of the successfully decrypted event, or None on failure and
|
||||
/// a bool, true when the `Room` state has been updated.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `room_id` - The unique id of the room the event belongs to.
|
||||
///
|
||||
/// * `event` - The event that should be handled by the client.
|
||||
pub async fn receive_left_timeline_event(
|
||||
&mut self,
|
||||
room_id: &RoomId,
|
||||
event: &mut EventJson<RoomEvent>,
|
||||
) -> (Option<EventJson<RoomEvent>>, bool) {
|
||||
match event.deserialize() {
|
||||
#[allow(unused_mut)]
|
||||
Ok(mut e) => {
|
||||
#[cfg(feature = "encryption")]
|
||||
let mut decrypted_event = None;
|
||||
#[cfg(not(feature = "encryption"))]
|
||||
let decrypted_event = None;
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
{
|
||||
if let RoomEvent::RoomEncrypted(ref mut e) = e {
|
||||
e.room_id = Some(room_id.to_owned());
|
||||
let mut olm = self.olm.lock().await;
|
||||
|
||||
if let Some(o) = &mut *olm {
|
||||
decrypted_event = o.decrypt_room_event(&e).await.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut room = self.get_or_create_left_room(&room_id).write().await;
|
||||
(decrypted_event, room.receive_timeline_event(&e))
|
||||
}
|
||||
_ => (None, false),
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive a state event for a room the user has left and update the client state.
|
||||
///
|
||||
/// Returns true if the state of the room changed, false
|
||||
/// otherwise.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `room_id` - The unique id of the room the event belongs to.
|
||||
///
|
||||
/// * `event` - The event that should be handled by the client.
|
||||
pub async fn receive_left_state_event(&mut self, room_id: &RoomId, event: &StateEvent) -> bool {
|
||||
let mut room = self.get_or_create_left_room(room_id).write().await;
|
||||
room.receive_state_event(event)
|
||||
}
|
||||
|
||||
/// Receive a presence event from a sync response and updates the client state.
|
||||
///
|
||||
/// Returns true if the membership list of the room changed, false
|
||||
/// Returns true if the state of the room changed, false
|
||||
/// otherwise.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -369,7 +523,7 @@ impl Client {
|
|||
event: &PresenceEvent,
|
||||
) -> bool {
|
||||
// this should be the room that was just created in the `Client::sync` loop.
|
||||
if let Some(room) = self.get_room(room_id) {
|
||||
if let Some(room) = self.get_joined_room(room_id) {
|
||||
let mut room = room.write().await;
|
||||
room.receive_presence_event(event)
|
||||
} else {
|
||||
|
@ -532,7 +686,7 @@ impl Client {
|
|||
&self,
|
||||
room_id: &RoomId,
|
||||
) -> Result<Vec<send_event_to_device::Request>> {
|
||||
let room = self.get_room(room_id).expect("No room found");
|
||||
let room = self.get_joined_room(room_id).expect("No room found");
|
||||
let mut olm = self.olm.lock().await;
|
||||
|
||||
match &mut *olm {
|
||||
|
@ -649,288 +803,117 @@ impl Client {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn emit_timeline_event(&self, room_id: &RoomId, event: &RoomEvent) {
|
||||
match event {
|
||||
RoomEvent::RoomMember(mem) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_member(Arc::clone(&room), &mem).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomName(name) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_name(Arc::clone(&room), &name).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomCanonicalAlias(canonical) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_canonical_alias(Arc::clone(&room), &canonical)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomAliases(aliases) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_aliases(Arc::clone(&room), &aliases).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomAvatar(avatar) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_avatar(Arc::clone(&room), &avatar).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomMessage(msg) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_message(Arc::clone(&room), &msg).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomMessageFeedback(msg_feedback) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_message_feedback(Arc::clone(&room), &msg_feedback)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomRedaction(redaction) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_redaction(Arc::clone(&room), &redaction).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomPowerLevels(power) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_power_levels(Arc::clone(&room), &power).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomEvent::RoomTombstone(tomb) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_tombstone(Arc::clone(&room), &tomb).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
pub(crate) async fn emit_timeline_event(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
event: &RoomEvent,
|
||||
room_state: RoomStateType,
|
||||
) {
|
||||
emit_event!(
|
||||
self, room_id, event, room_state,
|
||||
RoomEvent::RoomMember => on_room_member,
|
||||
RoomEvent::RoomName => on_room_name,
|
||||
RoomEvent::RoomCanonicalAlias => on_room_canonical_alias,
|
||||
RoomEvent::RoomAliases => on_room_aliases,
|
||||
RoomEvent::RoomAvatar => on_room_avatar,
|
||||
RoomEvent::RoomMessage => on_room_message,
|
||||
RoomEvent::RoomMessageFeedback => on_room_message_feedback,
|
||||
RoomEvent::RoomRedaction => on_room_redaction,
|
||||
RoomEvent::RoomPowerLevels => on_room_power_levels,
|
||||
RoomEvent::RoomTombstone => on_room_tombstone,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) async fn emit_stripped_state_event(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
event: &AnyStrippedStateEvent,
|
||||
room_state: RoomStateType,
|
||||
) {
|
||||
match event {
|
||||
AnyStrippedStateEvent::RoomMember(member) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_stripped_state_member(Arc::clone(&room), &member)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
AnyStrippedStateEvent::RoomName(name) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_stripped_state_name(Arc::clone(&room), &name).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
AnyStrippedStateEvent::RoomCanonicalAlias(canonical) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_stripped_state_canonical_alias(Arc::clone(&room), &canonical)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
AnyStrippedStateEvent::RoomAliases(aliases) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_stripped_state_aliases(Arc::clone(&room), &aliases)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
AnyStrippedStateEvent::RoomAvatar(avatar) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_stripped_state_avatar(Arc::clone(&room), &avatar)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
AnyStrippedStateEvent::RoomPowerLevels(power) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_stripped_state_power_levels(Arc::clone(&room), &power)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
AnyStrippedStateEvent::RoomJoinRules(rules) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_stripped_state_join_rules(Arc::clone(&room), &rules)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
emit_event!(
|
||||
self, room_id, event, room_state,
|
||||
AnyStrippedStateEvent::RoomMember => on_stripped_state_member,
|
||||
AnyStrippedStateEvent::RoomName => on_stripped_state_name,
|
||||
AnyStrippedStateEvent::RoomCanonicalAlias => on_stripped_state_canonical_alias,
|
||||
AnyStrippedStateEvent::RoomAliases => on_stripped_state_aliases,
|
||||
AnyStrippedStateEvent::RoomAvatar => on_stripped_state_avatar,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) async fn emit_state_event(&self, room_id: &RoomId, event: &StateEvent) {
|
||||
match event {
|
||||
StateEvent::RoomMember(member) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_state_member(Arc::clone(&room), &member).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
StateEvent::RoomName(name) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_state_name(Arc::clone(&room), &name).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
StateEvent::RoomCanonicalAlias(canonical) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_state_canonical_alias(Arc::clone(&room), &canonical)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
StateEvent::RoomAliases(aliases) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_state_aliases(Arc::clone(&room), &aliases).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
StateEvent::RoomAvatar(avatar) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_state_avatar(Arc::clone(&room), &avatar).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
StateEvent::RoomPowerLevels(power) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_state_power_levels(Arc::clone(&room), &power).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
StateEvent::RoomJoinRules(rules) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_state_join_rules(Arc::clone(&room), &rules).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
StateEvent::RoomTombstone(tomb) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_room_tombstone(Arc::clone(&room), &tomb).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
pub(crate) async fn emit_state_event(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
event: &StateEvent,
|
||||
room_state: RoomStateType,
|
||||
) {
|
||||
emit_event!(
|
||||
self, room_id, event, room_state,
|
||||
StateEvent::RoomMember => on_state_member,
|
||||
StateEvent::RoomName => on_state_name,
|
||||
StateEvent::RoomCanonicalAlias => on_state_canonical_alias,
|
||||
StateEvent::RoomAliases => on_state_aliases,
|
||||
StateEvent::RoomAvatar => on_state_avatar,
|
||||
StateEvent::RoomPowerLevels => on_state_power_levels,
|
||||
StateEvent::RoomTombstone => on_room_tombstone,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) async fn emit_account_data_event(&self, room_id: &RoomId, event: &NonRoomEvent) {
|
||||
match event {
|
||||
NonRoomEvent::Presence(presence) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_account_presence(Arc::clone(&room), &presence).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
NonRoomEvent::IgnoredUserList(ignored) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_account_ignored_users(Arc::clone(&room), &ignored)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
NonRoomEvent::PushRules(rules) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_account_push_rules(Arc::clone(&room), &rules).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
NonRoomEvent::FullyRead(full_read) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_account_data_fully_read(Arc::clone(&room), &full_read)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
pub(crate) async fn emit_account_data_event(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
event: &NonRoomEvent,
|
||||
room_state: RoomStateType,
|
||||
) {
|
||||
emit_event!(
|
||||
self, room_id, event, room_state,
|
||||
NonRoomEvent::Presence => on_account_presence,
|
||||
NonRoomEvent::IgnoredUserList => on_account_ignored_users,
|
||||
NonRoomEvent::PushRules => on_account_push_rules,
|
||||
NonRoomEvent::FullyRead => on_account_data_fully_read,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) async fn emit_ephemeral_event(&self, room_id: &RoomId, event: &NonRoomEvent) {
|
||||
match event {
|
||||
NonRoomEvent::Presence(presence) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_account_presence(Arc::clone(&room), &presence).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
NonRoomEvent::IgnoredUserList(ignored) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_account_ignored_users(Arc::clone(&room), &ignored)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
NonRoomEvent::PushRules(rules) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_account_push_rules(Arc::clone(&room), &rules).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
NonRoomEvent::FullyRead(full_read) => {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_account_data_fully_read(Arc::clone(&room), &full_read)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
pub(crate) async fn emit_ephemeral_event(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
event: &NonRoomEvent,
|
||||
room_state: RoomStateType,
|
||||
) {
|
||||
emit_event!(
|
||||
self, room_id, event, room_state,
|
||||
NonRoomEvent::Presence => on_account_presence,
|
||||
NonRoomEvent::IgnoredUserList => on_account_ignored_users,
|
||||
NonRoomEvent::PushRules => on_account_push_rules,
|
||||
NonRoomEvent::FullyRead => on_account_data_fully_read,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) async fn emit_presence_event(&self, room_id: &RoomId, event: &PresenceEvent) {
|
||||
pub(crate) async fn emit_presence_event(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
event: &PresenceEvent,
|
||||
room_state: RoomStateType,
|
||||
) {
|
||||
if let Some(ee) = &self.event_emitter {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
ee.on_presence_event(Arc::clone(&room), &event).await;
|
||||
match room_state {
|
||||
RoomStateType::Invited => {
|
||||
if let Some(room) = self.get_invited_room(&room_id) {
|
||||
ee.on_presence_event(RoomState::Invited(Arc::clone(&room)), &event)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
RoomStateType::Joined => {
|
||||
if let Some(room) = self.get_joined_room(&room_id) {
|
||||
ee.on_presence_event(RoomState::Joined(Arc::clone(&room)), &event)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
RoomStateType::Left => {
|
||||
if let Some(room) = self.get_left_room(&room_id) {
|
||||
ee.on_presence_event(RoomState::Left(Arc::clone(&room)), &event)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::events::{
|
||||
fully_read::FullyReadEvent,
|
||||
|
@ -36,8 +35,7 @@ use crate::events::{
|
|||
StrippedRoomMember, StrippedRoomName, StrippedRoomPowerLevels,
|
||||
},
|
||||
};
|
||||
use crate::models::Room;
|
||||
use tokio::sync::RwLock;
|
||||
use crate::RoomState;
|
||||
|
||||
/// This trait allows any type implementing `EventEmitter` to specify event callbacks for each event.
|
||||
/// The `AsyncClient` calls each method when the corresponding event is received.
|
||||
|
@ -53,7 +51,7 @@ use tokio::sync::RwLock;
|
|||
/// events::{
|
||||
/// room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||
/// },
|
||||
/// AsyncClient, AsyncClientConfig, EventEmitter, Room, SyncSettings,
|
||||
/// AsyncClient, AsyncClientConfig, EventEmitter, RoomState, SyncSettings,
|
||||
/// };
|
||||
/// use tokio::sync::RwLock;
|
||||
///
|
||||
|
@ -61,23 +59,25 @@ use tokio::sync::RwLock;
|
|||
///
|
||||
/// #[async_trait::async_trait]
|
||||
/// impl EventEmitter for EventCallback {
|
||||
/// async fn on_room_message(&self, room: Arc<RwLock<Room>>, event: &MessageEvent) {
|
||||
/// if let MessageEvent {
|
||||
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||
/// sender,
|
||||
/// ..
|
||||
/// } = event
|
||||
/// {
|
||||
/// let name = {
|
||||
/// let room = room.read().await;
|
||||
/// let member = room.members.get(&sender).unwrap();
|
||||
/// member
|
||||
/// .display_name
|
||||
/// .as_ref()
|
||||
/// .map(ToString::to_string)
|
||||
/// .unwrap_or(sender.to_string())
|
||||
/// };
|
||||
/// println!("{}: {}", name, msg_body);
|
||||
/// async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
||||
/// if let RoomState::Joined(room) = room {
|
||||
/// if let MessageEvent {
|
||||
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||
/// sender,
|
||||
/// ..
|
||||
/// } = event
|
||||
/// {
|
||||
/// let name = {
|
||||
/// let room = room.read().await;
|
||||
/// let member = room.members.get(&sender).unwrap();
|
||||
/// member
|
||||
/// .display_name
|
||||
/// .as_ref()
|
||||
/// .map(ToString::to_string)
|
||||
/// .unwrap_or(sender.to_string())
|
||||
/// };
|
||||
/// println!("{}: {}", name, msg_body);
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
|
@ -86,81 +86,76 @@ use tokio::sync::RwLock;
|
|||
pub trait EventEmitter: Send + Sync {
|
||||
// ROOM EVENTS from `IncomingTimeline`
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMember` event.
|
||||
async fn on_room_member(&self, _: Arc<RwLock<Room>>, _: &MemberEvent) {}
|
||||
async fn on_room_member(&self, _: RoomState, _: &MemberEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomName` event.
|
||||
async fn on_room_name(&self, _: Arc<RwLock<Room>>, _: &NameEvent) {}
|
||||
async fn on_room_name(&self, _: RoomState, _: &NameEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomCanonicalAlias` event.
|
||||
async fn on_room_canonical_alias(&self, _: Arc<RwLock<Room>>, _: &CanonicalAliasEvent) {}
|
||||
async fn on_room_canonical_alias(&self, _: RoomState, _: &CanonicalAliasEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomAliases` event.
|
||||
async fn on_room_aliases(&self, _: Arc<RwLock<Room>>, _: &AliasesEvent) {}
|
||||
async fn on_room_aliases(&self, _: RoomState, _: &AliasesEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomAvatar` event.
|
||||
async fn on_room_avatar(&self, _: Arc<RwLock<Room>>, _: &AvatarEvent) {}
|
||||
async fn on_room_avatar(&self, _: RoomState, _: &AvatarEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMessage` event.
|
||||
async fn on_room_message(&self, _: Arc<RwLock<Room>>, _: &MessageEvent) {}
|
||||
async fn on_room_message(&self, _: RoomState, _: &MessageEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMessageFeedback` event.
|
||||
async fn on_room_message_feedback(&self, _: Arc<RwLock<Room>>, _: &FeedbackEvent) {}
|
||||
async fn on_room_message_feedback(&self, _: RoomState, _: &FeedbackEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomRedaction` event.
|
||||
async fn on_room_redaction(&self, _: Arc<RwLock<Room>>, _: &RedactionEvent) {}
|
||||
async fn on_room_redaction(&self, _: RoomState, _: &RedactionEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomPowerLevels` event.
|
||||
async fn on_room_power_levels(&self, _: Arc<RwLock<Room>>, _: &PowerLevelsEvent) {}
|
||||
async fn on_room_power_levels(&self, _: RoomState, _: &PowerLevelsEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `RoomEvent::Tombstone` event.
|
||||
async fn on_room_tombstone(&self, _: Arc<RwLock<Room>>, _: &TombstoneEvent) {}
|
||||
async fn on_room_tombstone(&self, _: RoomState, _: &TombstoneEvent) {}
|
||||
|
||||
// `RoomEvent`s from `IncomingState`
|
||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomMember` event.
|
||||
async fn on_state_member(&self, _: Arc<RwLock<Room>>, _: &MemberEvent) {}
|
||||
async fn on_state_member(&self, _: RoomState, _: &MemberEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomName` event.
|
||||
async fn on_state_name(&self, _: Arc<RwLock<Room>>, _: &NameEvent) {}
|
||||
async fn on_state_name(&self, _: RoomState, _: &NameEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomCanonicalAlias` event.
|
||||
async fn on_state_canonical_alias(&self, _: Arc<RwLock<Room>>, _: &CanonicalAliasEvent) {}
|
||||
async fn on_state_canonical_alias(&self, _: RoomState, _: &CanonicalAliasEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomAliases` event.
|
||||
async fn on_state_aliases(&self, _: Arc<RwLock<Room>>, _: &AliasesEvent) {}
|
||||
async fn on_state_aliases(&self, _: RoomState, _: &AliasesEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomAvatar` event.
|
||||
async fn on_state_avatar(&self, _: Arc<RwLock<Room>>, _: &AvatarEvent) {}
|
||||
async fn on_state_avatar(&self, _: RoomState, _: &AvatarEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomPowerLevels` event.
|
||||
async fn on_state_power_levels(&self, _: Arc<RwLock<Room>>, _: &PowerLevelsEvent) {}
|
||||
async fn on_state_power_levels(&self, _: RoomState, _: &PowerLevelsEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomJoinRules` event.
|
||||
async fn on_state_join_rules(&self, _: Arc<RwLock<Room>>, _: &JoinRulesEvent) {}
|
||||
async fn on_state_join_rules(&self, _: RoomState, _: &JoinRulesEvent) {}
|
||||
|
||||
// `AnyStrippedStateEvent`s
|
||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomMember` event.
|
||||
async fn on_stripped_state_member(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomMember) {}
|
||||
async fn on_stripped_state_member(&self, _: RoomState, _: &StrippedRoomMember) {}
|
||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomName` event.
|
||||
async fn on_stripped_state_name(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomName) {}
|
||||
async fn on_stripped_state_name(&self, _: RoomState, _: &StrippedRoomName) {}
|
||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event.
|
||||
async fn on_stripped_state_canonical_alias(
|
||||
&self,
|
||||
_: Arc<RwLock<Room>>,
|
||||
_: RoomState,
|
||||
_: &StrippedRoomCanonicalAlias,
|
||||
) {
|
||||
}
|
||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event.
|
||||
async fn on_stripped_state_aliases(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomAliases) {}
|
||||
async fn on_stripped_state_aliases(&self, _: RoomState, _: &StrippedRoomAliases) {}
|
||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomAvatar` event.
|
||||
async fn on_stripped_state_avatar(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomAvatar) {}
|
||||
async fn on_stripped_state_avatar(&self, _: RoomState, _: &StrippedRoomAvatar) {}
|
||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event.
|
||||
async fn on_stripped_state_power_levels(
|
||||
&self,
|
||||
_: Arc<RwLock<Room>>,
|
||||
_: &StrippedRoomPowerLevels,
|
||||
) {
|
||||
}
|
||||
async fn on_stripped_state_power_levels(&self, _: RoomState, _: &StrippedRoomPowerLevels) {}
|
||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
|
||||
async fn on_stripped_state_join_rules(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomJoinRules) {}
|
||||
async fn on_stripped_state_join_rules(&self, _: RoomState, _: &StrippedRoomJoinRules) {}
|
||||
|
||||
// `NonRoomEvent` (this is a type alias from ruma_events) from `IncomingAccountData`
|
||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomMember` event.
|
||||
async fn on_account_presence(&self, _: Arc<RwLock<Room>>, _: &PresenceEvent) {}
|
||||
async fn on_account_presence(&self, _: RoomState, _: &PresenceEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomName` event.
|
||||
async fn on_account_ignored_users(&self, _: Arc<RwLock<Room>>, _: &IgnoredUserListEvent) {}
|
||||
async fn on_account_ignored_users(&self, _: RoomState, _: &IgnoredUserListEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomCanonicalAlias` event.
|
||||
async fn on_account_push_rules(&self, _: Arc<RwLock<Room>>, _: &PushRulesEvent) {}
|
||||
async fn on_account_push_rules(&self, _: RoomState, _: &PushRulesEvent) {}
|
||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
||||
async fn on_account_data_fully_read(&self, _: Arc<RwLock<Room>>, _: &FullyReadEvent) {}
|
||||
async fn on_account_data_fully_read(&self, _: RoomState, _: &FullyReadEvent) {}
|
||||
|
||||
// `PresenceEvent` is a struct so there is only the one method
|
||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
||||
async fn on_presence_event(&self, _: Arc<RwLock<Room>>, _: &PresenceEvent) {}
|
||||
async fn on_presence_event(&self, _: RoomState, _: &PresenceEvent) {}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -173,71 +168,71 @@ mod test {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl EventEmitter for EvEmitterTest {
|
||||
async fn on_room_member(&self, _: Arc<RwLock<Room>>, _: &MemberEvent) {
|
||||
async fn on_room_member(&self, _: RoomState, _: &MemberEvent) {
|
||||
self.0.lock().await.push("member".to_string())
|
||||
}
|
||||
async fn on_room_name(&self, _: Arc<RwLock<Room>>, _: &NameEvent) {
|
||||
async fn on_room_name(&self, _: RoomState, _: &NameEvent) {
|
||||
self.0.lock().await.push("name".to_string())
|
||||
}
|
||||
async fn on_room_canonical_alias(&self, _: Arc<RwLock<Room>>, _: &CanonicalAliasEvent) {
|
||||
async fn on_room_canonical_alias(&self, _: RoomState, _: &CanonicalAliasEvent) {
|
||||
self.0.lock().await.push("canonical".to_string())
|
||||
}
|
||||
async fn on_room_aliases(&self, _: Arc<RwLock<Room>>, _: &AliasesEvent) {
|
||||
async fn on_room_aliases(&self, _: RoomState, _: &AliasesEvent) {
|
||||
self.0.lock().await.push("aliases".to_string())
|
||||
}
|
||||
async fn on_room_avatar(&self, _: Arc<RwLock<Room>>, _: &AvatarEvent) {
|
||||
async fn on_room_avatar(&self, _: RoomState, _: &AvatarEvent) {
|
||||
self.0.lock().await.push("avatar".to_string())
|
||||
}
|
||||
async fn on_room_message(&self, _: Arc<RwLock<Room>>, _: &MessageEvent) {
|
||||
async fn on_room_message(&self, _: RoomState, _: &MessageEvent) {
|
||||
self.0.lock().await.push("message".to_string())
|
||||
}
|
||||
async fn on_room_message_feedback(&self, _: Arc<RwLock<Room>>, _: &FeedbackEvent) {
|
||||
async fn on_room_message_feedback(&self, _: RoomState, _: &FeedbackEvent) {
|
||||
self.0.lock().await.push("feedback".to_string())
|
||||
}
|
||||
async fn on_room_redaction(&self, _: Arc<RwLock<Room>>, _: &RedactionEvent) {
|
||||
async fn on_room_redaction(&self, _: RoomState, _: &RedactionEvent) {
|
||||
self.0.lock().await.push("redaction".to_string())
|
||||
}
|
||||
async fn on_room_power_levels(&self, _: Arc<RwLock<Room>>, _: &PowerLevelsEvent) {
|
||||
async fn on_room_power_levels(&self, _: RoomState, _: &PowerLevelsEvent) {
|
||||
self.0.lock().await.push("power".to_string())
|
||||
}
|
||||
async fn on_room_tombstone(&self, _: Arc<RwLock<Room>>, _: &TombstoneEvent) {
|
||||
async fn on_room_tombstone(&self, _: RoomState, _: &TombstoneEvent) {
|
||||
self.0.lock().await.push("tombstone".to_string())
|
||||
}
|
||||
|
||||
async fn on_state_member(&self, _: Arc<RwLock<Room>>, _: &MemberEvent) {
|
||||
async fn on_state_member(&self, _: RoomState, _: &MemberEvent) {
|
||||
self.0.lock().await.push("state member".to_string())
|
||||
}
|
||||
async fn on_state_name(&self, _: Arc<RwLock<Room>>, _: &NameEvent) {
|
||||
async fn on_state_name(&self, _: RoomState, _: &NameEvent) {
|
||||
self.0.lock().await.push("state name".to_string())
|
||||
}
|
||||
async fn on_state_canonical_alias(&self, _: Arc<RwLock<Room>>, _: &CanonicalAliasEvent) {
|
||||
async fn on_state_canonical_alias(&self, _: RoomState, _: &CanonicalAliasEvent) {
|
||||
self.0.lock().await.push("state canonical".to_string())
|
||||
}
|
||||
async fn on_state_aliases(&self, _: Arc<RwLock<Room>>, _: &AliasesEvent) {
|
||||
async fn on_state_aliases(&self, _: RoomState, _: &AliasesEvent) {
|
||||
self.0.lock().await.push("state aliases".to_string())
|
||||
}
|
||||
async fn on_state_avatar(&self, _: Arc<RwLock<Room>>, _: &AvatarEvent) {
|
||||
async fn on_state_avatar(&self, _: RoomState, _: &AvatarEvent) {
|
||||
self.0.lock().await.push("state avatar".to_string())
|
||||
}
|
||||
async fn on_state_power_levels(&self, _: Arc<RwLock<Room>>, _: &PowerLevelsEvent) {
|
||||
async fn on_state_power_levels(&self, _: RoomState, _: &PowerLevelsEvent) {
|
||||
self.0.lock().await.push("state power".to_string())
|
||||
}
|
||||
async fn on_state_join_rules(&self, _: Arc<RwLock<Room>>, _: &JoinRulesEvent) {
|
||||
async fn on_state_join_rules(&self, _: RoomState, _: &JoinRulesEvent) {
|
||||
self.0.lock().await.push("state rules".to_string())
|
||||
}
|
||||
|
||||
async fn on_stripped_state_member(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomMember) {
|
||||
async fn on_stripped_state_member(&self, _: RoomState, _: &StrippedRoomMember) {
|
||||
self.0
|
||||
.lock()
|
||||
.await
|
||||
.push("stripped state member".to_string())
|
||||
}
|
||||
async fn on_stripped_state_name(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomName) {
|
||||
async fn on_stripped_state_name(&self, _: RoomState, _: &StrippedRoomName) {
|
||||
self.0.lock().await.push("stripped state name".to_string())
|
||||
}
|
||||
async fn on_stripped_state_canonical_alias(
|
||||
&self,
|
||||
_: Arc<RwLock<Room>>,
|
||||
_: RoomState,
|
||||
_: &StrippedRoomCanonicalAlias,
|
||||
) {
|
||||
self.0
|
||||
|
@ -245,46 +240,38 @@ mod test {
|
|||
.await
|
||||
.push("stripped state canonical".to_string())
|
||||
}
|
||||
async fn on_stripped_state_aliases(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomAliases) {
|
||||
async fn on_stripped_state_aliases(&self, _: RoomState, _: &StrippedRoomAliases) {
|
||||
self.0
|
||||
.lock()
|
||||
.await
|
||||
.push("stripped state aliases".to_string())
|
||||
}
|
||||
async fn on_stripped_state_avatar(&self, _: Arc<RwLock<Room>>, _: &StrippedRoomAvatar) {
|
||||
async fn on_stripped_state_avatar(&self, _: RoomState, _: &StrippedRoomAvatar) {
|
||||
self.0
|
||||
.lock()
|
||||
.await
|
||||
.push("stripped state avatar".to_string())
|
||||
}
|
||||
async fn on_stripped_state_power_levels(
|
||||
&self,
|
||||
_: Arc<RwLock<Room>>,
|
||||
_: &StrippedRoomPowerLevels,
|
||||
) {
|
||||
async fn on_stripped_state_power_levels(&self, _: RoomState, _: &StrippedRoomPowerLevels) {
|
||||
self.0.lock().await.push("stripped state power".to_string())
|
||||
}
|
||||
async fn on_stripped_state_join_rules(
|
||||
&self,
|
||||
_: Arc<RwLock<Room>>,
|
||||
_: &StrippedRoomJoinRules,
|
||||
) {
|
||||
async fn on_stripped_state_join_rules(&self, _: RoomState, _: &StrippedRoomJoinRules) {
|
||||
self.0.lock().await.push("stripped state rules".to_string())
|
||||
}
|
||||
|
||||
async fn on_account_presence(&self, _: Arc<RwLock<Room>>, _: &PresenceEvent) {
|
||||
async fn on_account_presence(&self, _: RoomState, _: &PresenceEvent) {
|
||||
self.0.lock().await.push("account presence".to_string())
|
||||
}
|
||||
async fn on_account_ignored_users(&self, _: Arc<RwLock<Room>>, _: &IgnoredUserListEvent) {
|
||||
async fn on_account_ignored_users(&self, _: RoomState, _: &IgnoredUserListEvent) {
|
||||
self.0.lock().await.push("account ignore".to_string())
|
||||
}
|
||||
async fn on_account_push_rules(&self, _: Arc<RwLock<Room>>, _: &PushRulesEvent) {
|
||||
async fn on_account_push_rules(&self, _: RoomState, _: &PushRulesEvent) {
|
||||
self.0.lock().await.push("".to_string())
|
||||
}
|
||||
async fn on_account_data_fully_read(&self, _: Arc<RwLock<Room>>, _: &FullyReadEvent) {
|
||||
async fn on_account_data_fully_read(&self, _: RoomState, _: &FullyReadEvent) {
|
||||
self.0.lock().await.push("account read".to_string())
|
||||
}
|
||||
async fn on_presence_event(&self, _: Arc<RwLock<Room>>, _: &PresenceEvent) {
|
||||
async fn on_presence_event(&self, _: RoomState, _: &PresenceEvent) {
|
||||
self.0.lock().await.push("presence event".to_string())
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +317,6 @@ mod test {
|
|||
assert_eq!(
|
||||
v.as_slice(),
|
||||
[
|
||||
"state rules",
|
||||
"state member",
|
||||
"state aliases",
|
||||
"state power",
|
||||
|
@ -340,7 +326,7 @@ mod test {
|
|||
"message",
|
||||
"account read",
|
||||
"account ignore",
|
||||
"presence event",
|
||||
"presence event"
|
||||
],
|
||||
)
|
||||
}
|
||||
|
@ -410,14 +396,13 @@ mod test {
|
|||
assert_eq!(
|
||||
v.as_slice(),
|
||||
[
|
||||
"message",
|
||||
"state rules",
|
||||
"state member",
|
||||
"state aliases",
|
||||
"state power",
|
||||
"state canonical",
|
||||
"state member",
|
||||
"state member"
|
||||
"state member",
|
||||
"message"
|
||||
],
|
||||
)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ mod state;
|
|||
pub mod test_builder;
|
||||
|
||||
pub use async_client::{AsyncClient, AsyncClientConfig, SyncSettings};
|
||||
pub use base_client::Client;
|
||||
pub use base_client::{Client, RoomState, RoomStateType};
|
||||
pub use event_emitter::EventEmitter;
|
||||
#[cfg(feature = "encryption")]
|
||||
pub use matrix_sdk_crypto::{Device, TrustState};
|
||||
|
|
Loading…
Reference in New Issue