diff --git a/bindings/matrix-sdk-ffi/CHANGELOG.md b/bindings/matrix-sdk-ffi/CHANGELOG.md index 438e2d6ff52..9a2cf5255c8 100644 --- a/bindings/matrix-sdk-ffi/CHANGELOG.md +++ b/bindings/matrix-sdk-ffi/CHANGELOG.md @@ -25,6 +25,9 @@ All notable changes to this project will be documented in this file. [#5624](https://github.com/matrix-org/matrix-rust-sdk/pull/5624/) - Created `RoomPowerLevels::events` function which returns a `HashMap` with all the power levels per event type. ([#5937](https://github.com/matrix-org/matrix-rust-sdk/pull/5937)) +- Expose room power level thresholds in `OtherState::RoomPowerLevels` (ban, kick, invite, redact, state & + events defaults, per-event overrides, notifications), so clients can compute the required power level + for actions and compare with previous values. ### Refactor diff --git a/bindings/matrix-sdk-ffi/src/event.rs b/bindings/matrix-sdk-ffi/src/event.rs index 810a5874716..3e5ef0e0496 100644 --- a/bindings/matrix-sdk-ffi/src/event.rs +++ b/bindings/matrix-sdk-ffi/src/event.rs @@ -74,7 +74,7 @@ impl From for TimelineEvent { } /// The timeline event type. -#[derive(uniffi::Enum, PartialEq, Eq, Hash)] +#[derive(Clone, uniffi::Enum, PartialEq, Eq, Hash)] pub enum TimelineEventType { /// The event is a message-like one and should be displayed as such. MessageLike { value: MessageLikeEventType }, diff --git a/bindings/matrix-sdk-ffi/src/timeline/content.rs b/bindings/matrix-sdk-ffi/src/timeline/content.rs index 4b1b686881b..c486d4451ed 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/content.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/content.rs @@ -20,7 +20,10 @@ use ruma::events::{ room::history_visibility::HistoryVisibility as RumaHistoryVisibility, FullStateEventContent, }; -use crate::{client::JoinRule, timeline::msg_like::MsgLikeContent, utils::Timestamp}; +use crate::{ + client::JoinRule, event::TimelineEventType, timeline::msg_like::MsgLikeContent, + utils::Timestamp, +}; impl From for TimelineItemContent { fn from(value: matrix_sdk_ui::timeline::TimelineItemContent) -> Self { @@ -242,29 +245,69 @@ impl From for MembershipChange { } } +#[derive(Clone, uniffi::Record)] +pub struct PowerLevelChanges { + ban: i64, + kick: i64, + events_default: i64, + invite: i64, + redact: i64, + state_default: i64, + users_default: i64, + notifications: i64, +} + #[derive(Clone, uniffi::Enum)] +#[allow(clippy::large_enum_variant)] +// Added because the RoomPowerLevels variant is quite large. +// This is the same issue than for TimelineItemContent. pub enum OtherState { PolicyRuleRoom, PolicyRuleServer, PolicyRuleUser, RoomAliases, - RoomAvatar { url: Option }, + RoomAvatar { + url: Option, + }, RoomCanonicalAlias, - RoomCreate { federate: Option }, + RoomCreate { + federate: Option, + }, RoomEncryption, RoomGuestAccess, - RoomHistoryVisibility { history_visibility: Option }, - RoomJoinRules { join_rule: Option }, - RoomName { name: Option }, - RoomPinnedEvents { change: RoomPinnedEventsChange }, - RoomPowerLevels { users: HashMap, previous: Option> }, + RoomHistoryVisibility { + history_visibility: Option, + }, + RoomJoinRules { + join_rule: Option, + }, + RoomName { + name: Option, + }, + RoomPinnedEvents { + change: RoomPinnedEventsChange, + }, + RoomPowerLevels { + events: HashMap, + previous_events: Option>, + users: HashMap, + previous: Option>, + thresholds: Option, + previous_thresholds: Option, + }, RoomServerAcl, - RoomThirdPartyInvite { display_name: Option }, + RoomThirdPartyInvite { + display_name: Option, + }, RoomTombstone, - RoomTopic { topic: Option }, + RoomTopic { + topic: Option, + }, SpaceChild, SpaceParent, - Custom { event_type: String }, + Custom { + event_type: String, + }, } impl From<&matrix_sdk_ui::timeline::AnyOtherFullStateEventContent> for OtherState { @@ -330,6 +373,40 @@ impl From<&matrix_sdk_ui::timeline::AnyOtherFullStateEventContent> for OtherStat Content::RoomPinnedEvents(c) => Self::RoomPinnedEvents { change: c.into() }, Content::RoomPowerLevels(c) => match c { FullContent::Original { content, prev_content } => Self::RoomPowerLevels { + events: content + .events + .iter() + .map(|(k, &v)| (k.clone().into(), v.into())) + .collect(), + previous_events: prev_content.as_ref().map(|prev_content| { + prev_content + .events + .iter() + .map(|(k, &v)| (k.clone().into(), v.into())) + .collect() + }), + thresholds: Some(PowerLevelChanges { + ban: content.ban.into(), + kick: content.kick.into(), + events_default: content.events_default.into(), + invite: content.invite.into(), + redact: content.redact.into(), + state_default: content.state_default.into(), + users_default: content.users_default.into(), + notifications: content.notifications.room.into(), + }), + previous_thresholds: prev_content.as_ref().map(|prev_content| { + PowerLevelChanges { + ban: prev_content.ban.into(), + kick: prev_content.kick.into(), + events_default: prev_content.events_default.into(), + invite: prev_content.invite.into(), + redact: prev_content.redact.into(), + state_default: prev_content.state_default.into(), + users_default: prev_content.users_default.into(), + notifications: prev_content.notifications.room.into(), + } + }), users: power_level_user_changes(content, prev_content) .iter() .map(|(k, v)| (k.to_string(), *v)) @@ -338,9 +415,14 @@ impl From<&matrix_sdk_ui::timeline::AnyOtherFullStateEventContent> for OtherStat prev_content.users.iter().map(|(k, &v)| (k.to_string(), v.into())).collect() }), }, - FullContent::Redacted(_) => { - Self::RoomPowerLevels { users: Default::default(), previous: None } - } + FullContent::Redacted(_) => Self::RoomPowerLevels { + events: Default::default(), + previous_events: None, + users: Default::default(), + previous: None, + thresholds: None, + previous_thresholds: None, + }, }, Content::RoomServerAcl(_) => Self::RoomServerAcl, Content::RoomThirdPartyInvite(c) => {