From 3e67a43799ad9f21579d14bb08e5b2e888effcf4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 10 Dec 2025 15:16:00 +0100 Subject: [PATCH] change(room permissions): support space management --- .../impl/analytics/AnalyticUtils.kt | 4 ++-- .../ChangeRoomPermissionsPresenter.kt | 16 +++++++++++----- .../permissions/ChangeRoomPermissionsState.kt | 12 ++++++++---- .../ChangeRoomPermissionsStateProvider.kt | 3 ++- .../permissions/ChangeRoomPermissionsView.kt | 10 ++++++---- .../ChangeRoomPermissionsPresenterTest.kt | 5 +++-- .../permissions/ChangeRoomPermissionsViewTest.kt | 2 +- .../room/powerlevels/RoomPowerLevelsValues.kt | 3 ++- .../libraries/matrix/impl/room/JoinedRustRoom.kt | 4 +++- .../powerlevels/RoomPowerLevelsValuesMapper.kt | 3 ++- .../RoomPowerLevelsValuesMapperTest.kt | 3 ++- .../libraries/matrix/test/room/FakeBaseRoom.kt | 11 ++++++----- 12 files changed, 48 insertions(+), 28 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/analytics/AnalyticUtils.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/analytics/AnalyticUtils.kt index 9963a751f1..546d54c21a 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/analytics/AnalyticUtils.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/analytics/AnalyticUtils.kt @@ -34,8 +34,8 @@ internal fun AnalyticsService.trackPermissionChangeAnalytics(initial: RoomPowerL if (updated.kick != initial?.kick) { capture(RoomModeration(RoomModeration.Action.ChangePermissionsKickMembers, analyticsMemberRoleForPowerLevel(updated.kick))) } - if (updated.sendEvents != initial?.sendEvents) { - capture(RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, analyticsMemberRoleForPowerLevel(updated.sendEvents))) + if (updated.eventsDefault != initial?.eventsDefault) { + capture(RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, analyticsMemberRoleForPowerLevel(updated.eventsDefault))) } if (updated.redactEvents != initial?.redactEvents) { capture(RoomModeration(RoomModeration.Action.ChangePermissionsRedactMessages, analyticsMemberRoleForPowerLevel(updated.redactEvents))) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt index 99f5723bf9..c0e659ac04 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt @@ -36,8 +36,7 @@ class ChangeRoomPermissionsPresenter( ) : Presenter { companion object { private fun itemsForSection(section: RoomPermissionsSection) = when (section) { - RoomPermissionsSection.SpaceDetails, - RoomPermissionsSection.RoomDetails -> persistentListOf( + RoomPermissionsSection.EditDetails -> persistentListOf( RoomPermissionType.ROOM_NAME, RoomPermissionType.ROOM_AVATAR, RoomPermissionType.ROOM_TOPIC, @@ -51,14 +50,19 @@ class ChangeRoomPermissionsPresenter( RoomPermissionType.KICK, RoomPermissionType.BAN, ) + RoomPermissionsSection.ManageSpace -> persistentListOf( + RoomPermissionType.SPACE_MANAGE_ROOMS, + RoomPermissionType.CHANGE_SETTINGS, + ) + } private fun RoomPermissionsSection.shouldShow(isSpace: Boolean): Boolean { return when (this) { - RoomPermissionsSection.RoomDetails -> !isSpace + RoomPermissionsSection.EditDetails -> true RoomPermissionsSection.MembershipModeration -> true RoomPermissionsSection.MessagesAndContent -> !isSpace - RoomPermissionsSection.SpaceDetails -> isSpace + RoomPermissionsSection.ManageSpace -> isSpace } } @@ -99,11 +103,13 @@ class ChangeRoomPermissionsPresenter( RoomPermissionType.BAN -> currentPermissions?.copy(ban = powerLevel) RoomPermissionType.INVITE -> currentPermissions?.copy(invite = powerLevel) RoomPermissionType.KICK -> currentPermissions?.copy(kick = powerLevel) - RoomPermissionType.SEND_EVENTS -> currentPermissions?.copy(sendEvents = powerLevel) + RoomPermissionType.SEND_EVENTS -> currentPermissions?.copy(eventsDefault = powerLevel) RoomPermissionType.REDACT_EVENTS -> currentPermissions?.copy(redactEvents = powerLevel) RoomPermissionType.ROOM_NAME -> currentPermissions?.copy(roomName = powerLevel) RoomPermissionType.ROOM_AVATAR -> currentPermissions?.copy(roomAvatar = powerLevel) RoomPermissionType.ROOM_TOPIC -> currentPermissions?.copy(roomTopic = powerLevel) + RoomPermissionType.SPACE_MANAGE_ROOMS -> currentPermissions?.copy(spaceChild = powerLevel) + RoomPermissionType.CHANGE_SETTINGS -> currentPermissions?.copy(stateDefault = powerLevel) } } is ChangeRoomPermissionsEvent.Save -> coroutineScope.save() diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt index 0dde54db89..817be2a405 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt @@ -32,11 +32,13 @@ data class ChangeRoomPermissionsState( RoomPermissionType.BAN -> RoomMember.Role.forPowerLevel(currentPermissions.ban) RoomPermissionType.INVITE -> RoomMember.Role.forPowerLevel(currentPermissions.invite) RoomPermissionType.KICK -> RoomMember.Role.forPowerLevel(currentPermissions.kick) - RoomPermissionType.SEND_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.sendEvents) + RoomPermissionType.SEND_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.eventsDefault) RoomPermissionType.REDACT_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.redactEvents) RoomPermissionType.ROOM_NAME -> RoomMember.Role.forPowerLevel(currentPermissions.roomName) RoomPermissionType.ROOM_AVATAR -> RoomMember.Role.forPowerLevel(currentPermissions.roomAvatar) RoomPermissionType.ROOM_TOPIC -> RoomMember.Role.forPowerLevel(currentPermissions.roomTopic) + RoomPermissionType.SPACE_MANAGE_ROOMS -> RoomMember.Role.forPowerLevel(currentPermissions.spaceChild) + RoomPermissionType.CHANGE_SETTINGS -> RoomMember.Role.forPowerLevel(currentPermissions.stateDefault) } return when (role) { is RoomMember.Role.Owner, @@ -48,10 +50,10 @@ data class ChangeRoomPermissionsState( } enum class RoomPermissionsSection { - SpaceDetails, - RoomDetails, + EditDetails, MessagesAndContent, MembershipModeration, + ManageSpace } enum class SelectableRole : DropdownOption { @@ -80,5 +82,7 @@ enum class RoomPermissionType { REDACT_EVENTS, ROOM_NAME, ROOM_AVATAR, - ROOM_TOPIC + ROOM_TOPIC, + SPACE_MANAGE_ROOMS, + CHANGE_SETTINGS, } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt index 6280e4fd8f..b44bfc5075 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt @@ -51,12 +51,13 @@ private fun previewPermissions(): RoomPowerLevelsValues { ban = RoomMember.Role.User.powerLevel, // MessagesAndContent section redactEvents = RoomMember.Role.Moderator.powerLevel, - sendEvents = RoomMember.Role.Admin.powerLevel, + eventsDefault = RoomMember.Role.Admin.powerLevel, // RoomDetails section roomName = RoomMember.Role.Admin.powerLevel, roomAvatar = RoomMember.Role.Moderator.powerLevel, roomTopic = RoomMember.Role.User.powerLevel, // SpaceManagement section spaceChild = RoomMember.Role.Moderator.powerLevel, + stateDefault = RoomMember.Role.Moderator.powerLevel, ) } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt index 5ae8203eb4..fa3552673e 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt @@ -110,10 +110,10 @@ fun ChangeRoomPermissionsView( @Composable private fun titleForSection(section: RoomPermissionsSection): String = when (section) { - RoomPermissionsSection.SpaceDetails -> stringResource(R.string.screen_room_roles_and_permissions_space_details) - RoomPermissionsSection.RoomDetails -> stringResource(R.string.screen_room_roles_and_permissions_room_details) - RoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_roles_and_permissions_messages_and_content) - RoomPermissionsSection.MembershipModeration -> stringResource(R.string.screen_room_roles_and_permissions_member_moderation) + RoomPermissionsSection.EditDetails -> stringResource(R.string.screen_room_change_permissions_room_details) + RoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_change_permissions_messages_and_content) + RoomPermissionsSection.MembershipModeration -> stringResource(R.string.screen_room_change_permissions_member_moderation) + RoomPermissionsSection.ManageSpace -> stringResource(R.string.screen_room_change_permissions_manage_space) } @Composable @@ -126,6 +126,8 @@ private fun titleForType(type: RoomPermissionType): String = when (type) { RoomPermissionType.ROOM_NAME -> stringResource(R.string.screen_room_change_permissions_room_name) RoomPermissionType.ROOM_AVATAR -> stringResource(R.string.screen_room_change_permissions_room_avatar) RoomPermissionType.ROOM_TOPIC -> stringResource(R.string.screen_room_change_permissions_room_topic) + RoomPermissionType.SPACE_MANAGE_ROOMS -> stringResource(R.string.screen_room_change_permissions_manage_space_rooms) + RoomPermissionType.CHANGE_SETTINGS -> stringResource(R.string.screen_room_change_permissions_change_settings) } @PreviewsDayNight diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt index d666ec3ccc..2fb48bf6a4 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt @@ -53,7 +53,7 @@ class ChangeRoomPermissionsPresenterTest { presenter.present() }.test { val itemsBySection = awaitUpdatedItem().itemsBySection - assertThat(itemsBySection[RoomPermissionsSection.RoomDetails]).containsExactly( + assertThat(itemsBySection[RoomPermissionsSection.EditDetails]).containsExactly( RoomPermissionType.ROOM_NAME, RoomPermissionType.ROOM_AVATAR, RoomPermissionType.ROOM_TOPIC, @@ -115,8 +115,9 @@ class ChangeRoomPermissionsPresenterTest { invite = Moderator.powerLevel, kick = Moderator.powerLevel, ban = Moderator.powerLevel, + stateDefault = Moderator.powerLevel, redactEvents = Moderator.powerLevel, - sendEvents = Moderator.powerLevel, + eventsDefault = Moderator.powerLevel, roomName = Moderator.powerLevel, roomAvatar = Moderator.powerLevel, roomTopic = Moderator.powerLevel, diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt index 6b637efbed..f28c9c150f 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt @@ -104,7 +104,7 @@ class ChangeRoomPermissionsViewTest { state = aChangeRoomPermissionsState( itemsBySection = persistentMapOf( // Makes sure there is only one item to click on - RoomPermissionsSection.RoomDetails to persistentListOf(RoomPermissionType.ROOM_NAME) + RoomPermissionsSection.EditDetails to persistentListOf(RoomPermissionType.ROOM_NAME) ), eventSink = recorder, ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt index a7eebbb99c..e8f88ed86d 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt @@ -12,7 +12,8 @@ data class RoomPowerLevelsValues( val ban: Long, val invite: Long, val kick: Long, - val sendEvents: Long, + val eventsDefault: Long, + val stateDefault: Long, val redactEvents: Long, val roomName: Long, val roomAvatar: Long, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt index 943b5ee1d5..770efb3918 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt @@ -397,10 +397,12 @@ class JoinedRustRoom( invite = roomPowerLevelsValues.invite, kick = roomPowerLevelsValues.kick, redact = roomPowerLevelsValues.redactEvents, - eventsDefault = roomPowerLevelsValues.sendEvents, + stateDefault = roomPowerLevelsValues.stateDefault, + eventsDefault = roomPowerLevelsValues.eventsDefault, roomName = roomPowerLevelsValues.roomName, roomAvatar = roomPowerLevelsValues.roomAvatar, roomTopic = roomPowerLevelsValues.roomTopic, + spaceChild = roomPowerLevelsValues.spaceChild, ) innerRoom.applyPowerLevelChanges(changes) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapper.kt index 081d08457e..5e2a1c82da 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapper.kt @@ -19,7 +19,8 @@ object RoomPowerLevelsValuesMapper { ban = values.ban, invite = values.invite, kick = values.kick, - sendEvents = values.eventsDefault, + eventsDefault = values.eventsDefault, + stateDefault = values.stateDefault, redactEvents = values.redact, roomName = values.roomName, roomAvatar = values.roomAvatar, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapperTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapperTest.kt index 3c100283a1..f298da8b42 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapperTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapperTest.kt @@ -37,8 +37,9 @@ class RoomPowerLevelsValuesMapperTest { ban = 1, invite = 2, kick = 3, - sendEvents = 5, redactEvents = 4, + eventsDefault = 5, + stateDefault = 6, roomName = 8, roomAvatar = 9, roomTopic = 10, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt index b56066af73..78765d1ec4 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt @@ -211,10 +211,11 @@ fun defaultRoomPowerLevelValues() = RoomPowerLevelsValues( ban = 50, invite = 0, kick = 50, - sendEvents = 0, + eventsDefault = 0, + stateDefault = 50, redactEvents = 50, - roomName = 100, - roomAvatar = 100, - roomTopic = 100, - spaceChild = 100, + roomName = 50, + roomAvatar = 50, + roomTopic = 50, + spaceChild = 50, )