base: Upcast the bare rooms based on the membership state
parent
7abf0c8805
commit
f9af880176
|
@ -41,7 +41,7 @@ use tracing::{debug, warn};
|
|||
use tracing::{error, info, instrument};
|
||||
|
||||
use matrix_sdk_base::{
|
||||
responses::SyncResponse, BaseClient, BaseClientConfig, Room, Session, Store,
|
||||
responses::SyncResponse, BaseClient, BaseClientConfig, JoinedRoom, Room, Session, Store,
|
||||
};
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
|
@ -575,8 +575,8 @@ impl Client {
|
|||
/// # Arguments
|
||||
///
|
||||
/// `room_id` - The unique id of the room that should be fetched.
|
||||
pub fn get_joined_room(&self, room_id: &RoomId) -> Option<Room> {
|
||||
self.base_client.get_room(room_id)
|
||||
pub fn get_joined_room(&self, room_id: &RoomId) -> Option<JoinedRoom> {
|
||||
self.base_client.get_joined_room(room_id)
|
||||
}
|
||||
|
||||
///// Get an invited room with the given room id.
|
||||
|
@ -1150,7 +1150,7 @@ impl Client {
|
|||
let _guard = mutex.lock().await;
|
||||
|
||||
{
|
||||
let room = self.base_client.get_room(room_id).unwrap();
|
||||
let room = self.get_joined_room(room_id).unwrap();
|
||||
let members = room.joined_user_ids().await;
|
||||
// TODO don't collect here.
|
||||
let members_iter: Vec<UserId> = members.collect().await;
|
||||
|
@ -1252,17 +1252,17 @@ impl Client {
|
|||
/// Returns true if a room with the given id was found and the room is
|
||||
/// encrypted, false if the room wasn't found or isn't encrypted.
|
||||
async fn is_room_encrypted(&self, room_id: &RoomId) -> bool {
|
||||
match self.base_client.get_room(room_id) {
|
||||
Some(r) => r.is_encrypted(),
|
||||
None => false,
|
||||
}
|
||||
self.base_client
|
||||
.get_room(room_id)
|
||||
.map(|r| r.is_encrypted())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
async fn are_members_synced(&self, room_id: &RoomId) -> bool {
|
||||
match self.base_client.get_room(room_id) {
|
||||
Some(r) => r.are_members_synced(),
|
||||
None => true,
|
||||
}
|
||||
self.base_client
|
||||
.get_room(room_id)
|
||||
.map(|r| r.are_members_synced())
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
/// Send an attachment to a room.
|
||||
|
|
|
@ -66,7 +66,10 @@ compile_error!("only one of 'native-tls' or 'rustls-tls' features can be enabled
|
|||
#[cfg(feature = "encryption")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
pub use matrix_sdk_base::crypto::LocalTrust;
|
||||
pub use matrix_sdk_base::{Error as BaseError, Room, RoomInfo, RoomMember, Session};
|
||||
pub use matrix_sdk_base::{
|
||||
Error as BaseError, EventEmitter, InvitedRoom, JoinedRoom, LeftRoom, RoomInfo, RoomMember,
|
||||
Session,
|
||||
};
|
||||
|
||||
pub use matrix_sdk_common::*;
|
||||
pub use reqwest;
|
||||
|
|
|
@ -59,12 +59,14 @@ use zeroize::Zeroizing;
|
|||
use crate::{
|
||||
error::Result,
|
||||
responses::{
|
||||
AccountData, Ephemeral, InviteState, InvitedRoom, JoinedRoom, LeftRoom, MemberEvent,
|
||||
Presence, Rooms, State, StrippedMemberEvent, SyncResponse, Timeline,
|
||||
AccountData, Ephemeral, InviteState, InvitedRoom as InvitedRoomResponse,
|
||||
JoinedRoom as JoinedRoomResponse, LeftRoom as LeftRoomResponse, MemberEvent, Presence,
|
||||
Rooms, State, StrippedMemberEvent, SyncResponse, Timeline,
|
||||
},
|
||||
rooms::{Room, RoomInfo, RoomType, StrippedRoom, StrippedRoomInfo},
|
||||
session::Session,
|
||||
store::{StateChanges, Store},
|
||||
EventEmitter, InvitedRoom, JoinedRoom, LeftRoom, RoomState,
|
||||
};
|
||||
|
||||
pub type Token = String;
|
||||
|
@ -163,21 +165,6 @@ pub enum RoomStateType {
|
|||
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. `RoomState` is generic
|
||||
/// so it can be used to represent a `Room` or an `Arc<RwLock<Room>>`
|
||||
#[derive(Debug)]
|
||||
pub enum RoomState<R> {
|
||||
/// A room from the `join` section of a sync response.
|
||||
Joined(R),
|
||||
/// A room from the `leave` section of a sync response.
|
||||
Left(R),
|
||||
/// A room from the `invite` section of a sync response.
|
||||
Invited(R),
|
||||
}
|
||||
|
||||
/// A no IO Client implementation.
|
||||
///
|
||||
/// This Client is a state machine that receives responses and events and
|
||||
|
@ -199,6 +186,9 @@ pub struct BaseClient {
|
|||
cryptostore: Arc<Mutex<Option<Box<dyn CryptoStore>>>>,
|
||||
store_path: Arc<Option<PathBuf>>,
|
||||
store_passphrase: Arc<Zeroizing<String>>,
|
||||
/// Any implementor of EventEmitter will act as the callbacks for various
|
||||
/// events.
|
||||
event_emitter: Arc<RwLock<Option<Box<dyn EventEmitter>>>>,
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
|
@ -303,21 +293,21 @@ impl BaseClient {
|
|||
};
|
||||
|
||||
Ok(BaseClient {
|
||||
session: Arc::new(RwLock::new(None)),
|
||||
sync_token: Arc::new(RwLock::new(None)),
|
||||
session: RwLock::new(None).into(),
|
||||
sync_token: RwLock::new(None).into(),
|
||||
store,
|
||||
rooms: Arc::new(DashMap::new()),
|
||||
stripped_rooms: Arc::new(DashMap::new()),
|
||||
rooms: DashMap::new().into(),
|
||||
stripped_rooms: DashMap::new().into(),
|
||||
#[cfg(feature = "encryption")]
|
||||
olm: Arc::new(Mutex::new(None)),
|
||||
olm: Mutex::new(None).into(),
|
||||
#[cfg(feature = "encryption")]
|
||||
cryptostore: Arc::new(Mutex::new(config.crypto_store)),
|
||||
store_path: Arc::new(config.store_path),
|
||||
store_passphrase: Arc::new(
|
||||
config
|
||||
cryptostore: Mutex::new(config.crypto_store).into(),
|
||||
store_path: config.store_path.into(),
|
||||
store_passphrase: config
|
||||
.passphrase
|
||||
.unwrap_or_else(|| Zeroizing::new("DEFAULT_PASSPHRASE".to_owned())),
|
||||
),
|
||||
.unwrap_or_else(|| Zeroizing::new("DEFAULT_PASSPHRASE".to_owned()))
|
||||
.into(),
|
||||
event_emitter: RwLock::new(None).into(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -425,6 +415,13 @@ impl BaseClient {
|
|||
self.sync_token.read().await.clone()
|
||||
}
|
||||
|
||||
/// Add `EventEmitter` to `Client`.
|
||||
///
|
||||
/// The methods of `EventEmitter` are called when the respective `RoomEvents` occur.
|
||||
pub async fn add_event_emitter(&self, emitter: Box<dyn EventEmitter>) {
|
||||
*self.event_emitter.write().await = Some(emitter);
|
||||
}
|
||||
|
||||
async fn get_or_create_stripped_room(&self, room_id: &RoomId) -> StrippedRoom {
|
||||
let session = self.session.read().await;
|
||||
let user_id = &session
|
||||
|
@ -738,7 +735,13 @@ impl BaseClient {
|
|||
|
||||
rooms.join.insert(
|
||||
room_id,
|
||||
JoinedRoom::new(timeline, state, account_data, ephemeral, notification_count),
|
||||
JoinedRoomResponse::new(
|
||||
timeline,
|
||||
state,
|
||||
account_data,
|
||||
ephemeral,
|
||||
notification_count,
|
||||
),
|
||||
);
|
||||
|
||||
changes.add_room(room_info);
|
||||
|
@ -769,9 +772,10 @@ impl BaseClient {
|
|||
.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
|
||||
.await;
|
||||
|
||||
rooms
|
||||
.leave
|
||||
.insert(room_id, LeftRoom::new(timeline, state, account_data));
|
||||
rooms.leave.insert(
|
||||
room_id,
|
||||
LeftRoomResponse::new(timeline, state, account_data),
|
||||
);
|
||||
}
|
||||
|
||||
for (room_id, new_info) in response.rooms.invite {
|
||||
|
@ -791,7 +795,7 @@ impl BaseClient {
|
|||
changes.stripped_members.insert(room_id.clone(), members);
|
||||
changes.stripped_state.insert(room_id.clone(), state_events);
|
||||
|
||||
let room = InvitedRoom {
|
||||
let room = InvitedRoomResponse {
|
||||
invite_state: state,
|
||||
};
|
||||
|
||||
|
@ -851,7 +855,7 @@ impl BaseClient {
|
|||
async fn apply_changes(&self, changes: &StateChanges) {
|
||||
// TODO emit room changes here
|
||||
for (room_id, room_info) in &changes.room_infos {
|
||||
if let Some(room) = self.get_room(&room_id) {
|
||||
if let Some(room) = self.get_bare_room(&room_id) {
|
||||
room.update_summary(room_info.clone())
|
||||
}
|
||||
}
|
||||
|
@ -862,7 +866,7 @@ impl BaseClient {
|
|||
room_id: &RoomId,
|
||||
response: &api::membership::get_member_events::Response,
|
||||
) -> Result<()> {
|
||||
if let Some(room) = self.get_room(room_id) {
|
||||
if let Some(room) = self.get_bare_room(room_id) {
|
||||
let mut room_info = room.clone_info();
|
||||
room_info.mark_members_synced();
|
||||
|
||||
|
@ -1027,12 +1031,28 @@ impl BaseClient {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_room(&self, room_id: &RoomId) -> Option<Room> {
|
||||
fn get_bare_room(&self, room_id: &RoomId) -> Option<Room> {
|
||||
#[allow(clippy::map_clone)]
|
||||
self.rooms.get(room_id).map(|r| r.clone())
|
||||
}
|
||||
|
||||
pub fn get_stripped_room(&self, room_id: &RoomId) -> Option<StrippedRoom> {
|
||||
pub fn get_joined_room(&self, room_id: &RoomId) -> Option<JoinedRoom> {
|
||||
self.get_room(room_id).map(|r| r.joined()).flatten()
|
||||
}
|
||||
|
||||
pub fn get_room(&self, room_id: &RoomId) -> Option<RoomState> {
|
||||
self.get_bare_room(room_id)
|
||||
.map(|r| match r.room_type() {
|
||||
RoomType::Joined => Some(RoomState::Joined(JoinedRoom { inner: r })),
|
||||
RoomType::Left => Some(RoomState::Left(LeftRoom { inner: r })),
|
||||
RoomType::Invited => self
|
||||
.get_stripped_room(room_id)
|
||||
.map(|r| RoomState::Invited(InvitedRoom { inner: r })),
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
|
||||
fn get_stripped_room(&self, room_id: &RoomId) -> Option<StrippedRoom> {
|
||||
#[allow(clippy::map_clone)]
|
||||
self.stripped_rooms.get(room_id).map(|r| r.clone())
|
||||
}
|
||||
|
|
|
@ -40,13 +40,11 @@ use crate::{
|
|||
typing::TypingEventContent,
|
||||
BasicEvent, StrippedStateEvent, SyncEphemeralRoomEvent, SyncMessageEvent, SyncStateEvent,
|
||||
},
|
||||
Room, RoomState,
|
||||
rooms::RoomState,
|
||||
Room,
|
||||
};
|
||||
use matrix_sdk_common_macros::async_trait;
|
||||
|
||||
/// Type alias for `RoomState` enum when passed to `EventEmitter` methods.
|
||||
pub type SyncRoom = RoomState<Arc<RwLock<Room>>>;
|
||||
|
||||
/// This represents the various "unrecognized" events.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum CustomEvent<'c> {
|
||||
|
@ -76,7 +74,7 @@ pub enum CustomEvent<'c> {
|
|||
/// # room::message::{MessageEventContent, TextMessageEventContent},
|
||||
/// # SyncMessageEvent
|
||||
/// # },
|
||||
/// # EventEmitter, SyncRoom
|
||||
/// # EventEmitter, RoomState
|
||||
/// # };
|
||||
/// # use matrix_sdk_common::locks::RwLock;
|
||||
/// # use matrix_sdk_common_macros::async_trait;
|
||||
|
@ -85,8 +83,8 @@ pub enum CustomEvent<'c> {
|
|||
///
|
||||
/// #[async_trait]
|
||||
/// impl EventEmitter for EventCallback {
|
||||
/// async fn on_room_message(&self, room: SyncRoom, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
/// if let SyncRoom::Joined(room) = room {
|
||||
/// async fn on_room_message(&self, room: RoomState, event: &SyncMessageEvent<MessageEventContent>) {
|
||||
/// if let RoomState::Joined(room) = room {
|
||||
/// if let SyncMessageEvent {
|
||||
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||
/// sender,
|
||||
|
@ -112,135 +110,140 @@ pub enum CustomEvent<'c> {
|
|||
pub trait EventEmitter: Send + Sync {
|
||||
// ROOM EVENTS from `IncomingTimeline`
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomMember` event.
|
||||
async fn on_room_member(&self, _: SyncRoom, _: &SyncStateEvent<MemberEventContent>) {}
|
||||
async fn on_room_member(&self, _: RoomState, _: &SyncStateEvent<MemberEventContent>) {}
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomName` event.
|
||||
async fn on_room_name(&self, _: SyncRoom, _: &SyncStateEvent<NameEventContent>) {}
|
||||
async fn on_room_name(&self, _: RoomState, _: &SyncStateEvent<NameEventContent>) {}
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomCanonicalAlias` event.
|
||||
async fn on_room_canonical_alias(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<CanonicalAliasEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomAliases` event.
|
||||
async fn on_room_aliases(&self, _: SyncRoom, _: &SyncStateEvent<AliasesEventContent>) {}
|
||||
async fn on_room_aliases(&self, _: RoomState, _: &SyncStateEvent<AliasesEventContent>) {}
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomAvatar` event.
|
||||
async fn on_room_avatar(&self, _: SyncRoom, _: &SyncStateEvent<AvatarEventContent>) {}
|
||||
async fn on_room_avatar(&self, _: RoomState, _: &SyncStateEvent<AvatarEventContent>) {}
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomMessage` event.
|
||||
async fn on_room_message(&self, _: SyncRoom, _: &SyncMessageEvent<MsgEventContent>) {}
|
||||
async fn on_room_message(&self, _: RoomState, _: &SyncMessageEvent<MsgEventContent>) {}
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomMessageFeedback` event.
|
||||
async fn on_room_message_feedback(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncMessageEvent<FeedbackEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomRedaction` event.
|
||||
async fn on_room_redaction(&self, _: SyncRoom, _: &SyncRedactionEvent) {}
|
||||
async fn on_room_redaction(&self, _: RoomState, _: &SyncRedactionEvent) {}
|
||||
/// Fires when `Client` receives a `RoomEvent::RoomPowerLevels` event.
|
||||
async fn on_room_power_levels(&self, _: SyncRoom, _: &SyncStateEvent<PowerLevelsEventContent>) {
|
||||
async fn on_room_power_levels(
|
||||
&self,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<PowerLevelsEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `RoomEvent::Tombstone` event.
|
||||
async fn on_room_join_rules(&self, _: SyncRoom, _: &SyncStateEvent<JoinRulesEventContent>) {}
|
||||
async fn on_room_join_rules(&self, _: RoomState, _: &SyncStateEvent<JoinRulesEventContent>) {}
|
||||
/// Fires when `Client` receives a `RoomEvent::Tombstone` event.
|
||||
async fn on_room_tombstone(&self, _: SyncRoom, _: &SyncStateEvent<TombstoneEventContent>) {}
|
||||
async fn on_room_tombstone(&self, _: RoomState, _: &SyncStateEvent<TombstoneEventContent>) {}
|
||||
|
||||
// `RoomEvent`s from `IncomingState`
|
||||
/// Fires when `Client` receives a `StateEvent::RoomMember` event.
|
||||
async fn on_state_member(&self, _: SyncRoom, _: &SyncStateEvent<MemberEventContent>) {}
|
||||
async fn on_state_member(&self, _: RoomState, _: &SyncStateEvent<MemberEventContent>) {}
|
||||
/// Fires when `Client` receives a `StateEvent::RoomName` event.
|
||||
async fn on_state_name(&self, _: SyncRoom, _: &SyncStateEvent<NameEventContent>) {}
|
||||
async fn on_state_name(&self, _: RoomState, _: &SyncStateEvent<NameEventContent>) {}
|
||||
/// Fires when `Client` receives a `StateEvent::RoomCanonicalAlias` event.
|
||||
async fn on_state_canonical_alias(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<CanonicalAliasEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `StateEvent::RoomAliases` event.
|
||||
async fn on_state_aliases(&self, _: SyncRoom, _: &SyncStateEvent<AliasesEventContent>) {}
|
||||
async fn on_state_aliases(&self, _: RoomState, _: &SyncStateEvent<AliasesEventContent>) {}
|
||||
/// Fires when `Client` receives a `StateEvent::RoomAvatar` event.
|
||||
async fn on_state_avatar(&self, _: SyncRoom, _: &SyncStateEvent<AvatarEventContent>) {}
|
||||
async fn on_state_avatar(&self, _: RoomState, _: &SyncStateEvent<AvatarEventContent>) {}
|
||||
/// Fires when `Client` receives a `StateEvent::RoomPowerLevels` event.
|
||||
async fn on_state_power_levels(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<PowerLevelsEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `StateEvent::RoomJoinRules` event.
|
||||
async fn on_state_join_rules(&self, _: SyncRoom, _: &SyncStateEvent<JoinRulesEventContent>) {}
|
||||
async fn on_state_join_rules(&self, _: RoomState, _: &SyncStateEvent<JoinRulesEventContent>) {}
|
||||
|
||||
// `AnyStrippedStateEvent`s
|
||||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomMember` event.
|
||||
async fn on_stripped_state_member(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<MemberEventContent>,
|
||||
_: Option<MemberEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomName` event.
|
||||
async fn on_stripped_state_name(&self, _: SyncRoom, _: &StrippedStateEvent<NameEventContent>) {}
|
||||
async fn on_stripped_state_name(&self, _: RoomState, _: &StrippedStateEvent<NameEventContent>) {
|
||||
}
|
||||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event.
|
||||
async fn on_stripped_state_canonical_alias(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<CanonicalAliasEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event.
|
||||
async fn on_stripped_state_aliases(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<AliasesEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAvatar` event.
|
||||
async fn on_stripped_state_avatar(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<AvatarEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event.
|
||||
async fn on_stripped_state_power_levels(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<PowerLevelsEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
|
||||
async fn on_stripped_state_join_rules(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<JoinRulesEventContent>,
|
||||
) {
|
||||
}
|
||||
|
||||
// `NonRoomEvent` (this is a type alias from ruma_events)
|
||||
/// Fires when `Client` receives a `NonRoomEvent::RoomPresence` event.
|
||||
async fn on_non_room_presence(&self, _: SyncRoom, _: &PresenceEvent) {}
|
||||
async fn on_non_room_presence(&self, _: RoomState, _: &PresenceEvent) {}
|
||||
/// Fires when `Client` receives a `NonRoomEvent::RoomName` event.
|
||||
async fn on_non_room_ignored_users(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &BasicEvent<IgnoredUserListEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `NonRoomEvent::RoomCanonicalAlias` event.
|
||||
async fn on_non_room_push_rules(&self, _: SyncRoom, _: &BasicEvent<PushRulesEventContent>) {}
|
||||
async fn on_non_room_push_rules(&self, _: RoomState, _: &BasicEvent<PushRulesEventContent>) {}
|
||||
/// Fires when `Client` receives a `NonRoomEvent::RoomAliases` event.
|
||||
async fn on_non_room_fully_read(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncEphemeralRoomEvent<FullyReadEventContent>,
|
||||
) {
|
||||
}
|
||||
/// Fires when `Client` receives a `NonRoomEvent::Typing` event.
|
||||
async fn on_non_room_typing(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncEphemeralRoomEvent<TypingEventContent>,
|
||||
) {
|
||||
}
|
||||
|
@ -249,27 +252,27 @@ pub trait EventEmitter: Send + Sync {
|
|||
/// This is always a read receipt.
|
||||
async fn on_non_room_receipt(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncEphemeralRoomEvent<ReceiptEventContent>,
|
||||
) {
|
||||
}
|
||||
|
||||
// `PresenceEvent` is a struct so there is only the one method
|
||||
/// Fires when `Client` receives a `NonRoomEvent::RoomAliases` event.
|
||||
async fn on_presence_event(&self, _: SyncRoom, _: &PresenceEvent) {}
|
||||
async fn on_presence_event(&self, _: RoomState, _: &PresenceEvent) {}
|
||||
|
||||
/// Fires when `Client` receives a `Event::Custom` event or if deserialization fails
|
||||
/// because the event was unknown to ruma.
|
||||
///
|
||||
/// The only guarantee this method can give about the event is that it is valid JSON.
|
||||
async fn on_unrecognized_event(&self, _: SyncRoom, _: &RawJsonValue) {}
|
||||
async fn on_unrecognized_event(&self, _: RoomState, _: &RawJsonValue) {}
|
||||
|
||||
/// Fires when `Client` receives a `Event::Custom` event or if deserialization fails
|
||||
/// because the event was unknown to ruma.
|
||||
///
|
||||
/// The only guarantee this method can give about the event is that it is in the
|
||||
/// shape of a valid matrix event.
|
||||
async fn on_custom_event(&self, _: SyncRoom, _: &CustomEvent<'_>) {}
|
||||
async fn on_custom_event(&self, _: RoomState, _: &CustomEvent<'_>) {}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -288,78 +291,78 @@ mod test {
|
|||
|
||||
#[async_trait]
|
||||
impl EventEmitter for EvEmitterTest {
|
||||
async fn on_room_member(&self, _: SyncRoom, _: &SyncStateEvent<MemberEventContent>) {
|
||||
async fn on_room_member(&self, _: RoomState, _: &SyncStateEvent<MemberEventContent>) {
|
||||
self.0.lock().await.push("member".to_string())
|
||||
}
|
||||
async fn on_room_name(&self, _: SyncRoom, _: &SyncStateEvent<NameEventContent>) {
|
||||
async fn on_room_name(&self, _: RoomState, _: &SyncStateEvent<NameEventContent>) {
|
||||
self.0.lock().await.push("name".to_string())
|
||||
}
|
||||
async fn on_room_canonical_alias(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<CanonicalAliasEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("canonical".to_string())
|
||||
}
|
||||
async fn on_room_aliases(&self, _: SyncRoom, _: &SyncStateEvent<AliasesEventContent>) {
|
||||
async fn on_room_aliases(&self, _: RoomState, _: &SyncStateEvent<AliasesEventContent>) {
|
||||
self.0.lock().await.push("aliases".to_string())
|
||||
}
|
||||
async fn on_room_avatar(&self, _: SyncRoom, _: &SyncStateEvent<AvatarEventContent>) {
|
||||
async fn on_room_avatar(&self, _: RoomState, _: &SyncStateEvent<AvatarEventContent>) {
|
||||
self.0.lock().await.push("avatar".to_string())
|
||||
}
|
||||
async fn on_room_message(&self, _: SyncRoom, _: &SyncMessageEvent<MsgEventContent>) {
|
||||
async fn on_room_message(&self, _: RoomState, _: &SyncMessageEvent<MsgEventContent>) {
|
||||
self.0.lock().await.push("message".to_string())
|
||||
}
|
||||
async fn on_room_message_feedback(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncMessageEvent<FeedbackEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("feedback".to_string())
|
||||
}
|
||||
async fn on_room_redaction(&self, _: SyncRoom, _: &SyncRedactionEvent) {
|
||||
async fn on_room_redaction(&self, _: RoomState, _: &SyncRedactionEvent) {
|
||||
self.0.lock().await.push("redaction".to_string())
|
||||
}
|
||||
async fn on_room_power_levels(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<PowerLevelsEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("power".to_string())
|
||||
}
|
||||
async fn on_room_tombstone(&self, _: SyncRoom, _: &SyncStateEvent<TombstoneEventContent>) {
|
||||
async fn on_room_tombstone(&self, _: RoomState, _: &SyncStateEvent<TombstoneEventContent>) {
|
||||
self.0.lock().await.push("tombstone".to_string())
|
||||
}
|
||||
|
||||
async fn on_state_member(&self, _: SyncRoom, _: &SyncStateEvent<MemberEventContent>) {
|
||||
async fn on_state_member(&self, _: RoomState, _: &SyncStateEvent<MemberEventContent>) {
|
||||
self.0.lock().await.push("state member".to_string())
|
||||
}
|
||||
async fn on_state_name(&self, _: SyncRoom, _: &SyncStateEvent<NameEventContent>) {
|
||||
async fn on_state_name(&self, _: RoomState, _: &SyncStateEvent<NameEventContent>) {
|
||||
self.0.lock().await.push("state name".to_string())
|
||||
}
|
||||
async fn on_state_canonical_alias(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<CanonicalAliasEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("state canonical".to_string())
|
||||
}
|
||||
async fn on_state_aliases(&self, _: SyncRoom, _: &SyncStateEvent<AliasesEventContent>) {
|
||||
async fn on_state_aliases(&self, _: RoomState, _: &SyncStateEvent<AliasesEventContent>) {
|
||||
self.0.lock().await.push("state aliases".to_string())
|
||||
}
|
||||
async fn on_state_avatar(&self, _: SyncRoom, _: &SyncStateEvent<AvatarEventContent>) {
|
||||
async fn on_state_avatar(&self, _: RoomState, _: &SyncStateEvent<AvatarEventContent>) {
|
||||
self.0.lock().await.push("state avatar".to_string())
|
||||
}
|
||||
async fn on_state_power_levels(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<PowerLevelsEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("state power".to_string())
|
||||
}
|
||||
async fn on_state_join_rules(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncStateEvent<JoinRulesEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("state rules".to_string())
|
||||
|
@ -369,7 +372,7 @@ mod test {
|
|||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomMember` event.
|
||||
async fn on_stripped_state_member(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<MemberEventContent>,
|
||||
_: Option<MemberEventContent>,
|
||||
) {
|
||||
|
@ -381,7 +384,7 @@ mod test {
|
|||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomName` event.
|
||||
async fn on_stripped_state_name(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<NameEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("stripped state name".to_string())
|
||||
|
@ -389,7 +392,7 @@ mod test {
|
|||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event.
|
||||
async fn on_stripped_state_canonical_alias(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<CanonicalAliasEventContent>,
|
||||
) {
|
||||
self.0
|
||||
|
@ -400,7 +403,7 @@ mod test {
|
|||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event.
|
||||
async fn on_stripped_state_aliases(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<AliasesEventContent>,
|
||||
) {
|
||||
self.0
|
||||
|
@ -411,7 +414,7 @@ mod test {
|
|||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAvatar` event.
|
||||
async fn on_stripped_state_avatar(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<AvatarEventContent>,
|
||||
) {
|
||||
self.0
|
||||
|
@ -422,7 +425,7 @@ mod test {
|
|||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event.
|
||||
async fn on_stripped_state_power_levels(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<PowerLevelsEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("stripped state power".to_string())
|
||||
|
@ -430,53 +433,57 @@ mod test {
|
|||
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
|
||||
async fn on_stripped_state_join_rules(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &StrippedStateEvent<JoinRulesEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("stripped state rules".to_string())
|
||||
}
|
||||
|
||||
async fn on_non_room_presence(&self, _: SyncRoom, _: &PresenceEvent) {
|
||||
async fn on_non_room_presence(&self, _: RoomState, _: &PresenceEvent) {
|
||||
self.0.lock().await.push("presence".to_string())
|
||||
}
|
||||
async fn on_non_room_ignored_users(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &BasicEvent<IgnoredUserListEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("account ignore".to_string())
|
||||
}
|
||||
async fn on_non_room_push_rules(&self, _: SyncRoom, _: &BasicEvent<PushRulesEventContent>) {
|
||||
async fn on_non_room_push_rules(
|
||||
&self,
|
||||
_: RoomState,
|
||||
_: &BasicEvent<PushRulesEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("account push rules".to_string())
|
||||
}
|
||||
async fn on_non_room_fully_read(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncEphemeralRoomEvent<FullyReadEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("account read".to_string())
|
||||
}
|
||||
async fn on_non_room_typing(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncEphemeralRoomEvent<TypingEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("typing event".to_string())
|
||||
}
|
||||
async fn on_non_room_receipt(
|
||||
&self,
|
||||
_: SyncRoom,
|
||||
_: RoomState,
|
||||
_: &SyncEphemeralRoomEvent<ReceiptEventContent>,
|
||||
) {
|
||||
self.0.lock().await.push("receipt event".to_string())
|
||||
}
|
||||
async fn on_presence_event(&self, _: SyncRoom, _: &PresenceEvent) {
|
||||
async fn on_presence_event(&self, _: RoomState, _: &PresenceEvent) {
|
||||
self.0.lock().await.push("presence event".to_string())
|
||||
}
|
||||
async fn on_unrecognized_event(&self, _: SyncRoom, _: &RawJsonValue) {
|
||||
async fn on_unrecognized_event(&self, _: RoomState, _: &RawJsonValue) {
|
||||
self.0.lock().await.push("unrecognized event".to_string())
|
||||
}
|
||||
async fn on_custom_event(&self, _: SyncRoom, _: &CustomEvent<'_>) {
|
||||
async fn on_custom_event(&self, _: RoomState, _: &CustomEvent<'_>) {
|
||||
self.0.lock().await.push("custom event".to_string())
|
||||
}
|
||||
}
|
||||
|
@ -503,8 +510,8 @@ mod test {
|
|||
let client = get_client().await;
|
||||
client.add_event_emitter(emitter).await;
|
||||
|
||||
let mut response = sync_response(SyncResponseFile::Default);
|
||||
client.receive_sync_response(&mut response).await.unwrap();
|
||||
let response = sync_response(SyncResponseFile::Default);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
||||
|
@ -535,8 +542,8 @@ mod test {
|
|||
let client = get_client().await;
|
||||
client.add_event_emitter(emitter).await;
|
||||
|
||||
let mut response = sync_response(SyncResponseFile::Invite);
|
||||
client.receive_sync_response(&mut response).await.unwrap();
|
||||
let response = sync_response(SyncResponseFile::Invite);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
||||
|
@ -554,8 +561,8 @@ mod test {
|
|||
let client = get_client().await;
|
||||
client.add_event_emitter(emitter).await;
|
||||
|
||||
let mut response = sync_response(SyncResponseFile::Leave);
|
||||
client.receive_sync_response(&mut response).await.unwrap();
|
||||
let response = sync_response(SyncResponseFile::Leave);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
||||
|
@ -582,8 +589,8 @@ mod test {
|
|||
let client = get_client().await;
|
||||
client.add_event_emitter(emitter).await;
|
||||
|
||||
let mut response = sync_response(SyncResponseFile::All);
|
||||
client.receive_sync_response(&mut response).await.unwrap();
|
||||
let response = sync_response(SyncResponseFile::All);
|
||||
client.receive_sync_response(response).await.unwrap();
|
||||
|
||||
let v = test_vec.lock().await;
|
||||
assert_eq!(
|
||||
|
|
|
@ -44,15 +44,17 @@ pub use matrix_sdk_common::*;
|
|||
|
||||
mod client;
|
||||
mod error;
|
||||
mod event_emitter;
|
||||
pub mod responses;
|
||||
mod rooms;
|
||||
mod session;
|
||||
mod store;
|
||||
|
||||
pub use rooms::{Room, RoomInfo, RoomMember};
|
||||
pub use event_emitter::EventEmitter;
|
||||
pub use rooms::{InvitedRoom, JoinedRoom, LeftRoom, Room, RoomInfo, RoomMember, RoomState};
|
||||
pub use store::Store;
|
||||
|
||||
pub use client::{BaseClient, BaseClientConfig, RoomState, RoomStateType};
|
||||
pub use client::{BaseClient, BaseClientConfig, RoomStateType};
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
|
|
|
@ -8,7 +8,7 @@ pub use stripped::{StrippedRoom, StrippedRoomInfo};
|
|||
pub use members::RoomMember;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::max;
|
||||
use std::{cmp::max, ops::Deref};
|
||||
|
||||
use matrix_sdk_common::{
|
||||
events::{
|
||||
|
@ -18,6 +18,86 @@ use matrix_sdk_common::{
|
|||
identifiers::RoomAliasId,
|
||||
};
|
||||
|
||||
/// 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. `RoomState` is generic
|
||||
/// so it can be used to represent a `Room` or an `Arc<RwLock<Room>>`
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RoomState {
|
||||
/// A room from the `join` section of a sync response.
|
||||
Joined(JoinedRoom),
|
||||
/// A room from the `leave` section of a sync response.
|
||||
Left(LeftRoom),
|
||||
/// A room from the `invite` section of a sync response.
|
||||
Invited(InvitedRoom),
|
||||
}
|
||||
|
||||
impl RoomState {
|
||||
pub fn joined(self) -> Option<JoinedRoom> {
|
||||
if let RoomState::Joined(r) = self {
|
||||
Some(r)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_encrypted(&self) -> bool {
|
||||
match self {
|
||||
RoomState::Joined(r) => r.inner.is_encrypted(),
|
||||
RoomState::Left(r) => r.inner.is_encrypted(),
|
||||
RoomState::Invited(r) => r.inner.is_encrypted(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn are_members_synced(&self) -> bool {
|
||||
if let RoomState::Joined(r) = self {
|
||||
r.inner.are_members_synced()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct JoinedRoom {
|
||||
pub(crate) inner: Room,
|
||||
}
|
||||
|
||||
impl Deref for JoinedRoom {
|
||||
type Target = Room;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LeftRoom {
|
||||
pub(crate) inner: Room,
|
||||
}
|
||||
|
||||
impl Deref for LeftRoom {
|
||||
type Target = Room;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InvitedRoom {
|
||||
pub(crate) inner: StrippedRoom,
|
||||
}
|
||||
|
||||
impl Deref for InvitedRoom {
|
||||
type Target = StrippedRoom;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct BaseRoomInfo {
|
||||
pub name: Option<String>,
|
||||
|
|
|
@ -83,6 +83,10 @@ impl Room {
|
|||
self.inner.lock().unwrap().members_synced
|
||||
}
|
||||
|
||||
pub fn room_type(&self) -> RoomType {
|
||||
self.inner.lock().unwrap().room_type
|
||||
}
|
||||
|
||||
pub async fn get_active_members(&self) -> impl Stream<Item = RoomMember> + '_ {
|
||||
let joined = self.store.get_joined_user_ids(self.room_id()).await;
|
||||
let invited = self.store.get_invited_user_ids(self.room_id()).await;
|
||||
|
|
Loading…
Reference in New Issue