mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-16 03:55:42 -04:00
base: Add method to construct RoomMember from parts
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
committed by
Jonas Platte
parent
e32e9b5a22
commit
38fc1f7b15
@@ -267,6 +267,16 @@ impl MemberEvent {
|
||||
pub fn user_id(&self) -> &UserId {
|
||||
self.state_key()
|
||||
}
|
||||
|
||||
/// The name that should be displayed for this member event.
|
||||
///
|
||||
/// It there is no `displayname` in the event's content, the localpart or
|
||||
/// the user ID is returned.
|
||||
pub fn display_name(&self) -> &str {
|
||||
self.original_content()
|
||||
.and_then(|c| c.displayname.as_deref())
|
||||
.unwrap_or_else(|| self.user_id().localpart())
|
||||
}
|
||||
}
|
||||
|
||||
impl SyncOrStrippedState<RoomPowerLevelsEventContent> {
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use ruma::{
|
||||
events::{
|
||||
@@ -23,7 +26,7 @@ use ruma::{
|
||||
},
|
||||
MessageLikeEventType, StateEventType,
|
||||
},
|
||||
MxcUri, UserId,
|
||||
MxcUri, OwnedUserId, UserId,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -49,6 +52,33 @@ pub struct RoomMember {
|
||||
}
|
||||
|
||||
impl RoomMember {
|
||||
pub(crate) fn from_parts(member_info: MemberInfo, room_info: &MemberRoomInfo<'_>) -> Self {
|
||||
let MemberInfo { event, profile, presence } = member_info;
|
||||
let MemberRoomInfo {
|
||||
power_levels,
|
||||
max_power_level,
|
||||
room_creator,
|
||||
users_display_names,
|
||||
ignored_users,
|
||||
} = room_info;
|
||||
|
||||
let is_room_creator = room_creator.as_deref() == Some(event.user_id());
|
||||
let display_name_ambiguous =
|
||||
users_display_names.get(event.display_name()).is_some_and(|s| s.len() > 1);
|
||||
let is_ignored = ignored_users.as_ref().is_some_and(|s| s.contains(event.user_id()));
|
||||
|
||||
Self {
|
||||
event: event.into(),
|
||||
profile: profile.into(),
|
||||
presence: presence.into(),
|
||||
power_levels: power_levels.clone(),
|
||||
max_power_level: *max_power_level,
|
||||
is_room_creator,
|
||||
display_name_ambiguous,
|
||||
is_ignored,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the unique user id of this member.
|
||||
pub fn user_id(&self) -> &UserId {
|
||||
self.event.user_id()
|
||||
@@ -191,3 +221,19 @@ impl RoomMember {
|
||||
self.is_ignored
|
||||
}
|
||||
}
|
||||
|
||||
// Information about a room member.
|
||||
pub(crate) struct MemberInfo {
|
||||
pub event: MemberEvent,
|
||||
pub(crate) profile: Option<MinimalRoomMemberEvent>,
|
||||
pub(crate) presence: Option<PresenceEvent>,
|
||||
}
|
||||
|
||||
// Information about a the room a member is in.
|
||||
pub(crate) struct MemberRoomInfo<'a> {
|
||||
pub(crate) power_levels: Arc<Option<SyncOrStrippedState<RoomPowerLevelsEventContent>>>,
|
||||
pub(crate) max_power_level: i64,
|
||||
pub(crate) room_creator: Option<OwnedUserId>,
|
||||
pub(crate) users_display_names: BTreeMap<&'a str, BTreeSet<OwnedUserId>>,
|
||||
pub(crate) ignored_users: Option<BTreeSet<OwnedUserId>>,
|
||||
}
|
||||
|
||||
@@ -41,7 +41,10 @@ use ruma::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{debug, info, instrument, warn};
|
||||
|
||||
use super::{BaseRoomInfo, DisplayName, RoomMember};
|
||||
use super::{
|
||||
members::{MemberInfo, MemberRoomInfo},
|
||||
BaseRoomInfo, DisplayName, RoomMember,
|
||||
};
|
||||
use crate::{
|
||||
deserialized_responses::MemberEvent,
|
||||
store::{DynStateStore, Result as StoreResult, StateStoreExt},
|
||||
@@ -457,51 +460,52 @@ impl Room {
|
||||
let Some(raw_event) = self.store.get_member_event(self.room_id(), user_id).await? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let member_event = raw_event.deserialize()?;
|
||||
let event = raw_event.deserialize()?;
|
||||
|
||||
let presence =
|
||||
self.store.get_presence_event(user_id).await?.and_then(|e| e.deserialize().ok());
|
||||
let profile = self.store.get_profile(self.room_id(), user_id).await?;
|
||||
let max_power_level = self.max_power_level();
|
||||
let is_room_creator = self.inner.read().unwrap().creator() == Some(user_id);
|
||||
|
||||
let power = self
|
||||
let display_names = [event.display_name().to_owned()];
|
||||
let room_info = self.member_room_info(&display_names).await?;
|
||||
|
||||
let member_info = MemberInfo { event, profile, presence };
|
||||
|
||||
Ok(Some(RoomMember::from_parts(member_info, &room_info)))
|
||||
}
|
||||
|
||||
/// The current `MemberRoomInfo` for this room.
|
||||
async fn member_room_info<'a>(
|
||||
&self,
|
||||
display_names: &'a [String],
|
||||
) -> StoreResult<MemberRoomInfo<'a>> {
|
||||
let max_power_level = self.max_power_level();
|
||||
let room_creator = self.inner.read().unwrap().creator().map(ToOwned::to_owned);
|
||||
|
||||
let power_levels = self
|
||||
.store
|
||||
.get_state_event_static(self.room_id())
|
||||
.await?
|
||||
.and_then(|e| e.deserialize().ok());
|
||||
|
||||
let ambiguous = self
|
||||
.store
|
||||
.get_users_with_display_name(
|
||||
self.room_id(),
|
||||
member_event
|
||||
.original_content()
|
||||
.and_then(|c| c.displayname.as_deref())
|
||||
.unwrap_or_else(|| user_id.localpart()),
|
||||
)
|
||||
.await?
|
||||
.len()
|
||||
> 1;
|
||||
let users_display_names =
|
||||
self.store.get_users_with_display_names(self.room_id(), display_names).await?;
|
||||
|
||||
let is_ignored = self
|
||||
let ignored_users = self
|
||||
.store
|
||||
.get_account_data_event_static::<IgnoredUserListEventContent>()
|
||||
.await?
|
||||
.map(|c| c.deserialize())
|
||||
.transpose()?
|
||||
.is_some_and(|e| e.content.ignored_users.contains_key(member_event.user_id()));
|
||||
.map(|e| e.content.ignored_users.into_keys().collect());
|
||||
|
||||
Ok(Some(RoomMember {
|
||||
event: Arc::new(member_event),
|
||||
profile: profile.into(),
|
||||
presence: presence.into(),
|
||||
power_levels: power.into(),
|
||||
Ok(MemberRoomInfo {
|
||||
power_levels: power_levels.into(),
|
||||
max_power_level,
|
||||
is_room_creator,
|
||||
display_name_ambiguous: ambiguous,
|
||||
is_ignored,
|
||||
}))
|
||||
room_creator,
|
||||
users_display_names,
|
||||
ignored_users,
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the `Tags` for this room.
|
||||
|
||||
Reference in New Issue
Block a user