move matrix_sdk_base::EventHandler to matrix_sdk
parent
e9dff24ba7
commit
382ec01bc3
|
@ -4,7 +4,8 @@ use tokio::time::{sleep, Duration};
|
|||
use matrix_sdk::{
|
||||
self, async_trait,
|
||||
events::{room::member::MemberEventContent, StrippedStateEvent},
|
||||
room, BaseRoom, Client, ClientConfig, EventHandler, SyncSettings,
|
||||
room::Room,
|
||||
Client, ClientConfig, EventHandler, SyncSettings,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
|
@ -22,7 +23,7 @@ impl AutoJoinBot {
|
|||
impl EventHandler for AutoJoinBot {
|
||||
async fn on_stripped_state_member(
|
||||
&self,
|
||||
room: BaseRoom,
|
||||
room: Room,
|
||||
room_member: &StrippedStateEvent<MemberEventContent>,
|
||||
_: Option<MemberEventContent>,
|
||||
) {
|
||||
|
@ -30,7 +31,7 @@ impl EventHandler for AutoJoinBot {
|
|||
return;
|
||||
}
|
||||
|
||||
if let Some(room) = room::Invited::new(self.client.clone(), room) {
|
||||
if let Room::Invited(room) = room {
|
||||
println!("Autojoining room {}", room.room_id());
|
||||
let mut delay = 2;
|
||||
|
||||
|
|
|
@ -6,27 +6,23 @@ use matrix_sdk::{
|
|||
room::message::{MessageEventContent, MessageType, TextMessageEventContent},
|
||||
AnyMessageEventContent, SyncMessageEvent,
|
||||
},
|
||||
room::Joined,
|
||||
BaseRoom, Client, ClientConfig, EventHandler, SyncSettings,
|
||||
room::Room,
|
||||
Client, ClientConfig, EventHandler, SyncSettings,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
struct CommandBot {
|
||||
/// This clone of the `Client` will send requests to the server,
|
||||
/// while the other keeps us in sync with the server using `sync`.
|
||||
client: Client,
|
||||
}
|
||||
struct CommandBot;
|
||||
|
||||
impl CommandBot {
|
||||
pub fn new(client: Client) -> Self {
|
||||
Self { client }
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for CommandBot {
|
||||
async fn on_room_message(&self, room: BaseRoom, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
if let Some(room) = Joined::new(self.client.clone(), room) {
|
||||
async fn on_room_message(&self, room: Room, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
if let Room::Joined(room) = room {
|
||||
let msg_body = if let SyncMessageEvent {
|
||||
content:
|
||||
MessageEventContent {
|
||||
|
@ -85,9 +81,7 @@ async fn login_and_sync(
|
|||
client.sync_once(SyncSettings::default()).await.unwrap();
|
||||
// add our CommandBot to be notified of incoming messages, we do this after the initial
|
||||
// sync to avoid responding to messages before the bot was running.
|
||||
client
|
||||
.set_event_handler(Box::new(CommandBot::new(client.clone())))
|
||||
.await;
|
||||
client.set_event_handler(Box::new(CommandBot::new())).await;
|
||||
|
||||
// since we called `sync_once` before we entered our sync loop we must pass
|
||||
// that sync token to `sync`
|
||||
|
|
|
@ -14,27 +14,26 @@ use matrix_sdk::{
|
|||
room::message::{MessageEventContent, MessageType, TextMessageEventContent},
|
||||
SyncMessageEvent,
|
||||
},
|
||||
room::Joined,
|
||||
BaseRoom, Client, EventHandler, SyncSettings,
|
||||
room::Room,
|
||||
Client, EventHandler, SyncSettings,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
struct ImageBot {
|
||||
client: Client,
|
||||
image: Arc<Mutex<File>>,
|
||||
}
|
||||
|
||||
impl ImageBot {
|
||||
pub fn new(client: Client, image: File) -> Self {
|
||||
pub fn new(image: File) -> Self {
|
||||
let image = Arc::new(Mutex::new(image));
|
||||
Self { client, image }
|
||||
Self { image }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for ImageBot {
|
||||
async fn on_room_message(&self, room: BaseRoom, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
if let Some(room) = Joined::new(self.client.clone(), room) {
|
||||
async fn on_room_message(&self, room: Room, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
if let Room::Joined(room) = room {
|
||||
let msg_body = if let SyncMessageEvent {
|
||||
content:
|
||||
MessageEventContent {
|
||||
|
@ -80,7 +79,7 @@ async fn login_and_sync(
|
|||
|
||||
client.sync_once(SyncSettings::default()).await.unwrap();
|
||||
client
|
||||
.set_event_handler(Box::new(ImageBot::new(client.clone(), image)))
|
||||
.set_event_handler(Box::new(ImageBot::new(image)))
|
||||
.await;
|
||||
|
||||
let settings = SyncSettings::default().token(client.sync_token().await.unwrap());
|
||||
|
|
|
@ -7,15 +7,16 @@ use matrix_sdk::{
|
|||
room::message::{MessageEventContent, MessageType, TextMessageEventContent},
|
||||
SyncMessageEvent,
|
||||
},
|
||||
BaseRoom, Client, EventHandler, RoomType, SyncSettings,
|
||||
room::Room,
|
||||
Client, EventHandler, SyncSettings,
|
||||
};
|
||||
|
||||
struct EventCallback;
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for EventCallback {
|
||||
async fn on_room_message(&self, room: BaseRoom, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
if room.room_type() == RoomType::Joined {
|
||||
async fn on_room_message(&self, room: Room, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
if let Room::Joined(room) = room {
|
||||
if let SyncMessageEvent {
|
||||
content:
|
||||
MessageEventContent {
|
||||
|
|
|
@ -40,8 +40,7 @@ use tracing::{debug, warn};
|
|||
use tracing::{error, info, instrument};
|
||||
|
||||
use matrix_sdk_base::{
|
||||
deserialized_responses::SyncResponse, BaseClient, BaseClientConfig, EventHandler, Session,
|
||||
Store,
|
||||
deserialized_responses::SyncResponse, BaseClient, BaseClientConfig, Session, Store,
|
||||
};
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
|
@ -82,6 +81,7 @@ use matrix_sdk_common::{
|
|||
assign,
|
||||
identifiers::{DeviceIdBox, EventId, RoomId, RoomIdOrAliasId, ServerName, UserId},
|
||||
instant::{Duration, Instant},
|
||||
locks::RwLock,
|
||||
presence::PresenceState,
|
||||
uuid::Uuid,
|
||||
FromHttpResponseError, UInt,
|
||||
|
@ -106,9 +106,11 @@ use crate::{
|
|||
#[cfg(feature = "encryption")]
|
||||
use crate::{
|
||||
device::{Device, UserDevices},
|
||||
event_handler::Handler,
|
||||
identifiers::DeviceId,
|
||||
sas::Sas,
|
||||
verification_request::VerificationRequest,
|
||||
EventHandler,
|
||||
};
|
||||
|
||||
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
@ -139,6 +141,9 @@ pub struct Client {
|
|||
key_claim_lock: Arc<Mutex<()>>,
|
||||
pub(crate) members_request_locks: Arc<DashMap<RoomId, Arc<Mutex<()>>>>,
|
||||
pub(crate) typing_notice_times: Arc<DashMap<RoomId, Instant>>,
|
||||
/// Any implementor of EventHandler will act as the callbacks for various
|
||||
/// events.
|
||||
event_handler: Arc<RwLock<Option<Handler>>>,
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
|
@ -396,6 +401,7 @@ impl Client {
|
|||
key_claim_lock: Arc::new(Mutex::new(())),
|
||||
members_request_locks: Arc::new(DashMap::new()),
|
||||
typing_notice_times: Arc::new(DashMap::new()),
|
||||
event_handler: Arc::new(RwLock::new(None)),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -541,7 +547,11 @@ impl Client {
|
|||
///
|
||||
/// The methods of `EventHandler` are called when the respective `RoomEvents` occur.
|
||||
pub async fn set_event_handler(&self, handler: Box<dyn EventHandler>) {
|
||||
self.base_client.set_event_handler(handler).await;
|
||||
let handler = Handler {
|
||||
inner: handler,
|
||||
client: self.clone(),
|
||||
};
|
||||
*self.event_handler.write().await = Some(handler);
|
||||
}
|
||||
|
||||
/// Get all the rooms the client knows about.
|
||||
|
@ -1180,8 +1190,13 @@ impl Client {
|
|||
+ SYNC_REQUEST_TIMEOUT;
|
||||
|
||||
let response = self.send(request, Some(timeout)).await?;
|
||||
let sync_response = self.base_client.receive_sync_response(response).await?;
|
||||
|
||||
Ok(self.base_client.receive_sync_response(response).await?)
|
||||
if let Some(handler) = self.event_handler.read().await.as_ref() {
|
||||
handler.handle_sync(&sync_response).await;
|
||||
}
|
||||
|
||||
Ok(sync_response)
|
||||
}
|
||||
|
||||
/// Repeatedly call sync to synchronize the client state with the server.
|
||||
|
|
|
@ -47,14 +47,14 @@ use crate::{
|
|||
AnySyncStateEvent, BasicEvent, StrippedStateEvent, SyncEphemeralRoomEvent,
|
||||
SyncMessageEvent, SyncStateEvent,
|
||||
},
|
||||
rooms::Room,
|
||||
Store,
|
||||
room::Room,
|
||||
Client,
|
||||
};
|
||||
use matrix_sdk_common::async_trait;
|
||||
|
||||
pub(crate) struct Handler {
|
||||
pub(crate) inner: Box<dyn EventHandler>,
|
||||
pub(crate) store: Store,
|
||||
pub(crate) client: Client,
|
||||
}
|
||||
|
||||
impl Deref for Handler {
|
||||
|
@ -67,7 +67,7 @@ impl Deref for Handler {
|
|||
|
||||
impl Handler {
|
||||
fn get_room(&self, room_id: &RoomId) -> Option<Room> {
|
||||
self.store.get_room(room_id)
|
||||
self.client.get_room(room_id)
|
||||
}
|
||||
|
||||
pub(crate) async fn handle_sync(&self, response: &SyncResponse) {
|
||||
|
@ -270,22 +270,23 @@ pub enum CustomEvent<'c> {
|
|||
/// # use std::ops::Deref;
|
||||
/// # use std::sync::Arc;
|
||||
/// # use std::{env, process::exit};
|
||||
/// # use matrix_sdk_base::{
|
||||
/// # self,
|
||||
/// # use matrix_sdk::{
|
||||
/// # async_trait,
|
||||
/// # EventHandler,
|
||||
/// # events::{
|
||||
/// # room::message::{MessageEventContent, MessageType, TextMessageEventContent},
|
||||
/// # SyncMessageEvent
|
||||
/// # },
|
||||
/// # EventHandler, Room, RoomType,
|
||||
/// # locks::RwLock,
|
||||
/// # room::Room,
|
||||
/// # };
|
||||
/// # use matrix_sdk_common::{async_trait, locks::RwLock};
|
||||
///
|
||||
/// struct EventCallback;
|
||||
///
|
||||
/// #[async_trait]
|
||||
/// impl EventHandler for EventCallback {
|
||||
/// async fn on_room_message(&self, room: Room, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
/// if room.room_type() == RoomType::Joined {
|
||||
/// if let Room::Joined(room) = room {
|
||||
/// if let SyncMessageEvent {
|
||||
/// content:
|
||||
/// MessageEventContent {
|
||||
|
@ -458,8 +459,9 @@ pub trait EventHandler: Send + Sync {
|
|||
mod test {
|
||||
use super::*;
|
||||
use matrix_sdk_common::{async_trait, locks::Mutex};
|
||||
use matrix_sdk_test::{async_test, sync_response, SyncResponseFile};
|
||||
use std::sync::Arc;
|
||||
use matrix_sdk_test::{async_test, test_json};
|
||||
use mockito::{mock, Matcher};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub use wasm_bindgen_test::*;
|
||||
|
@ -667,19 +669,34 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
use crate::{identifiers::user_id, BaseClient, Session};
|
||||
use crate::{identifiers::user_id, Client, Session, SyncSettings};
|
||||
|
||||
async fn get_client() -> BaseClient {
|
||||
async fn get_client() -> Client {
|
||||
let session = Session {
|
||||
access_token: "1234".to_owned(),
|
||||
user_id: user_id!("@example:example.com"),
|
||||
device_id: "DEVICEID".into(),
|
||||
};
|
||||
let client = BaseClient::new().unwrap();
|
||||
let homeserver = url::Url::parse(&mockito::server_url()).unwrap();
|
||||
let client = Client::new(homeserver).unwrap();
|
||||
client.restore_login(session).await.unwrap();
|
||||
client
|
||||
}
|
||||
|
||||
async fn mock_sync(client: Client, response: String) {
|
||||
let _m = mock(
|
||||
"GET",
|
||||
Matcher::Regex(r"^/_matrix/client/r0/sync\?.*$".to_string()),
|
||||
)
|
||||
.with_status(200)
|
||||
.match_header("authorization", "Bearer 1234")
|
||||
.with_body(response)
|
||||
.create();
|
||||
|
||||
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
|
||||
let _response = client.sync_once(sync_settings).await.unwrap();
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn event_handler_joined() {
|
||||
let vec = Arc::new(Mutex::new(Vec::new()));
|
||||
|
@ -688,9 +705,7 @@ mod test {
|
|||
|
||||
let client = get_client().await;
|
||||
client.set_event_handler(handler).await;
|
||||
|
||||
let response = sync_response(SyncResponseFile::Default);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
mock_sync(client, test_json::SYNC.to_string()).await;
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
||||
|
@ -720,9 +735,7 @@ mod test {
|
|||
|
||||
let client = get_client().await;
|
||||
client.set_event_handler(handler).await;
|
||||
|
||||
let response = sync_response(SyncResponseFile::Invite);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
mock_sync(client, test_json::INVITE_SYNC.to_string()).await;
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
||||
|
@ -743,9 +756,7 @@ mod test {
|
|||
|
||||
let client = get_client().await;
|
||||
client.set_event_handler(handler).await;
|
||||
|
||||
let response = sync_response(SyncResponseFile::Leave);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
mock_sync(client, test_json::LEAVE_SYNC.to_string()).await;
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
||||
|
@ -773,9 +784,7 @@ mod test {
|
|||
|
||||
let client = get_client().await;
|
||||
client.set_event_handler(handler).await;
|
||||
|
||||
let response = sync_response(SyncResponseFile::All);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
mock_sync(client, test_json::MORE_SYNC.to_string()).await;
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
||||
|
@ -798,9 +807,7 @@ mod test {
|
|||
|
||||
let client = get_client().await;
|
||||
client.set_event_handler(handler).await;
|
||||
|
||||
let response = sync_response(SyncResponseFile::Voip);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
mock_sync(client, test_json::VOIP_SYNC.to_string()).await;
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
|
@ -68,8 +68,8 @@ compile_error!("only one of 'native-tls' or 'rustls-tls' features can be enabled
|
|||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
pub use matrix_sdk_base::crypto::{EncryptionInfo, LocalTrust};
|
||||
pub use matrix_sdk_base::{
|
||||
CustomEvent, Error as BaseError, EventHandler, Room as BaseRoom, RoomInfo, RoomMember,
|
||||
RoomType, Session, StateChanges, StoreError,
|
||||
Error as BaseError, Room as BaseRoom, RoomInfo, RoomMember, RoomType, Session, StateChanges,
|
||||
StoreError,
|
||||
};
|
||||
|
||||
pub use matrix_sdk_common::*;
|
||||
|
@ -77,6 +77,7 @@ pub use reqwest;
|
|||
|
||||
mod client;
|
||||
mod error;
|
||||
mod event_handler;
|
||||
mod http_client;
|
||||
/// High-level room API
|
||||
pub mod room;
|
||||
|
@ -93,6 +94,7 @@ pub use client::{Client, ClientConfig, LoopCtrl, SyncSettings};
|
|||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
pub use device::Device;
|
||||
pub use error::{Error, HttpError, Result};
|
||||
pub use event_handler::{CustomEvent, EventHandler};
|
||||
pub use http_client::HttpSend;
|
||||
#[cfg(feature = "encryption")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
|
|
|
@ -62,11 +62,9 @@ use zeroize::Zeroizing;
|
|||
|
||||
use crate::{
|
||||
error::Result,
|
||||
event_handler::Handler,
|
||||
rooms::{Room, RoomInfo, RoomType},
|
||||
session::Session,
|
||||
store::{ambiguity_map::AmbiguityCache, Result as StoreResult, StateChanges, Store},
|
||||
EventHandler,
|
||||
};
|
||||
|
||||
pub type Token = String;
|
||||
|
@ -172,9 +170,6 @@ pub struct BaseClient {
|
|||
cryptostore: Arc<Mutex<Option<Box<dyn CryptoStore>>>>,
|
||||
store_path: Arc<Option<PathBuf>>,
|
||||
store_passphrase: Arc<Option<Zeroizing<String>>>,
|
||||
/// Any implementor of EventHandler will act as the callbacks for various
|
||||
/// events.
|
||||
event_handler: Arc<RwLock<Option<Handler>>>,
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
|
@ -320,7 +315,6 @@ impl BaseClient {
|
|||
cryptostore: Mutex::new(crypto_store).into(),
|
||||
store_path: config.store_path.into(),
|
||||
store_passphrase: config.passphrase.into(),
|
||||
event_handler: RwLock::new(None).into(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -419,17 +413,6 @@ impl BaseClient {
|
|||
self.sync_token.read().await.clone()
|
||||
}
|
||||
|
||||
/// Add `EventHandler` to `Client`.
|
||||
///
|
||||
/// The methods of `EventHandler` are called when the respective `RoomEvents` occur.
|
||||
pub async fn set_event_handler(&self, handler: Box<dyn EventHandler>) {
|
||||
let handler = Handler {
|
||||
inner: handler,
|
||||
store: self.store.clone(),
|
||||
};
|
||||
*self.event_handler.write().await = Some(handler);
|
||||
}
|
||||
|
||||
async fn handle_timeline(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
|
@ -934,10 +917,6 @@ impl BaseClient {
|
|||
},
|
||||
};
|
||||
|
||||
if let Some(handler) = self.event_handler.read().await.as_ref() {
|
||||
handler.handle_sync(&response).await;
|
||||
}
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
|
|
|
@ -46,12 +46,10 @@ pub use matrix_sdk_common::*;
|
|||
|
||||
mod client;
|
||||
mod error;
|
||||
mod event_handler;
|
||||
mod rooms;
|
||||
mod session;
|
||||
mod store;
|
||||
|
||||
pub use event_handler::{CustomEvent, EventHandler};
|
||||
pub use rooms::{Room, RoomInfo, RoomMember, RoomType};
|
||||
pub use store::{StateChanges, StateStore, Store, StoreError};
|
||||
|
||||
|
|
Loading…
Reference in New Issue