base: Re-introduce the event emitter.
parent
f9af880176
commit
a370eb1e37
|
@ -4,7 +4,7 @@ use tokio::time::{delay_for, Duration};
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
self,
|
self,
|
||||||
events::{room::member::MemberEventContent, StrippedStateEvent},
|
events::{room::member::MemberEventContent, StrippedStateEvent},
|
||||||
Client, ClientConfig, EventEmitter, SyncRoom, SyncSettings,
|
Client, ClientConfig, EventEmitter, RoomState, SyncSettings,
|
||||||
};
|
};
|
||||||
use matrix_sdk_common_macros::async_trait;
|
use matrix_sdk_common_macros::async_trait;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -23,7 +23,7 @@ impl AutoJoinBot {
|
||||||
impl EventEmitter for AutoJoinBot {
|
impl EventEmitter for AutoJoinBot {
|
||||||
async fn on_stripped_state_member(
|
async fn on_stripped_state_member(
|
||||||
&self,
|
&self,
|
||||||
room: SyncRoom,
|
room: RoomState,
|
||||||
room_member: &StrippedStateEvent<MemberEventContent>,
|
room_member: &StrippedStateEvent<MemberEventContent>,
|
||||||
_: Option<MemberEventContent>,
|
_: Option<MemberEventContent>,
|
||||||
) {
|
) {
|
||||||
|
@ -31,29 +31,30 @@ impl EventEmitter for AutoJoinBot {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let SyncRoom::Invited(room) = room {
|
if let RoomState::Invited(room) = room {
|
||||||
let room = room.read().await;
|
println!("Autojoining room {}", room.room_id());
|
||||||
println!("Autojoining room {}", room.room_id);
|
|
||||||
let mut delay = 2;
|
let mut delay = 2;
|
||||||
|
|
||||||
while let Err(err) = self.client.join_room_by_id(&room.room_id).await {
|
while let Err(err) = self.client.join_room_by_id(room.room_id()).await {
|
||||||
// retry autojoin due to synapse sending invites, before the
|
// retry autojoin due to synapse sending invites, before the
|
||||||
// invited user can join for more information see
|
// invited user can join for more information see
|
||||||
// https://github.com/matrix-org/synapse/issues/4345
|
// https://github.com/matrix-org/synapse/issues/4345
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Failed to join room {} ({:?}), retrying in {}s",
|
"Failed to join room {} ({:?}), retrying in {}s",
|
||||||
room.room_id, err, delay
|
room.room_id(),
|
||||||
|
err,
|
||||||
|
delay
|
||||||
);
|
);
|
||||||
|
|
||||||
delay_for(Duration::from_secs(delay)).await;
|
delay_for(Duration::from_secs(delay)).await;
|
||||||
delay *= 2;
|
delay *= 2;
|
||||||
|
|
||||||
if delay > 3600 {
|
if delay > 3600 {
|
||||||
eprintln!("Can't join room {} ({:?})", room.room_id, err);
|
eprintln!("Can't join room {} ({:?})", room.room_id(), err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("Successfully joined room {}", room.room_id);
|
println!("Successfully joined room {}", room.room_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +70,7 @@ async fn login_and_sync(
|
||||||
let client_config = ClientConfig::new().store_path(home);
|
let client_config = ClientConfig::new().store_path(home);
|
||||||
|
|
||||||
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
||||||
let mut client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
let client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
||||||
|
|
||||||
client
|
client
|
||||||
.login(username, password, None, Some("autojoin bot"))
|
.login(username, password, None, Some("autojoin bot"))
|
||||||
|
|
|
@ -6,7 +6,7 @@ use matrix_sdk::{
|
||||||
room::message::{MessageEventContent, TextMessageEventContent},
|
room::message::{MessageEventContent, TextMessageEventContent},
|
||||||
AnyMessageEventContent, SyncMessageEvent,
|
AnyMessageEventContent, SyncMessageEvent,
|
||||||
},
|
},
|
||||||
Client, ClientConfig, EventEmitter, JsonStore, SyncRoom, SyncSettings,
|
Client, ClientConfig, EventEmitter, RoomState, SyncSettings,
|
||||||
};
|
};
|
||||||
use matrix_sdk_common_macros::async_trait;
|
use matrix_sdk_common_macros::async_trait;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -25,8 +25,12 @@ impl CommandBot {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl EventEmitter for CommandBot {
|
impl EventEmitter for CommandBot {
|
||||||
async fn on_room_message(&self, room: SyncRoom, event: &SyncMessageEvent<MessageEventContent>) {
|
async fn on_room_message(
|
||||||
if let SyncRoom::Joined(room) = room {
|
&self,
|
||||||
|
room: RoomState,
|
||||||
|
event: &SyncMessageEvent<MessageEventContent>,
|
||||||
|
) {
|
||||||
|
if let RoomState::Joined(room) = room {
|
||||||
let msg_body = if let SyncMessageEvent {
|
let msg_body = if let SyncMessageEvent {
|
||||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
..
|
..
|
||||||
|
@ -41,15 +45,13 @@ impl EventEmitter for CommandBot {
|
||||||
let content = AnyMessageEventContent::RoomMessage(MessageEventContent::text_plain(
|
let content = AnyMessageEventContent::RoomMessage(MessageEventContent::text_plain(
|
||||||
"🎉🎊🥳 let's PARTY!! 🥳🎊🎉",
|
"🎉🎊🥳 let's PARTY!! 🥳🎊🎉",
|
||||||
));
|
));
|
||||||
// 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
|
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.room_id(), content, None)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -68,15 +70,14 @@ async fn login_and_sync(
|
||||||
let mut home = dirs::home_dir().expect("no home directory found");
|
let mut home = dirs::home_dir().expect("no home directory found");
|
||||||
home.push("party_bot");
|
home.push("party_bot");
|
||||||
|
|
||||||
let store = JsonStore::open(&home)?;
|
|
||||||
let client_config = ClientConfig::new()
|
let client_config = ClientConfig::new()
|
||||||
.proxy("http://localhost:8080")?
|
.proxy("http://localhost:8080")?
|
||||||
.disable_ssl_verification()
|
.disable_ssl_verification()
|
||||||
.state_store(Box::new(store));
|
.store_path(home);
|
||||||
|
|
||||||
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
||||||
// create a new Client with the given homeserver url and config
|
// create a new Client with the given homeserver url and config
|
||||||
let mut client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
let client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
||||||
|
|
||||||
client
|
client
|
||||||
.login(&username, &password, None, Some("command bot"))
|
.login(&username, &password, None, Some("command bot"))
|
||||||
|
|
|
@ -14,7 +14,7 @@ use matrix_sdk::{
|
||||||
room::message::{MessageEventContent, TextMessageEventContent},
|
room::message::{MessageEventContent, TextMessageEventContent},
|
||||||
SyncMessageEvent,
|
SyncMessageEvent,
|
||||||
},
|
},
|
||||||
Client, ClientConfig, EventEmitter, SyncRoom, SyncSettings,
|
Client, ClientConfig, EventEmitter, RoomState, SyncSettings,
|
||||||
};
|
};
|
||||||
use matrix_sdk_common_macros::async_trait;
|
use matrix_sdk_common_macros::async_trait;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -33,8 +33,12 @@ impl ImageBot {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl EventEmitter for ImageBot {
|
impl EventEmitter for ImageBot {
|
||||||
async fn on_room_message(&self, room: SyncRoom, event: &SyncMessageEvent<MessageEventContent>) {
|
async fn on_room_message(
|
||||||
if let SyncRoom::Joined(room) = room {
|
&self,
|
||||||
|
room: RoomState,
|
||||||
|
event: &SyncMessageEvent<MessageEventContent>,
|
||||||
|
) {
|
||||||
|
if let RoomState::Joined(room) = room {
|
||||||
let msg_body = if let SyncMessageEvent {
|
let msg_body = if let SyncMessageEvent {
|
||||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
..
|
..
|
||||||
|
@ -46,13 +50,17 @@ impl EventEmitter for ImageBot {
|
||||||
};
|
};
|
||||||
|
|
||||||
if msg_body.contains("!image") {
|
if msg_body.contains("!image") {
|
||||||
let room_id = room.read().await.room_id.clone();
|
|
||||||
|
|
||||||
println!("sending image");
|
println!("sending image");
|
||||||
let mut image = self.image.lock().await;
|
let mut image = self.image.lock().await;
|
||||||
|
|
||||||
self.client
|
self.client
|
||||||
.room_send_attachment(&room_id, "cat", &mime::IMAGE_JPEG, &mut *image, None)
|
.room_send_attachment(
|
||||||
|
room.room_id(),
|
||||||
|
"cat",
|
||||||
|
&mime::IMAGE_JPEG,
|
||||||
|
&mut *image,
|
||||||
|
None,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -75,7 +83,7 @@ async fn login_and_sync(
|
||||||
.disable_ssl_verification();
|
.disable_ssl_verification();
|
||||||
|
|
||||||
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
||||||
let mut client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
let client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
||||||
|
|
||||||
client
|
client
|
||||||
.login(&username, &password, None, Some("command bot"))
|
.login(&username, &password, None, Some("command bot"))
|
||||||
|
|
|
@ -7,7 +7,7 @@ use matrix_sdk::{
|
||||||
room::message::{MessageEventContent, TextMessageEventContent},
|
room::message::{MessageEventContent, TextMessageEventContent},
|
||||||
SyncMessageEvent,
|
SyncMessageEvent,
|
||||||
},
|
},
|
||||||
Client, ClientConfig, EventEmitter, SyncRoom, SyncSettings,
|
Client, ClientConfig, EventEmitter, RoomState, SyncSettings,
|
||||||
};
|
};
|
||||||
use matrix_sdk_common_macros::async_trait;
|
use matrix_sdk_common_macros::async_trait;
|
||||||
|
|
||||||
|
@ -15,21 +15,22 @@ struct EventCallback;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl EventEmitter for EventCallback {
|
impl EventEmitter for EventCallback {
|
||||||
async fn on_room_message(&self, room: SyncRoom, event: &SyncMessageEvent<MessageEventContent>) {
|
async fn on_room_message(
|
||||||
if let SyncRoom::Joined(room) = room {
|
&self,
|
||||||
|
room: RoomState,
|
||||||
|
event: &SyncMessageEvent<MessageEventContent>,
|
||||||
|
) {
|
||||||
|
if let RoomState::Joined(room) = room {
|
||||||
if let SyncMessageEvent {
|
if let SyncMessageEvent {
|
||||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
sender,
|
sender,
|
||||||
..
|
..
|
||||||
} = event
|
} = event
|
||||||
{
|
{
|
||||||
let name = {
|
let member = room.get_member(&sender).await.unwrap();
|
||||||
// any reads should be held for the shortest time possible to
|
let name = member
|
||||||
// avoid dead locks
|
.display_name()
|
||||||
let room = room.read().await;
|
.unwrap_or_else(|| member.user_id().as_str());
|
||||||
let member = room.joined_members.get(&sender).unwrap();
|
|
||||||
member.name()
|
|
||||||
};
|
|
||||||
println!("{}: {}", name, msg_body);
|
println!("{}: {}", name, msg_body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ async fn login(
|
||||||
.proxy("http://localhost:8080")?
|
.proxy("http://localhost:8080")?
|
||||||
.disable_ssl_verification();
|
.disable_ssl_verification();
|
||||||
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
||||||
let mut client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
let client = Client::new_with_config(homeserver_url, client_config).unwrap();
|
||||||
|
|
||||||
client.add_event_emitter(Box::new(EventCallback)).await;
|
client.add_event_emitter(Box::new(EventCallback)).await;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ use tracing::{debug, warn};
|
||||||
use tracing::{error, info, instrument};
|
use tracing::{error, info, instrument};
|
||||||
|
|
||||||
use matrix_sdk_base::{
|
use matrix_sdk_base::{
|
||||||
responses::SyncResponse, BaseClient, BaseClientConfig, JoinedRoom, Room, Session, Store,
|
responses::SyncResponse, BaseClient, BaseClientConfig, EventEmitter, JoinedRoom, Session, Store,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
|
@ -549,11 +549,12 @@ impl Client {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
///// Add `EventEmitter` to `Client`.
|
/// Add `EventEmitter` to `Client`.
|
||||||
/////
|
///
|
||||||
///// The methods of `EventEmitter` are called when the respective `RoomEvents` occur.
|
/// The methods of `EventEmitter` are called when the respective `RoomEvents` occur.
|
||||||
//pub async fn add_event_emitter(&mut self, emitter: Box<dyn EventEmitter>) {
|
pub async fn add_event_emitter(&self, emitter: Box<dyn EventEmitter>) {
|
||||||
//}
|
self.base_client.add_event_emitter(emitter).await;
|
||||||
|
}
|
||||||
|
|
||||||
// /// Returns the joined rooms this client knows about.
|
// /// Returns the joined rooms this client knows about.
|
||||||
// pub fn joined_rooms(&self) -> Arc<RwLock<HashMap<RoomId, Arc<RwLock<Room>>>>> {
|
// pub fn joined_rooms(&self) -> Arc<RwLock<HashMap<RoomId, Arc<RwLock<Room>>>>> {
|
||||||
|
|
|
@ -68,7 +68,7 @@ compile_error!("only one of 'native-tls' or 'rustls-tls' features can be enabled
|
||||||
pub use matrix_sdk_base::crypto::LocalTrust;
|
pub use matrix_sdk_base::crypto::LocalTrust;
|
||||||
pub use matrix_sdk_base::{
|
pub use matrix_sdk_base::{
|
||||||
Error as BaseError, EventEmitter, InvitedRoom, JoinedRoom, LeftRoom, RoomInfo, RoomMember,
|
Error as BaseError, EventEmitter, InvitedRoom, JoinedRoom, LeftRoom, RoomInfo, RoomMember,
|
||||||
Session,
|
RoomState, Session,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use matrix_sdk_common::*;
|
pub use matrix_sdk_common::*;
|
||||||
|
|
|
@ -58,6 +58,7 @@ use zeroize::Zeroizing;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Result,
|
error::Result,
|
||||||
|
event_emitter::Emitter,
|
||||||
responses::{
|
responses::{
|
||||||
AccountData, Ephemeral, InviteState, InvitedRoom as InvitedRoomResponse,
|
AccountData, Ephemeral, InviteState, InvitedRoom as InvitedRoomResponse,
|
||||||
JoinedRoom as JoinedRoomResponse, LeftRoom as LeftRoomResponse, MemberEvent, Presence,
|
JoinedRoom as JoinedRoomResponse, LeftRoom as LeftRoomResponse, MemberEvent, Presence,
|
||||||
|
@ -188,7 +189,7 @@ pub struct BaseClient {
|
||||||
store_passphrase: Arc<Zeroizing<String>>,
|
store_passphrase: Arc<Zeroizing<String>>,
|
||||||
/// Any implementor of EventEmitter will act as the callbacks for various
|
/// Any implementor of EventEmitter will act as the callbacks for various
|
||||||
/// events.
|
/// events.
|
||||||
event_emitter: Arc<RwLock<Option<Box<dyn EventEmitter>>>>,
|
event_emitter: Arc<RwLock<Option<Emitter>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(tarpaulin_include))]
|
#[cfg(not(tarpaulin_include))]
|
||||||
|
@ -419,6 +420,7 @@ impl BaseClient {
|
||||||
///
|
///
|
||||||
/// The methods of `EventEmitter` are called when the respective `RoomEvents` occur.
|
/// The methods of `EventEmitter` are called when the respective `RoomEvents` occur.
|
||||||
pub async fn add_event_emitter(&self, emitter: Box<dyn EventEmitter>) {
|
pub async fn add_event_emitter(&self, emitter: Box<dyn EventEmitter>) {
|
||||||
|
let emitter = Emitter { inner: emitter };
|
||||||
*self.event_emitter.write().await = Some(emitter);
|
*self.event_emitter.write().await = Some(emitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,7 +834,7 @@ impl BaseClient {
|
||||||
|
|
||||||
info!("Processed a sync response in {:?}", now.elapsed().unwrap());
|
info!("Processed a sync response in {:?}", now.elapsed().unwrap());
|
||||||
|
|
||||||
Ok(SyncResponse {
|
let response = SyncResponse {
|
||||||
next_batch: response.next_batch,
|
next_batch: response.next_batch,
|
||||||
rooms,
|
rooms,
|
||||||
presence: Presence {
|
presence: Presence {
|
||||||
|
@ -849,11 +851,16 @@ impl BaseClient {
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
};
|
||||||
|
|
||||||
|
if let Some(emitter) = self.event_emitter.read().await.as_ref() {
|
||||||
|
emitter.emit_sync(&response).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn apply_changes(&self, changes: &StateChanges) {
|
async fn apply_changes(&self, changes: &StateChanges) {
|
||||||
// TODO emit room changes here
|
|
||||||
for (room_id, room_info) in &changes.room_infos {
|
for (room_id, room_info) in &changes.room_infos {
|
||||||
if let Some(room) = self.get_bare_room(&room_id) {
|
if let Some(room) = self.get_bare_room(&room_id) {
|
||||||
room.update_summary(room_info.clone())
|
room.update_summary(room_info.clone())
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
// 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 std::ops::Deref;
|
||||||
|
|
||||||
use matrix_sdk_common::locks::RwLock;
|
use matrix_sdk_common::{events::AnySyncRoomEvent, identifiers::RoomId};
|
||||||
use serde_json::value::RawValue as RawJsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -38,13 +38,203 @@ use crate::{
|
||||||
tombstone::TombstoneEventContent,
|
tombstone::TombstoneEventContent,
|
||||||
},
|
},
|
||||||
typing::TypingEventContent,
|
typing::TypingEventContent,
|
||||||
BasicEvent, StrippedStateEvent, SyncEphemeralRoomEvent, SyncMessageEvent, SyncStateEvent,
|
AnyBasicEvent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent, AnySyncMessageEvent,
|
||||||
|
AnySyncStateEvent, BasicEvent, StrippedStateEvent, SyncEphemeralRoomEvent,
|
||||||
|
SyncMessageEvent, SyncStateEvent,
|
||||||
},
|
},
|
||||||
|
responses::SyncResponse,
|
||||||
rooms::RoomState,
|
rooms::RoomState,
|
||||||
Room,
|
|
||||||
};
|
};
|
||||||
use matrix_sdk_common_macros::async_trait;
|
use matrix_sdk_common_macros::async_trait;
|
||||||
|
|
||||||
|
pub(crate) struct Emitter {
|
||||||
|
pub(crate) inner: Box<dyn EventEmitter>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Emitter {
|
||||||
|
type Target = dyn EventEmitter;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&*self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Emitter {
|
||||||
|
fn get_room(&self, _room_id: &RoomId) -> Option<RoomState> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn emit_sync(&self, response: &SyncResponse) {
|
||||||
|
for (room_id, room_info) in &response.rooms.join {
|
||||||
|
if let Some(room) = self.get_room(room_id) {
|
||||||
|
for event in &room_info.ephemeral.events {
|
||||||
|
self.emit_ephemeral_event(room.clone(), event).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in &room_info.account_data.events {
|
||||||
|
self.emit_account_data_event(room.clone(), event).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in &room_info.state.events {
|
||||||
|
self.emit_state_event(room.clone(), event).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in &room_info.timeline.events {
|
||||||
|
self.emit_timeline_event(room.clone(), event).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (room_id, room_info) in &response.rooms.leave {
|
||||||
|
if let Some(room) = self.get_room(room_id) {
|
||||||
|
for event in &room_info.account_data.events {
|
||||||
|
self.emit_account_data_event(room.clone(), event).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in &room_info.state.events {
|
||||||
|
self.emit_state_event(room.clone(), event).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in &room_info.timeline.events {
|
||||||
|
self.emit_timeline_event(room.clone(), event).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (room_id, room_info) in &response.rooms.invite {
|
||||||
|
if let Some(room) = self.get_room(room_id) {
|
||||||
|
for event in &room_info.invite_state.events {
|
||||||
|
self.emit_stripped_state_event(room.clone(), event).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in &response.presence.events {
|
||||||
|
self.on_presence_event(event).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn emit_timeline_event(&self, room: RoomState, event: &AnySyncRoomEvent) {
|
||||||
|
match event {
|
||||||
|
AnySyncRoomEvent::State(event) => match event {
|
||||||
|
AnySyncStateEvent::RoomMember(e) => self.on_room_member(room, e).await,
|
||||||
|
AnySyncStateEvent::RoomName(e) => self.on_room_name(room, e).await,
|
||||||
|
AnySyncStateEvent::RoomCanonicalAlias(e) => {
|
||||||
|
self.on_room_canonical_alias(room, e).await
|
||||||
|
}
|
||||||
|
AnySyncStateEvent::RoomAliases(e) => self.on_room_aliases(room, e).await,
|
||||||
|
AnySyncStateEvent::RoomAvatar(e) => self.on_room_avatar(room, e).await,
|
||||||
|
AnySyncStateEvent::RoomPowerLevels(e) => self.on_room_power_levels(room, e).await,
|
||||||
|
AnySyncStateEvent::RoomTombstone(e) => self.on_room_tombstone(room, e).await,
|
||||||
|
AnySyncStateEvent::RoomJoinRules(e) => self.on_room_join_rules(room, e).await,
|
||||||
|
AnySyncStateEvent::Custom(e) => {
|
||||||
|
self.on_custom_event(room, &CustomEvent::State(e)).await
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
AnySyncRoomEvent::Message(event) => match event {
|
||||||
|
AnySyncMessageEvent::RoomMessage(e) => self.on_room_message(room, e).await,
|
||||||
|
AnySyncMessageEvent::RoomMessageFeedback(e) => {
|
||||||
|
self.on_room_message_feedback(room, e).await
|
||||||
|
}
|
||||||
|
AnySyncMessageEvent::RoomRedaction(e) => self.on_room_redaction(room, e).await,
|
||||||
|
AnySyncMessageEvent::Custom(e) => {
|
||||||
|
self.on_custom_event(room, &CustomEvent::Message(e)).await
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
AnySyncRoomEvent::RedactedState(_event) => {}
|
||||||
|
AnySyncRoomEvent::RedactedMessage(_event) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn emit_state_event(&self, room: RoomState, event: &AnySyncStateEvent) {
|
||||||
|
match event {
|
||||||
|
AnySyncStateEvent::RoomMember(member) => self.on_state_member(room, &member).await,
|
||||||
|
AnySyncStateEvent::RoomName(name) => self.on_state_name(room, &name).await,
|
||||||
|
AnySyncStateEvent::RoomCanonicalAlias(canonical) => {
|
||||||
|
self.on_state_canonical_alias(room, &canonical).await
|
||||||
|
}
|
||||||
|
AnySyncStateEvent::RoomAliases(aliases) => self.on_state_aliases(room, &aliases).await,
|
||||||
|
AnySyncStateEvent::RoomAvatar(avatar) => self.on_state_avatar(room, &avatar).await,
|
||||||
|
AnySyncStateEvent::RoomPowerLevels(power) => {
|
||||||
|
self.on_state_power_levels(room, &power).await
|
||||||
|
}
|
||||||
|
AnySyncStateEvent::RoomJoinRules(rules) => self.on_state_join_rules(room, &rules).await,
|
||||||
|
AnySyncStateEvent::RoomTombstone(tomb) => {
|
||||||
|
// TODO make `on_state_tombstone` method
|
||||||
|
self.on_room_tombstone(room, &tomb).await
|
||||||
|
}
|
||||||
|
AnySyncStateEvent::Custom(custom) => {
|
||||||
|
self.on_custom_event(room, &CustomEvent::State(custom))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn emit_stripped_state_event(
|
||||||
|
&self,
|
||||||
|
// TODO these events are only emitted in invited rooms.
|
||||||
|
room: RoomState,
|
||||||
|
event: &AnyStrippedStateEvent,
|
||||||
|
) {
|
||||||
|
match event {
|
||||||
|
AnyStrippedStateEvent::RoomMember(member) => {
|
||||||
|
self.on_stripped_state_member(room, &member, None).await
|
||||||
|
}
|
||||||
|
AnyStrippedStateEvent::RoomName(name) => self.on_stripped_state_name(room, &name).await,
|
||||||
|
AnyStrippedStateEvent::RoomCanonicalAlias(canonical) => {
|
||||||
|
self.on_stripped_state_canonical_alias(room, &canonical)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
AnyStrippedStateEvent::RoomAliases(aliases) => {
|
||||||
|
self.on_stripped_state_aliases(room, &aliases).await
|
||||||
|
}
|
||||||
|
AnyStrippedStateEvent::RoomAvatar(avatar) => {
|
||||||
|
self.on_stripped_state_avatar(room, &avatar).await
|
||||||
|
}
|
||||||
|
AnyStrippedStateEvent::RoomPowerLevels(power) => {
|
||||||
|
self.on_stripped_state_power_levels(room, &power).await
|
||||||
|
}
|
||||||
|
AnyStrippedStateEvent::RoomJoinRules(rules) => {
|
||||||
|
self.on_stripped_state_join_rules(room, &rules).await
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn emit_account_data_event(&self, room: RoomState, event: &AnyBasicEvent) {
|
||||||
|
match event {
|
||||||
|
AnyBasicEvent::Presence(presence) => self.on_non_room_presence(room, &presence).await,
|
||||||
|
AnyBasicEvent::IgnoredUserList(ignored) => {
|
||||||
|
self.on_non_room_ignored_users(room, &ignored).await
|
||||||
|
}
|
||||||
|
AnyBasicEvent::PushRules(rules) => self.on_non_room_push_rules(room, &rules).await,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn emit_ephemeral_event(
|
||||||
|
&self,
|
||||||
|
room: RoomState,
|
||||||
|
event: &AnySyncEphemeralRoomEvent,
|
||||||
|
) {
|
||||||
|
match event {
|
||||||
|
AnySyncEphemeralRoomEvent::FullyRead(full_read) => {
|
||||||
|
self.on_non_room_fully_read(room, full_read).await
|
||||||
|
}
|
||||||
|
AnySyncEphemeralRoomEvent::Typing(typing) => {
|
||||||
|
self.on_non_room_typing(room, typing).await
|
||||||
|
}
|
||||||
|
AnySyncEphemeralRoomEvent::Receipt(receipt) => {
|
||||||
|
self.on_non_room_receipt(room, receipt).await
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This represents the various "unrecognized" events.
|
/// This represents the various "unrecognized" events.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum CustomEvent<'c> {
|
pub enum CustomEvent<'c> {
|
||||||
|
@ -259,7 +449,7 @@ pub trait EventEmitter: Send + Sync {
|
||||||
|
|
||||||
// `PresenceEvent` is a struct so there is only the one method
|
// `PresenceEvent` is a struct so there is only the one method
|
||||||
/// Fires when `Client` receives a `NonRoomEvent::RoomAliases` event.
|
/// Fires when `Client` receives a `NonRoomEvent::RoomAliases` event.
|
||||||
async fn on_presence_event(&self, _: RoomState, _: &PresenceEvent) {}
|
async fn on_presence_event(&self, _: &PresenceEvent) {}
|
||||||
|
|
||||||
/// Fires when `Client` receives a `Event::Custom` event or if deserialization fails
|
/// Fires when `Client` receives a `Event::Custom` event or if deserialization fails
|
||||||
/// because the event was unknown to ruma.
|
/// because the event was unknown to ruma.
|
||||||
|
@ -477,7 +667,7 @@ mod test {
|
||||||
) {
|
) {
|
||||||
self.0.lock().await.push("receipt event".to_string())
|
self.0.lock().await.push("receipt event".to_string())
|
||||||
}
|
}
|
||||||
async fn on_presence_event(&self, _: RoomState, _: &PresenceEvent) {
|
async fn on_presence_event(&self, _: &PresenceEvent) {
|
||||||
self.0.lock().await.push("presence event".to_string())
|
self.0.lock().await.push("presence event".to_string())
|
||||||
}
|
}
|
||||||
async fn on_unrecognized_event(&self, _: RoomState, _: &RawJsonValue) {
|
async fn on_unrecognized_event(&self, _: RoomState, _: &RawJsonValue) {
|
||||||
|
|
|
@ -64,6 +64,7 @@ pub struct JoinedRoom {
|
||||||
pub(crate) inner: Room,
|
pub(crate) inner: Room,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO do we wan't to deref here or have separate implementations.
|
||||||
impl Deref for JoinedRoom {
|
impl Deref for JoinedRoom {
|
||||||
type Target = Room;
|
type Target = Room;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue