From 557d27a1a30270fd14f9afcece994fe547a25891 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 2 May 2023 11:49:50 +0200 Subject: [PATCH] sdk: Add more convenient power level action checks to RoomMember --- crates/matrix-sdk-base/Changelog.md | 8 +++ crates/matrix-sdk-base/src/rooms/members.rs | 68 +++++++++++++++++++-- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/crates/matrix-sdk-base/Changelog.md b/crates/matrix-sdk-base/Changelog.md index fff8ad6e13f..eb86722a808 100644 --- a/crates/matrix-sdk-base/Changelog.md +++ b/crates/matrix-sdk-base/Changelog.md @@ -12,6 +12,14 @@ - `Room::members` takes a `RoomMemberships` to be able to filter the results by any membership state. - `Room::active_members` and `Room::joined_members` are deprecated. +- `RoomMember` has new methods: + - `can_ban` + - `can_invite` + - `can_kick` + - `can_redact` + - `can_send_message` + - `can_send_state` + - `can_trigger_room_notification` ## 0.5.1 diff --git a/crates/matrix-sdk-base/src/rooms/members.rs b/crates/matrix-sdk-base/src/rooms/members.rs index e3dea619f8a..853417031ec 100644 --- a/crates/matrix-sdk-base/src/rooms/members.rs +++ b/crates/matrix-sdk-base/src/rooms/members.rs @@ -19,8 +19,9 @@ use ruma::{ presence::PresenceEvent, room::{ member::MembershipState, - power_levels::{PowerLevelAction, SyncRoomPowerLevelsEvent}, + power_levels::{PowerLevelAction, RoomPowerLevels, SyncRoomPowerLevelsEvent}, }, + MessageLikeEventType, StateEventType, }, MxcUri, UserId, }; @@ -105,13 +106,68 @@ impl RoomMember { .unwrap_or_else(|| if self.is_room_creator { 100 } else { 0 }) } - /// Whether the given user can do the given action based on the power + /// Whether this user can ban other users based on the power levels. + /// + /// Same as `member.can_do(PowerLevelAction::Ban)`. + pub fn can_ban(&self) -> bool { + self.can_do_impl(|pls| pls.user_can_ban(self.user_id())) + } + + /// Whether this user can invite other users based on the power levels. + /// + /// Same as `member.can_do(PowerLevelAction::Invite)`. + pub fn can_invite(&self) -> bool { + self.can_do_impl(|pls| pls.user_can_invite(self.user_id())) + } + + /// Whether this user can kick other users based on the power levels. + /// + /// Same as `member.can_do(PowerLevelAction::Kick)`. + pub fn can_kick(&self) -> bool { + self.can_do_impl(|pls| pls.user_can_kick(self.user_id())) + } + + /// Whether this user can redact events based on the power levels. + /// + /// Same as `member.can_do(PowerLevelAction::Redact)`. + pub fn can_redact(&self) -> bool { + self.can_do_impl(|pls| pls.user_can_redact(self.user_id())) + } + + /// Whether this user can send message events based on the power levels. + /// + /// Same as `member.can_do(PowerLevelAction::SendMessage(msg_type))`. + pub fn can_send_message(&self, msg_type: MessageLikeEventType) -> bool { + self.can_do_impl(|pls| pls.user_can_send_message(self.user_id(), msg_type)) + } + + /// Whether this user can send state events based on the power levels. + /// + /// Same as `member.can_do(PowerLevelAction::SendState(state_type))`. + pub fn can_send_state(&self, state_type: StateEventType) -> bool { + self.can_do_impl(|pls| pls.user_can_send_state(self.user_id(), state_type)) + } + + /// Whether this user can notify everybody in the room by writing `@room` in + /// a message. + /// + /// Same as `member. + /// can_do(PowerLevelAction::TriggerNotification(NotificationPowerLevelType::Room))`. + pub fn can_trigger_room_notification(&self) -> bool { + self.can_do_impl(|pls| pls.user_can_trigger_room_notification(self.user_id())) + } + + /// Whether this user can do the given action based on the power /// levels. pub fn can_do(&self, action: PowerLevelAction) -> bool { - (*self.power_levels) - .as_ref() - .map(|e| e.power_levels().user_can_do(self.user_id(), action)) - .unwrap_or_else(|| self.is_room_creator) + self.can_do_impl(|pls| pls.user_can_do(self.user_id(), action)) + } + + fn can_do_impl(&self, f: impl FnOnce(RoomPowerLevels) -> bool) -> bool { + match &*self.power_levels { + Some(event) => f(event.power_levels()), + None => self.is_room_creator, + } } /// Is the name that the member uses ambiguous in the room.