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 std::{env, process::exit};
|
||||||
|
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
self,
|
self,
|
||||||
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
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;
|
use url::Url;
|
||||||
|
|
||||||
struct CommandBot {
|
struct CommandBot {
|
||||||
|
@ -23,37 +21,39 @@ impl CommandBot {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl EventEmitter for CommandBot {
|
impl EventEmitter for CommandBot {
|
||||||
async fn on_room_message(&self, room: Arc<RwLock<Room>>, event: &MessageEvent) {
|
async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
||||||
let msg_body = if let MessageEvent {
|
if let RoomState::Joined(room) = room {
|
||||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
let msg_body = if let MessageEvent {
|
||||||
..
|
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
} = event
|
..
|
||||||
{
|
} = event
|
||||||
msg_body.clone()
|
{
|
||||||
} else {
|
msg_body.clone()
|
||||||
String::new()
|
} else {
|
||||||
};
|
String::new()
|
||||||
|
};
|
||||||
|
|
||||||
if msg_body.contains("!party") {
|
if msg_body.contains("!party") {
|
||||||
let content = MessageEventContent::Text(TextMessageEventContent {
|
let content = MessageEventContent::Text(TextMessageEventContent {
|
||||||
body: "🎉🎊🥳 let's PARTY!! 🥳🎊🎉".to_string(),
|
body: "🎉🎊🥳 let's PARTY!! 🥳🎊🎉".to_string(),
|
||||||
format: None,
|
format: None,
|
||||||
formatted_body: None,
|
formatted_body: None,
|
||||||
relates_to: None,
|
relates_to: None,
|
||||||
});
|
});
|
||||||
// we clone here to hold the lock for as little time as possible.
|
// we clone here to hold the lock for as little time as possible.
|
||||||
let room_id = room.read().await.room_id.clone();
|
let room_id = room.read().await.room_id.clone();
|
||||||
|
|
||||||
println!("sending");
|
println!("sending");
|
||||||
|
|
||||||
self.client
|
self.client
|
||||||
// send our message to the room we found the "!party" command in
|
// 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.
|
// the last parameter is an optional Uuid which we don't care about.
|
||||||
.room_send(&room_id, content, None)
|
.room_send(&room_id, content, None)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!("message sent");
|
println!("message sent");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
use std::sync::Arc;
|
|
||||||
use std::{env, process::exit};
|
use std::{env, process::exit};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
self,
|
self,
|
||||||
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||||
AsyncClient, AsyncClientConfig, EventEmitter, Room, SyncSettings,
|
AsyncClient, AsyncClientConfig, EventEmitter, RoomState, SyncSettings,
|
||||||
};
|
};
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
struct EventCallback;
|
struct EventCallback;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl EventEmitter for EventCallback {
|
impl EventEmitter for EventCallback {
|
||||||
async fn on_room_message(&self, room: Arc<RwLock<Room>>, event: &MessageEvent) {
|
async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
||||||
if let MessageEvent {
|
if let RoomState::Joined(room) = room {
|
||||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
if let MessageEvent {
|
||||||
sender,
|
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
..
|
sender,
|
||||||
} = event
|
..
|
||||||
{
|
} = event
|
||||||
let name = {
|
{
|
||||||
// any reads should be held for the shortest time possible to
|
let name = {
|
||||||
// avoid dead locks
|
// any reads should be held for the shortest time possible to
|
||||||
let room = room.read().await;
|
// avoid dead locks
|
||||||
let member = room.members.get(&sender).unwrap();
|
let room = room.read().await;
|
||||||
member
|
let member = room.members.get(&sender).unwrap();
|
||||||
.display_name
|
member
|
||||||
.as_ref()
|
.display_name
|
||||||
.map(ToString::to_string)
|
.as_ref()
|
||||||
.unwrap_or(sender.to_string())
|
.map(ToString::to_string)
|
||||||
};
|
.unwrap_or(sender.to_string())
|
||||||
println!("{}: {}", name, msg_body);
|
};
|
||||||
|
println!("{}: {}", name, msg_body);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ use crate::models::Room;
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use crate::state::StateStore;
|
use crate::state::StateStore;
|
||||||
use crate::VERSION;
|
use crate::VERSION;
|
||||||
use crate::{Error, EventEmitter, Result};
|
use crate::{Error, EventEmitter, Result, RoomStateType};
|
||||||
|
|
||||||
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
|
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
|
||||||
|
|
||||||
|
@ -322,6 +322,9 @@ impl AsyncClient {
|
||||||
///
|
///
|
||||||
/// This is a human readable room name.
|
/// This is a human readable room name.
|
||||||
pub async fn get_room_name(&self, room_id: &RoomId) -> Option<String> {
|
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
|
self.base_client
|
||||||
.read()
|
.read()
|
||||||
.await
|
.await
|
||||||
|
@ -336,13 +339,27 @@ impl AsyncClient {
|
||||||
self.base_client.read().await.calculate_room_names().await
|
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`
|
/// 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()
|
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`.
|
/// This allows `AsyncClient` to manually sync state with the provided `StateStore`.
|
||||||
///
|
///
|
||||||
/// Returns true when a successful `StateStore` sync has completed.
|
/// Returns true when a successful `StateStore` sync has completed.
|
||||||
|
@ -663,13 +680,12 @@ impl AsyncClient {
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
async fn iter_joined_rooms(&self, response: &mut sync_events::Response) -> Result<bool> {
|
async fn iter_joined_rooms(&self, response: &mut sync_events::Response) -> Result<bool> {
|
||||||
let mut updated = false;
|
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 matrix_room = {
|
||||||
let mut client = self.base_client.write().await;
|
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 let Ok(e) = event.deserialize() {
|
||||||
if client.receive_joined_state_event(&room_id, &e).await {
|
if client.receive_joined_state_event(&room_id, &e).await {
|
||||||
updated = true;
|
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
|
// 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
|
// 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() {
|
if let Ok(e) = event.deserialize() {
|
||||||
let client = self.base_client.read().await;
|
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 decrypted_event = {
|
||||||
let mut client = self.base_client.write().await;
|
let mut client = self.base_client.write().await;
|
||||||
let (decrypt_ev, timeline_update) = client
|
let (decrypt_ev, timeline_update) = client
|
||||||
|
@ -709,12 +730,14 @@ impl AsyncClient {
|
||||||
|
|
||||||
if let Ok(e) = event.deserialize() {
|
if let Ok(e) = event.deserialize() {
|
||||||
let client = self.base_client.read().await;
|
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
|
// 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 {
|
for account_data in &account_data.events {
|
||||||
{
|
{
|
||||||
if let Ok(e) = account_data.deserialize() {
|
if let Ok(e) = account_data.deserialize() {
|
||||||
|
@ -722,7 +745,9 @@ impl AsyncClient {
|
||||||
if client.receive_account_data_event(&room_id, &e).await {
|
if client.receive_account_data_event(&room_id, &e).await {
|
||||||
updated = true;
|
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;
|
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() {
|
if let Ok(e) = ephemeral.deserialize() {
|
||||||
let mut client = self.base_client.write().await;
|
let mut client = self.base_client.write().await;
|
||||||
|
@ -752,7 +779,9 @@ impl AsyncClient {
|
||||||
updated = true;
|
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)
|
Ok(updated)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
async fn iter_left_rooms(&self, response: &mut sync_events::Response) -> Result<bool> {
|
async fn iter_left_rooms(&self, response: &mut sync_events::Response) -> Result<bool> {
|
||||||
let mut updated = false;
|
let mut updated = false;
|
||||||
for (room_id, left_room) in &mut response.rooms.leave {
|
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 {
|
for mut event in &mut left_room.timeline.events {
|
||||||
let decrypted_event = {
|
let decrypted_event = {
|
||||||
let mut client = self.base_client.write().await;
|
let mut client = self.base_client.write().await;
|
||||||
|
|
||||||
let (decrypt_ev, timeline_update) = client
|
let (decrypt_ev, timeline_update) = client
|
||||||
.receive_joined_timeline_event(room_id, &mut event)
|
.receive_left_timeline_event(room_id, &mut event)
|
||||||
.await;
|
.await;
|
||||||
if timeline_update {
|
if timeline_update {
|
||||||
updated = true;
|
updated = true;
|
||||||
|
@ -791,30 +840,23 @@ impl AsyncClient {
|
||||||
|
|
||||||
if let Ok(e) = event.deserialize() {
|
if let Ok(e) = event.deserialize() {
|
||||||
let client = self.base_client.read().await;
|
let client = self.base_client.read().await;
|
||||||
client.emit_timeline_event(&room_id, &e).await;
|
client
|
||||||
}
|
.emit_timeline_event(&room_id, &e, RoomStateType::Left)
|
||||||
}
|
.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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if updated {
|
if updated {
|
||||||
if let Some(store) = self.base_client.read().await.state_store.as_ref() {
|
if let Some(store) = self.base_client.read().await.state_store.as_ref() {
|
||||||
let mut client = self.base_client.write().await;
|
store
|
||||||
let room = client.get_or_create_room(&room_id).clone();
|
.store_room_state(matrix_room.read().await.deref())
|
||||||
store.store_room_state(room.read().await.deref()).await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(updated)
|
Ok(updated)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
async fn iter_invited_rooms(&self, response: &sync_events::Response) -> Result<bool> {
|
async fn iter_invited_rooms(&self, response: &sync_events::Response) -> Result<bool> {
|
||||||
let mut updated = false;
|
let mut updated = false;
|
||||||
for (room_id, invited_room) in &response.rooms.invite {
|
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 {
|
for event in &invited_room.invite_state.events {
|
||||||
if let Ok(e) = event.deserialize() {
|
if let Ok(e) = event.deserialize() {
|
||||||
let client = self.base_client.read().await;
|
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;
|
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.
|
/// A no IO Client implementation.
|
||||||
///
|
///
|
||||||
/// This Client is a state machine that receives responses and events and
|
/// This Client is a state machine that receives responses and events and
|
||||||
|
@ -70,6 +122,10 @@ pub struct Client {
|
||||||
pub sync_token: Option<Token>,
|
pub sync_token: Option<Token>,
|
||||||
/// A map of the rooms our user is joined in.
|
/// A map of the rooms our user is joined in.
|
||||||
pub joined_rooms: HashMap<RoomId, Arc<RwLock<Room>>>,
|
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.
|
/// A list of ignored users.
|
||||||
pub ignored_users: Vec<UserId>,
|
pub ignored_users: Vec<UserId>,
|
||||||
/// The push ruleset for the logged in user.
|
/// The push ruleset for the logged in user.
|
||||||
|
@ -120,6 +176,8 @@ impl Client {
|
||||||
session,
|
session,
|
||||||
sync_token: None,
|
sync_token: None,
|
||||||
joined_rooms: HashMap::new(),
|
joined_rooms: HashMap::new(),
|
||||||
|
invited_rooms: HashMap::new(),
|
||||||
|
lefted_rooms: HashMap::new(),
|
||||||
ignored_users: Vec::new(),
|
ignored_users: Vec::new(),
|
||||||
push_ruleset: None,
|
push_ruleset: None,
|
||||||
event_emitter: None,
|
event_emitter: None,
|
||||||
|
@ -224,7 +282,7 @@ impl Client {
|
||||||
res
|
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)]
|
#[allow(clippy::or_fun_call)]
|
||||||
self.joined_rooms
|
self.joined_rooms
|
||||||
.entry(room_id.clone())
|
.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)
|
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.
|
/// Handle a m.ignored_user_list event, updating the room state if necessary.
|
||||||
///
|
///
|
||||||
/// Returns true if the room name changed, false otherwise.
|
/// 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))
|
(decrypted_event, room.receive_timeline_event(&e))
|
||||||
}
|
}
|
||||||
_ => (None, false),
|
_ => (None, false),
|
||||||
|
@ -317,7 +414,7 @@ impl Client {
|
||||||
|
|
||||||
/// Receive a state event for a joined room and update the client state.
|
/// 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.
|
/// otherwise.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -330,7 +427,7 @@ impl Client {
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
event: &StateEvent,
|
event: &StateEvent,
|
||||||
) -> bool {
|
) -> 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)
|
room.receive_state_event(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,13 +446,70 @@ impl Client {
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
event: &AnyStrippedStateEvent,
|
event: &AnyStrippedStateEvent,
|
||||||
) -> bool {
|
) -> 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)
|
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.
|
/// 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.
|
/// otherwise.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -369,7 +523,7 @@ impl Client {
|
||||||
event: &PresenceEvent,
|
event: &PresenceEvent,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// this should be the room that was just created in the `Client::sync` loop.
|
// 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;
|
let mut room = room.write().await;
|
||||||
room.receive_presence_event(event)
|
room.receive_presence_event(event)
|
||||||
} else {
|
} else {
|
||||||
|
@ -532,7 +686,7 @@ impl Client {
|
||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
) -> Result<Vec<send_event_to_device::Request>> {
|
) -> 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;
|
let mut olm = self.olm.lock().await;
|
||||||
|
|
||||||
match &mut *olm {
|
match &mut *olm {
|
||||||
|
@ -649,288 +803,117 @@ impl Client {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn emit_timeline_event(&self, room_id: &RoomId, event: &RoomEvent) {
|
pub(crate) async fn emit_timeline_event(
|
||||||
match event {
|
&self,
|
||||||
RoomEvent::RoomMember(mem) => {
|
room_id: &RoomId,
|
||||||
if let Some(ee) = &self.event_emitter {
|
event: &RoomEvent,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
room_state: RoomStateType,
|
||||||
ee.on_room_member(Arc::clone(&room), &mem).await;
|
) {
|
||||||
}
|
emit_event!(
|
||||||
}
|
self, room_id, event, room_state,
|
||||||
}
|
RoomEvent::RoomMember => on_room_member,
|
||||||
RoomEvent::RoomName(name) => {
|
RoomEvent::RoomName => on_room_name,
|
||||||
if let Some(ee) = &self.event_emitter {
|
RoomEvent::RoomCanonicalAlias => on_room_canonical_alias,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
RoomEvent::RoomAliases => on_room_aliases,
|
||||||
ee.on_room_name(Arc::clone(&room), &name).await;
|
RoomEvent::RoomAvatar => on_room_avatar,
|
||||||
}
|
RoomEvent::RoomMessage => on_room_message,
|
||||||
}
|
RoomEvent::RoomMessageFeedback => on_room_message_feedback,
|
||||||
}
|
RoomEvent::RoomRedaction => on_room_redaction,
|
||||||
RoomEvent::RoomCanonicalAlias(canonical) => {
|
RoomEvent::RoomPowerLevels => on_room_power_levels,
|
||||||
if let Some(ee) = &self.event_emitter {
|
RoomEvent::RoomTombstone => on_room_tombstone,
|
||||||
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_stripped_state_event(
|
pub(crate) async fn emit_stripped_state_event(
|
||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
event: &AnyStrippedStateEvent,
|
event: &AnyStrippedStateEvent,
|
||||||
|
room_state: RoomStateType,
|
||||||
) {
|
) {
|
||||||
match event {
|
emit_event!(
|
||||||
AnyStrippedStateEvent::RoomMember(member) => {
|
self, room_id, event, room_state,
|
||||||
if let Some(ee) = &self.event_emitter {
|
AnyStrippedStateEvent::RoomMember => on_stripped_state_member,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
AnyStrippedStateEvent::RoomName => on_stripped_state_name,
|
||||||
ee.on_stripped_state_member(Arc::clone(&room), &member)
|
AnyStrippedStateEvent::RoomCanonicalAlias => on_stripped_state_canonical_alias,
|
||||||
.await;
|
AnyStrippedStateEvent::RoomAliases => on_stripped_state_aliases,
|
||||||
}
|
AnyStrippedStateEvent::RoomAvatar => on_stripped_state_avatar,
|
||||||
}
|
);
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn emit_state_event(&self, room_id: &RoomId, event: &StateEvent) {
|
pub(crate) async fn emit_state_event(
|
||||||
match event {
|
&self,
|
||||||
StateEvent::RoomMember(member) => {
|
room_id: &RoomId,
|
||||||
if let Some(ee) = &self.event_emitter {
|
event: &StateEvent,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
room_state: RoomStateType,
|
||||||
ee.on_state_member(Arc::clone(&room), &member).await;
|
) {
|
||||||
}
|
emit_event!(
|
||||||
}
|
self, room_id, event, room_state,
|
||||||
}
|
StateEvent::RoomMember => on_state_member,
|
||||||
StateEvent::RoomName(name) => {
|
StateEvent::RoomName => on_state_name,
|
||||||
if let Some(ee) = &self.event_emitter {
|
StateEvent::RoomCanonicalAlias => on_state_canonical_alias,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
StateEvent::RoomAliases => on_state_aliases,
|
||||||
ee.on_state_name(Arc::clone(&room), &name).await;
|
StateEvent::RoomAvatar => on_state_avatar,
|
||||||
}
|
StateEvent::RoomPowerLevels => on_state_power_levels,
|
||||||
}
|
StateEvent::RoomTombstone => on_room_tombstone,
|
||||||
}
|
);
|
||||||
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_account_data_event(&self, room_id: &RoomId, event: &NonRoomEvent) {
|
pub(crate) async fn emit_account_data_event(
|
||||||
match event {
|
&self,
|
||||||
NonRoomEvent::Presence(presence) => {
|
room_id: &RoomId,
|
||||||
if let Some(ee) = &self.event_emitter {
|
event: &NonRoomEvent,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
room_state: RoomStateType,
|
||||||
ee.on_account_presence(Arc::clone(&room), &presence).await;
|
) {
|
||||||
}
|
emit_event!(
|
||||||
}
|
self, room_id, event, room_state,
|
||||||
}
|
NonRoomEvent::Presence => on_account_presence,
|
||||||
NonRoomEvent::IgnoredUserList(ignored) => {
|
NonRoomEvent::IgnoredUserList => on_account_ignored_users,
|
||||||
if let Some(ee) = &self.event_emitter {
|
NonRoomEvent::PushRules => on_account_push_rules,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
NonRoomEvent::FullyRead => on_account_data_fully_read,
|
||||||
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) {
|
pub(crate) async fn emit_ephemeral_event(
|
||||||
match event {
|
&self,
|
||||||
NonRoomEvent::Presence(presence) => {
|
room_id: &RoomId,
|
||||||
if let Some(ee) = &self.event_emitter {
|
event: &NonRoomEvent,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
room_state: RoomStateType,
|
||||||
ee.on_account_presence(Arc::clone(&room), &presence).await;
|
) {
|
||||||
}
|
emit_event!(
|
||||||
}
|
self, room_id, event, room_state,
|
||||||
}
|
NonRoomEvent::Presence => on_account_presence,
|
||||||
NonRoomEvent::IgnoredUserList(ignored) => {
|
NonRoomEvent::IgnoredUserList => on_account_ignored_users,
|
||||||
if let Some(ee) = &self.event_emitter {
|
NonRoomEvent::PushRules => on_account_push_rules,
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
NonRoomEvent::FullyRead => on_account_data_fully_read,
|
||||||
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_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(ee) = &self.event_emitter {
|
||||||
if let Some(room) = self.get_room(&room_id) {
|
match room_state {
|
||||||
ee.on_presence_event(Arc::clone(&room), &event).await;
|
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.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use crate::events::{
|
use crate::events::{
|
||||||
fully_read::FullyReadEvent,
|
fully_read::FullyReadEvent,
|
||||||
|
@ -36,8 +35,7 @@ use crate::events::{
|
||||||
StrippedRoomMember, StrippedRoomName, StrippedRoomPowerLevels,
|
StrippedRoomMember, StrippedRoomName, StrippedRoomPowerLevels,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::models::Room;
|
use crate::RoomState;
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
/// This trait allows any type implementing `EventEmitter` to specify event callbacks for each event.
|
/// 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.
|
/// The `AsyncClient` calls each method when the corresponding event is received.
|
||||||
|
@ -53,7 +51,7 @@ use tokio::sync::RwLock;
|
||||||
/// events::{
|
/// events::{
|
||||||
/// room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
/// room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||||
/// },
|
/// },
|
||||||
/// AsyncClient, AsyncClientConfig, EventEmitter, Room, SyncSettings,
|
/// AsyncClient, AsyncClientConfig, EventEmitter, RoomState, SyncSettings,
|
||||||
/// };
|
/// };
|
||||||
/// use tokio::sync::RwLock;
|
/// use tokio::sync::RwLock;
|
||||||
///
|
///
|
||||||
|
@ -61,23 +59,25 @@ use tokio::sync::RwLock;
|
||||||
///
|
///
|
||||||
/// #[async_trait::async_trait]
|
/// #[async_trait::async_trait]
|
||||||
/// impl EventEmitter for EventCallback {
|
/// impl EventEmitter for EventCallback {
|
||||||
/// async fn on_room_message(&self, room: Arc<RwLock<Room>>, event: &MessageEvent) {
|
/// async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
||||||
/// if let MessageEvent {
|
/// if let RoomState::Joined(room) = room {
|
||||||
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
/// if let MessageEvent {
|
||||||
/// sender,
|
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
/// ..
|
/// sender,
|
||||||
/// } = event
|
/// ..
|
||||||
/// {
|
/// } = event
|
||||||
/// let name = {
|
/// {
|
||||||
/// let room = room.read().await;
|
/// let name = {
|
||||||
/// let member = room.members.get(&sender).unwrap();
|
/// let room = room.read().await;
|
||||||
/// member
|
/// let member = room.members.get(&sender).unwrap();
|
||||||
/// .display_name
|
/// member
|
||||||
/// .as_ref()
|
/// .display_name
|
||||||
/// .map(ToString::to_string)
|
/// .as_ref()
|
||||||
/// .unwrap_or(sender.to_string())
|
/// .map(ToString::to_string)
|
||||||
/// };
|
/// .unwrap_or(sender.to_string())
|
||||||
/// println!("{}: {}", name, msg_body);
|
/// };
|
||||||
|
/// println!("{}: {}", name, msg_body);
|
||||||
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
|
@ -86,81 +86,76 @@ use tokio::sync::RwLock;
|
||||||
pub trait EventEmitter: Send + Sync {
|
pub trait EventEmitter: Send + Sync {
|
||||||
// ROOM EVENTS from `IncomingTimeline`
|
// ROOM EVENTS from `IncomingTimeline`
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMember` event.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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`
|
// `RoomEvent`s from `IncomingState`
|
||||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomMember` event.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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
|
// `AnyStrippedStateEvent`s
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomMember` event.
|
/// 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.
|
/// 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.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event.
|
||||||
async fn on_stripped_state_canonical_alias(
|
async fn on_stripped_state_canonical_alias(
|
||||||
&self,
|
&self,
|
||||||
_: Arc<RwLock<Room>>,
|
_: RoomState,
|
||||||
_: &StrippedRoomCanonicalAlias,
|
_: &StrippedRoomCanonicalAlias,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event.
|
/// 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.
|
/// 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.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event.
|
||||||
async fn on_stripped_state_power_levels(
|
async fn on_stripped_state_power_levels(&self, _: RoomState, _: &StrippedRoomPowerLevels) {}
|
||||||
&self,
|
|
||||||
_: Arc<RwLock<Room>>,
|
|
||||||
_: &StrippedRoomPowerLevels,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
|
/// 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`
|
// `NonRoomEvent` (this is a type alias from ruma_events) from `IncomingAccountData`
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomMember` event.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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
|
// `PresenceEvent` is a struct so there is only the one method
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
/// 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)]
|
#[cfg(test)]
|
||||||
|
@ -173,71 +168,71 @@ mod test {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl EventEmitter for EvEmitterTest {
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
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
|
self.0
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.push("stripped state member".to_string())
|
.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())
|
self.0.lock().await.push("stripped state name".to_string())
|
||||||
}
|
}
|
||||||
async fn on_stripped_state_canonical_alias(
|
async fn on_stripped_state_canonical_alias(
|
||||||
&self,
|
&self,
|
||||||
_: Arc<RwLock<Room>>,
|
_: RoomState,
|
||||||
_: &StrippedRoomCanonicalAlias,
|
_: &StrippedRoomCanonicalAlias,
|
||||||
) {
|
) {
|
||||||
self.0
|
self.0
|
||||||
|
@ -245,46 +240,38 @@ mod test {
|
||||||
.await
|
.await
|
||||||
.push("stripped state canonical".to_string())
|
.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
|
self.0
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.push("stripped state aliases".to_string())
|
.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
|
self.0
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.push("stripped state avatar".to_string())
|
.push("stripped state avatar".to_string())
|
||||||
}
|
}
|
||||||
async fn on_stripped_state_power_levels(
|
async fn on_stripped_state_power_levels(&self, _: RoomState, _: &StrippedRoomPowerLevels) {
|
||||||
&self,
|
|
||||||
_: Arc<RwLock<Room>>,
|
|
||||||
_: &StrippedRoomPowerLevels,
|
|
||||||
) {
|
|
||||||
self.0.lock().await.push("stripped state power".to_string())
|
self.0.lock().await.push("stripped state power".to_string())
|
||||||
}
|
}
|
||||||
async fn on_stripped_state_join_rules(
|
async fn on_stripped_state_join_rules(&self, _: RoomState, _: &StrippedRoomJoinRules) {
|
||||||
&self,
|
|
||||||
_: Arc<RwLock<Room>>,
|
|
||||||
_: &StrippedRoomJoinRules,
|
|
||||||
) {
|
|
||||||
self.0.lock().await.push("stripped state rules".to_string())
|
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())
|
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())
|
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())
|
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())
|
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())
|
self.0.lock().await.push("presence event".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,7 +317,6 @@ mod test {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
v.as_slice(),
|
v.as_slice(),
|
||||||
[
|
[
|
||||||
"state rules",
|
|
||||||
"state member",
|
"state member",
|
||||||
"state aliases",
|
"state aliases",
|
||||||
"state power",
|
"state power",
|
||||||
|
@ -340,7 +326,7 @@ mod test {
|
||||||
"message",
|
"message",
|
||||||
"account read",
|
"account read",
|
||||||
"account ignore",
|
"account ignore",
|
||||||
"presence event",
|
"presence event"
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -410,14 +396,13 @@ mod test {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
v.as_slice(),
|
v.as_slice(),
|
||||||
[
|
[
|
||||||
"message",
|
|
||||||
"state rules",
|
|
||||||
"state member",
|
"state member",
|
||||||
"state aliases",
|
"state aliases",
|
||||||
"state power",
|
"state power",
|
||||||
"state canonical",
|
"state canonical",
|
||||||
"state member",
|
"state member",
|
||||||
"state member"
|
"state member",
|
||||||
|
"message"
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ mod state;
|
||||||
pub mod test_builder;
|
pub mod test_builder;
|
||||||
|
|
||||||
pub use async_client::{AsyncClient, AsyncClientConfig, SyncSettings};
|
pub use async_client::{AsyncClient, AsyncClientConfig, SyncSettings};
|
||||||
pub use base_client::Client;
|
pub use base_client::{Client, RoomState, RoomStateType};
|
||||||
pub use event_emitter::EventEmitter;
|
pub use event_emitter::EventEmitter;
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
pub use matrix_sdk_crypto::{Device, TrustState};
|
pub use matrix_sdk_crypto::{Device, TrustState};
|
||||||
|
|
Loading…
Reference in New Issue