diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml
index 803510ed76..02fef53306 100644
--- a/library/ui-strings/src/main/res/values/strings.xml
+++ b/library/ui-strings/src/main/res/values/strings.xml
@@ -120,6 +120,7 @@
%1$s modified %2$s widget
You modified %1$s widget
+ Owner
Admin
Moderator
Default
@@ -2383,6 +2384,7 @@
Invites
Users
+ Owner in %1$s
Admin in %1$s
Moderator in %1$s
Default in %1$s
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/space/SpaceHierarchyTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/space/SpaceHierarchyTest.kt
index de661275a7..6c9d0ad983 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/space/SpaceHierarchyTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/space/SpaceHierarchyTest.kt
@@ -40,7 +40,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry
import org.matrix.android.sdk.api.session.room.model.RoomType
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.room.model.create.RestrictedRoomPreset
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.powerlevels.Role
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
import org.matrix.android.sdk.common.CommonTestHelper.Companion.runSessionTest
@@ -500,12 +500,12 @@ class SpaceHierarchyTest : InstrumentedTest {
room.stateService().sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent!!)
commonTestHelper.retryPeriodically {
- val powerLevelsHelper = aliceSession.getRoom(bobRoomId)!!
+ val roomPowerLevels = aliceSession.getRoom(bobRoomId)!!
.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
?.content
?.toModel()
- ?.let { PowerLevelsHelper(it) }
- powerLevelsHelper!!.isUserAllowedToSend(aliceSession.myUserId, true, EventType.STATE_SPACE_PARENT)
+ ?.let { RoomPowerLevels(it) }
+ roomPowerLevels!!.isUserAllowedToSend(aliceSession.myUserId, true, EventType.STATE_SPACE_PARENT)
}
aliceSession.spaceService().setSpaceParent(bobRoomId, spaceAInfo.spaceId, false, listOf(bobSession.sessionParams.homeServerHost ?: ""))
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/SenderNotificationPermissionCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/SenderNotificationPermissionCondition.kt
index 82f5023c2f..c3e9b9f527 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/SenderNotificationPermissionCondition.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/SenderNotificationPermissionCondition.kt
@@ -16,8 +16,7 @@
package org.matrix.android.sdk.api.session.pushrules
import org.matrix.android.sdk.api.session.events.model.Event
-import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
class SenderNotificationPermissionCondition(
/**
@@ -35,8 +34,7 @@ class SenderNotificationPermissionCondition(
override fun technicalDescription() = "User power level <$key>"
- fun isSatisfied(event: Event, powerLevels: PowerLevelsContent): Boolean {
- val powerLevelsHelper = PowerLevelsHelper(powerLevels)
- return event.senderId != null && powerLevelsHelper.getUserPowerLevelValue(event.senderId) >= powerLevels.notificationLevel(key)
+ fun isSatisfied(event: Event, roomPowerLevels: RoomPowerLevels): Boolean {
+ return event.senderId != null && roomPowerLevels.isUserAbleToTriggerNotification(event.senderId, key)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomExtensions.kt
index b30c60554f..29638857bc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomExtensions.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomExtensions.kt
@@ -17,7 +17,13 @@
package org.matrix.android.sdk.api.session.room
import org.matrix.android.sdk.api.query.QueryStateEventValue
+import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.Event
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.toModel
+import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
+import org.matrix.android.sdk.api.session.room.model.create.getRoomCreateContentWithSender
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
/**
@@ -34,3 +40,15 @@ fun Room.getTimelineEvent(eventId: String): TimelineEvent? =
*/
fun Room.getStateEvent(eventType: String, stateKey: QueryStateEventValue): Event? =
stateService().getStateEvent(eventType, stateKey)
+
+/**
+ * Get the current RoomPowerLevels of the room.
+ */
+fun Room.getRoomPowerLevels(): RoomPowerLevels {
+ val powerLevelsContent = getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)?.content?.toModel()
+ val roomCreateContent = getStateEvent(EventType.STATE_ROOM_CREATE, QueryStringValue.IsEmpty)?.getRoomCreateContentWithSender()
+ return RoomPowerLevels(
+ powerLevelsContent,
+ roomCreateContent
+ )
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt
index 0329828130..894640a488 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt
@@ -18,7 +18,8 @@ package org.matrix.android.sdk.api.session.room.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent.Companion.NOTIFICATIONS_ROOM_KEY
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
/**
* Class representing the EventType.EVENT_TYPE_STATE_ROOM_POWER_LEVELS state event content.
@@ -88,7 +89,7 @@ data class PowerLevelsContent(
* Get the notification level for a dedicated key.
*
* @param key the notification key
- * @return the level, default to Moderator if the key is not found
+ * @return the level
*/
fun notificationLevel(key: String): Int {
return when (val value = notifications.orEmpty()[key]) {
@@ -96,10 +97,9 @@ data class PowerLevelsContent(
is String -> value.toInt()
is Double -> value.toInt()
is Int -> value
- else -> Role.Moderator.value
+ else -> defaultNotificationLevel(key)
}
}
-
companion object {
/**
* Key to use for content.notifications and get the level required to trigger an @room notification. Defaults to 50 if unspecified.
@@ -108,11 +108,21 @@ data class PowerLevelsContent(
}
}
+private fun defaultNotificationLevel(key: String): Int {
+ return when (key) {
+ NOTIFICATIONS_ROOM_KEY -> UserPowerLevel.Moderator.value
+ else -> UserPowerLevel.User.value
+ }
+}
+
+
// Fallback to default value, defined in the Matrix specification
-fun PowerLevelsContent.banOrDefault() = ban ?: Role.Moderator.value
-fun PowerLevelsContent.kickOrDefault() = kick ?: Role.Moderator.value
-fun PowerLevelsContent.inviteOrDefault() = invite ?: Role.Moderator.value
-fun PowerLevelsContent.redactOrDefault() = redact ?: Role.Moderator.value
-fun PowerLevelsContent.eventsDefaultOrDefault() = eventsDefault ?: Role.Default.value
-fun PowerLevelsContent.usersDefaultOrDefault() = usersDefault ?: Role.Default.value
-fun PowerLevelsContent.stateDefaultOrDefault() = stateDefault ?: Role.Moderator.value
+fun PowerLevelsContent?.banOrDefault() = this?.ban ?: UserPowerLevel.Moderator.value
+fun PowerLevelsContent?.kickOrDefault() = this?.kick ?: UserPowerLevel.Moderator.value
+fun PowerLevelsContent?.inviteOrDefault() = this?.invite ?: UserPowerLevel.User.value
+fun PowerLevelsContent?.redactOrDefault() = this?.redact ?: UserPowerLevel.Moderator.value
+fun PowerLevelsContent?.eventsDefaultOrDefault() = this?.eventsDefault ?: UserPowerLevel.User.value
+fun PowerLevelsContent?.usersDefaultOrDefault() = this?.usersDefault ?: UserPowerLevel.User.value
+fun PowerLevelsContent?.stateDefaultOrDefault() = this?.stateDefault ?: UserPowerLevel.Moderator.value
+
+fun PowerLevelsContent?.notificationLevelOrDefault(key: String) = this?.notificationLevel(key) ?: defaultNotificationLevel(key)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomCreateContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomCreateContent.kt
index d73c941a86..2408f4a004 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomCreateContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomCreateContent.kt
@@ -18,15 +18,39 @@ package org.matrix.android.sdk.api.session.room.model.create
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
+import org.matrix.android.sdk.api.session.events.model.Event
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.toModel
/**
* Content of a m.room.create type event.
*/
@JsonClass(generateAdapter = true)
data class RoomCreateContent(
+ // Creator should be replaced by the sender of the event
@Json(name = "creator") val creator: String? = null,
@Json(name = "room_version") val roomVersion: String? = null,
@Json(name = "predecessor") val predecessor: Predecessor? = null,
// Defines the room type, see #RoomType (user extensible)
- @Json(name = "type") val type: String? = null
+ @Json(name = "type") val type: String? = null,
+ @Json(name = "additional_creators") val additionalCreators: List? = null,
)
+
+data class RoomCreateContentWithSender(
+ val senderId: String,
+ val inner: RoomCreateContent
+) {
+ val creators = setOf(senderId) + inner.additionalCreators.orEmpty().toSet()
+}
+
+fun Event.getRoomCreateContentWithSender(): RoomCreateContentWithSender? {
+ if (this.type != EventType.STATE_ROOM_CREATE) return null
+ val innerContent = getClearContent().toModel() ?: return null
+ val senderId = senderId ?: return null
+ return RoomCreateContentWithSender(senderId, innerContent)
+}
+
+fun RoomCreateContent.explicitlyPrivilegeRoomCreators(): Boolean {
+ val supportedRoomVersions = listOf("org.matrix.hydra.11", "12")
+ return supportedRoomVersions.contains(roomVersion)
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt
index c5cc573458..57cd75e70d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt
@@ -17,26 +17,22 @@
package org.matrix.android.sdk.api.session.room.powerlevels
-sealed class Role(open val value: Int) : Comparable {
- object Admin : Role(100)
- object Moderator : Role(50)
- object Default : Role(0)
- data class Custom(override val value: Int) : Role(value)
+enum class Role {
+ Creator,
+ SuperAdmin,
+ Admin,
+ Moderator,
+ User;
- override fun compareTo(other: Role): Int {
- return value.compareTo(other.value)
- }
companion object {
-
- // Order matters, default value should be checked after defined roles
- fun fromValue(value: Int, default: Int): Role {
- return when (value) {
- Admin.value -> Admin
- Moderator.value -> Moderator
- Default.value,
- default -> Default
- else -> Custom(value)
+ fun getSuggestedRole(userPowerLevel: UserPowerLevel): Role {
+ return when {
+ userPowerLevel == UserPowerLevel.Infinite -> Creator
+ userPowerLevel >= UserPowerLevel.SuperAdmin -> SuperAdmin
+ userPowerLevel >= UserPowerLevel.Admin -> Admin
+ userPowerLevel >= UserPowerLevel.Moderator -> Moderator
+ else -> User
}
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/PowerLevelsHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/RoomPowerLevels.kt
similarity index 59%
rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/PowerLevelsHelper.kt
rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/RoomPowerLevels.kt
index 36993074aa..d7fbeb8769 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/PowerLevelsHelper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/RoomPowerLevels.kt
@@ -19,17 +19,23 @@ package org.matrix.android.sdk.api.session.room.powerlevels
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.banOrDefault
+import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContentWithSender
+import org.matrix.android.sdk.api.session.room.model.create.explicitlyPrivilegeRoomCreators
import org.matrix.android.sdk.api.session.room.model.eventsDefaultOrDefault
import org.matrix.android.sdk.api.session.room.model.inviteOrDefault
import org.matrix.android.sdk.api.session.room.model.kickOrDefault
+import org.matrix.android.sdk.api.session.room.model.notificationLevelOrDefault
import org.matrix.android.sdk.api.session.room.model.redactOrDefault
import org.matrix.android.sdk.api.session.room.model.stateDefaultOrDefault
import org.matrix.android.sdk.api.session.room.model.usersDefaultOrDefault
/**
- * This class is an helper around PowerLevelsContent.
+ * This class is an helper around PowerLevelsContent and RoomCreateContent.
*/
-class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
+class RoomPowerLevels(
+ val powerLevelsContent: PowerLevelsContent?,
+ private val roomCreateContent: RoomCreateContentWithSender?,
+) {
/**
* Returns the user power level of a dedicated user Id.
@@ -37,10 +43,14 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
* @param userId the user id
* @return the power level
*/
- fun getUserPowerLevelValue(userId: String): Int {
- return powerLevelsContent.users
+ fun getUserPowerLevel(userId: String): UserPowerLevel {
+ if (shouldGiveInfinitePowerLevel(userId)) return UserPowerLevel.Infinite
+ if (powerLevelsContent == null) return UserPowerLevel.User
+ val value = powerLevelsContent.users
?.get(userId)
?: powerLevelsContent.usersDefaultOrDefault()
+
+ return UserPowerLevel.Value(value)
}
/**
@@ -50,9 +60,8 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
* @return the power level
*/
fun getUserRole(userId: String): Role {
- val value = getUserPowerLevelValue(userId)
- // I think we should use powerLevelsContent.usersDefault, but Ganfra told me that it was like that on riot-Web
- return Role.fromValue(value, powerLevelsContent.eventsDefaultOrDefault())
+ val value = getUserPowerLevel(userId)
+ return Role.getSuggestedRole(value)
}
/**
@@ -65,14 +74,14 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
*/
fun isUserAllowedToSend(userId: String, isState: Boolean, eventType: String?): Boolean {
return if (userId.isNotEmpty()) {
- val powerLevel = getUserPowerLevelValue(userId)
- val minimumPowerLevel = powerLevelsContent.events?.get(eventType)
+ val powerLevel = getUserPowerLevel(userId)
+ val minimumPowerLevel = powerLevelsContent?.events?.get(eventType)
?: if (isState) {
powerLevelsContent.stateDefaultOrDefault()
} else {
powerLevelsContent.eventsDefaultOrDefault()
}
- powerLevel >= minimumPowerLevel
+ powerLevel >= UserPowerLevel.Value(minimumPowerLevel)
} else false
}
@@ -82,8 +91,8 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
* @return true if able to invite
*/
fun isUserAbleToInvite(userId: String): Boolean {
- val powerLevel = getUserPowerLevelValue(userId)
- return powerLevel >= powerLevelsContent.inviteOrDefault()
+ val powerLevel = getUserPowerLevel(userId)
+ return powerLevel >= UserPowerLevel.Value(powerLevelsContent.inviteOrDefault())
}
/**
@@ -92,8 +101,8 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
* @return true if able to ban
*/
fun isUserAbleToBan(userId: String): Boolean {
- val powerLevel = getUserPowerLevelValue(userId)
- return powerLevel >= powerLevelsContent.banOrDefault()
+ val powerLevel = getUserPowerLevel(userId)
+ return powerLevel >= UserPowerLevel.Value(powerLevelsContent.banOrDefault())
}
/**
@@ -102,8 +111,8 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
* @return true if able to kick
*/
fun isUserAbleToKick(userId: String): Boolean {
- val powerLevel = getUserPowerLevelValue(userId)
- return powerLevel >= powerLevelsContent.kickOrDefault()
+ val powerLevel = getUserPowerLevel(userId)
+ return powerLevel >= UserPowerLevel.Value(powerLevelsContent.kickOrDefault())
}
/**
@@ -112,7 +121,22 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
* @return true if able to redact
*/
fun isUserAbleToRedact(userId: String): Boolean {
- val powerLevel = getUserPowerLevelValue(userId)
- return powerLevel >= powerLevelsContent.redactOrDefault()
+ val powerLevel = getUserPowerLevel(userId)
+ return powerLevel >= UserPowerLevel.Value(powerLevelsContent.redactOrDefault())
+ }
+
+ fun isUserAbleToTriggerNotification(userId: String, notificationKey: String): Boolean {
+ val userPowerLevel = getUserPowerLevel(userId)
+ val notificationPowerLevel = UserPowerLevel.Value(powerLevelsContent.notificationLevelOrDefault(key = notificationKey))
+ return userPowerLevel >= notificationPowerLevel
+ }
+
+ private fun shouldGiveInfinitePowerLevel(userId: String): Boolean {
+ if (roomCreateContent == null) return false
+ return if (roomCreateContent.inner.explicitlyPrivilegeRoomCreators()) {
+ roomCreateContent.creators.contains(userId)
+ } else {
+ false
+ }
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/UserPowerLevel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/UserPowerLevel.kt
new file mode 100644
index 0000000000..8932f16685
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/UserPowerLevel.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2025 New Vector Ltd.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
+ * Please see LICENSE files in the repository root for full details.
+ */
+
+package org.matrix.android.sdk.api.session.room.powerlevels
+
+sealed interface UserPowerLevel : Comparable {
+ data object Infinite : UserPowerLevel
+
+ @JvmInline
+ value class Value(val value: Int) : UserPowerLevel
+
+ override fun compareTo(other: UserPowerLevel): Int {
+ return when (this) {
+ Infinite -> when (other) {
+ Infinite -> 0
+ is Value -> 1
+ }
+ is Value -> when (other) {
+ Infinite -> -1
+ is Value -> value.compareTo(other.value)
+ }
+ }
+ }
+
+ companion object {
+ val User = Value(0)
+ val Moderator = Value(50)
+ val Admin = Value(100)
+ val SuperAdmin = Value(150)
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt
index 5fb20bb259..7f1277864c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt
@@ -17,15 +17,11 @@
package org.matrix.android.sdk.internal.session.permalinks
import org.matrix.android.sdk.api.MatrixPatterns.getServerName
-import org.matrix.android.sdk.api.query.QueryStringValue
-import org.matrix.android.sdk.api.session.events.model.EventType
-import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
-import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.room.RoomGetter
+import org.matrix.android.sdk.internal.session.room.powerlevels.getRoomPowerLevels
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import java.net.URLEncoder
import javax.inject.Inject
@@ -101,10 +97,7 @@ internal class ViaParameterFinder @Inject constructor(
}
fun userCanInvite(userId: String, roomId: String): Boolean {
- val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
- ?.content?.toModel()
- ?.let { PowerLevelsHelper(it) }
-
- return powerLevelsHelper?.isUserAbleToInvite(userId) ?: false
+ val roomPowerLevels = stateEventDataSource.getRoomPowerLevels(roomId)
+ return roomPowerLevels.isUserAbleToInvite(userId)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultConditionResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultConditionResolver.kt
index c2310f4fda..c1fb93b3ff 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultConditionResolver.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultConditionResolver.kt
@@ -24,15 +24,20 @@ import org.matrix.android.sdk.api.session.pushrules.ContainsDisplayNameCondition
import org.matrix.android.sdk.api.session.pushrules.EventMatchCondition
import org.matrix.android.sdk.api.session.pushrules.RoomMemberCountCondition
import org.matrix.android.sdk.api.session.pushrules.SenderNotificationPermissionCondition
+import org.matrix.android.sdk.api.session.room.getRoomPowerLevels
import org.matrix.android.sdk.api.session.room.getStateEvent
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
+import org.matrix.android.sdk.api.session.room.model.create.getRoomCreateContentWithSender
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.room.RoomGetter
+import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import javax.inject.Inject
internal class DefaultConditionResolver @Inject constructor(
private val roomGetter: RoomGetter,
- @UserId private val userId: String
+ @UserId private val userId: String,
+ private val stateEventDataSource: StateEventDataSource,
) : ConditionResolver {
override fun resolveEventMatchCondition(
@@ -55,13 +60,8 @@ internal class DefaultConditionResolver @Inject constructor(
): Boolean {
val roomId = event.roomId ?: return false
val room = roomGetter.getRoom(roomId) ?: return false
-
- val powerLevelsContent = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
- ?.content
- ?.toModel()
- ?: PowerLevelsContent()
-
- return condition.isSatisfied(event, powerLevelsContent)
+ val roomPowerLevels = room.getRoomPowerLevels()
+ return condition.isSatisfied(event, roomPowerLevels)
}
override fun resolveContainsDisplayNameCondition(
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt
index edc10bd187..3b963c13cb 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt
@@ -16,7 +16,6 @@
package org.matrix.android.sdk.internal.session.room
import io.realm.Realm
-import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.crypto.verification.VerificationState
import org.matrix.android.sdk.api.session.events.model.AggregatedAnnotation
import org.matrix.android.sdk.api.session.events.model.Event
@@ -27,7 +26,6 @@ import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventCon
import org.matrix.android.sdk.api.session.events.model.getRelationContent
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.events.model.toModel
-import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.ReferencesAggregatedContent
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent
@@ -36,7 +34,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent
import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent
import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.internal.SessionManager
import org.matrix.android.sdk.internal.crypto.verification.toState
import org.matrix.android.sdk.internal.database.helper.findRootThreadEvent
@@ -62,6 +60,7 @@ import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.LiveLocationAggregationProcessor
import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollAggregationProcessor
import org.matrix.android.sdk.internal.session.room.aggregation.utd.EncryptedReferenceAggregationProcessor
+import org.matrix.android.sdk.internal.session.room.powerlevels.getRoomPowerLevels
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import org.matrix.android.sdk.internal.util.time.Clock
import timber.log.Timber
@@ -216,9 +215,8 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
}
in EventType.POLL_END.values -> {
sessionManager.getSessionComponent(sessionId)?.session()?.let { session ->
- getPowerLevelsHelper(event.roomId)?.let {
- pollAggregationProcessor.handlePollEndEvent(session, it, realm, event)
- }
+ val roomPowerLevels = stateEventDataSource.getRoomPowerLevels(event.roomId)
+ pollAggregationProcessor.handlePollEndEvent(session, roomPowerLevels, realm, event)
}
}
in EventType.STATE_ROOM_BEACON_INFO.values -> {
@@ -381,12 +379,6 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
}
}
- private fun getPowerLevelsHelper(roomId: String): PowerLevelsHelper? {
- return stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
- ?.content?.toModel()
- ?.let { PowerLevelsHelper(it) }
- }
-
private fun handleInitialAggregatedRelations(
realm: Realm,
event: Event,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt
index ca224cd543..5a6648934e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt
@@ -32,7 +32,7 @@ import org.matrix.android.sdk.api.session.room.model.VoteInfo
import org.matrix.android.sdk.api.session.room.model.VoteSummary
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
@@ -160,13 +160,13 @@ internal class DefaultPollAggregationProcessor @Inject constructor(
return true
}
- override fun handlePollEndEvent(session: Session, powerLevelsHelper: PowerLevelsHelper, realm: Realm, event: Event): Boolean {
+ override fun handlePollEndEvent(session: Session, roomPowerLevels: RoomPowerLevels, realm: Realm, event: Event): Boolean {
val roomId = event.roomId ?: return false
val pollEventId = event.getRelationContent()?.eventId ?: return false
val pollOwnerId = getPollEvent(session, roomId, pollEventId)?.root?.senderId
val isPollOwner = pollOwnerId == event.senderId
- if (!isPollOwner && !powerLevelsHelper.isUserAbleToRedact(event.senderId ?: "")) {
+ if (!isPollOwner && !roomPowerLevels.isUserAbleToRedact(event.senderId ?: "")) {
return false
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt
index 33a69b720a..578ba6064e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt
@@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.session.room.aggregation.poll
import io.realm.Realm
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.Event
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
internal interface PollAggregationProcessor {
/**
@@ -48,7 +48,7 @@ internal interface PollAggregationProcessor {
*/
fun handlePollEndEvent(
session: Session,
- powerLevelsHelper: PowerLevelsHelper,
+ roomPowerLevels: RoomPowerLevels,
realm: Realm,
event: Event
): Boolean
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/powerlevels/RoomPowerLevels.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/powerlevels/RoomPowerLevels.kt
new file mode 100644
index 0000000000..d3556324e7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/powerlevels/RoomPowerLevels.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2025 New Vector Ltd.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
+ * Please see LICENSE files in the repository root for full details.
+ */
+
+package org.matrix.android.sdk.internal.session.room.powerlevels
+
+import org.matrix.android.sdk.api.query.QueryStringValue
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.toModel
+import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
+import org.matrix.android.sdk.api.session.room.model.create.getRoomCreateContentWithSender
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
+import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
+
+internal fun StateEventDataSource.getRoomPowerLevels(roomId: String): RoomPowerLevels {
+ val powerLevelsContent = getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
+ ?.content?.toModel()
+ val roomCreateContent = getStateEvent(roomId, EventType.STATE_ROOM_CREATE, QueryStringValue.IsEmpty)?.getRoomCreateContentWithSender()
+ return RoomPowerLevels(powerLevelsContent, roomCreateContent)
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt
index 723d604ad4..433a4399a3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt
@@ -96,3 +96,4 @@ internal class StateEventDataSource @Inject constructor(
}
}
}
+
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt
index cbb75398c4..8820af2034 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt
@@ -34,7 +34,8 @@ import org.matrix.android.sdk.api.session.room.model.RoomTopicContent
import org.matrix.android.sdk.api.session.room.model.RoomType
import org.matrix.android.sdk.api.session.room.model.VersioningState
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContentWithSender
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.api.session.sync.model.RoomSyncSummary
import org.matrix.android.sdk.api.session.sync.model.RoomSyncUnreadNotifications
@@ -313,13 +314,25 @@ internal class RoomSummaryUpdater @Inject constructor(
// check if sender can post child relation in parent?
val senderId = parentInfo.stateEventSender
val parentRoomId = parentInfo.roomId
- val powerLevelsHelper = CurrentStateEventEntity
+ val powerLevelsContent = CurrentStateEventEntity
.getOrNull(realm, parentRoomId, "", EventType.STATE_ROOM_POWER_LEVELS)
?.root
?.let { ContentMapper.map(it.content).toModel() }
- ?.let { PowerLevelsHelper(it) }
- isValidRelation = powerLevelsHelper?.isUserAllowedToSend(senderId, true, EventType.STATE_SPACE_CHILD) ?: false
+ val roomCreateContent = CurrentStateEventEntity
+ .getOrNull(realm, parentRoomId, "", EventType.STATE_ROOM_CREATE)
+ ?.root
+ ?.let {
+ val content = ContentMapper.map(it.content).toModel()
+ val sender = it.sender
+ if (content != null && sender != null) {
+ RoomCreateContentWithSender(sender, content)
+ } else {
+ null
+ }
+ }
+ val roomPowerLevels = RoomPowerLevels(powerLevelsContent, roomCreateContent)
+ isValidRelation = roomPowerLevels.isUserAllowedToSend(senderId, true, EventType.STATE_SPACE_CHILD)
}
if (isValidRelation) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/version/DefaultRoomVersionService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/version/DefaultRoomVersionService.kt
index 0bde3a11d2..fd99bb7158 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/version/DefaultRoomVersionService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/version/DefaultRoomVersionService.kt
@@ -25,7 +25,8 @@ import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.homeserver.RoomVersionStatus
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.model.create.getRoomCreateContentWithSender
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.version.RoomVersionService
import org.matrix.android.sdk.internal.session.homeserver.HomeServerCapabilitiesDataSource
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
@@ -71,11 +72,17 @@ internal class DefaultRoomVersionService @AssistedInject constructor(
}
override fun userMayUpgradeRoom(userId: String): Boolean {
- val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
+ val powerLevelsContent = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
?.content?.toModel()
- ?.let { PowerLevelsHelper(it) }
- return powerLevelsHelper?.isUserAllowedToSend(userId, true, EventType.STATE_ROOM_TOMBSTONE) ?: false
+ val roomCreateContent = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_CREATE, QueryStringValue.IsEmpty)
+ ?.getRoomCreateContentWithSender()
+
+ val roomPowerLevels = RoomPowerLevels(
+ powerLevelsContent = powerLevelsContent,
+ roomCreateContent = roomCreateContent
+ )
+ return roomPowerLevels.isUserAllowedToSend(userId, true, EventType.STATE_ROOM_TOMBSTONE)
}
companion object {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt
index cd13b03017..80ecc4fa81 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt
@@ -35,8 +35,9 @@ import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
import org.matrix.android.sdk.api.session.space.CreateSpaceParams
import org.matrix.android.sdk.api.session.space.JoinSpaceResult
import org.matrix.android.sdk.api.session.space.Space
@@ -47,11 +48,13 @@ import org.matrix.android.sdk.api.session.space.model.SpaceChildContent
import org.matrix.android.sdk.api.session.space.model.SpaceChildSummaryEvent
import org.matrix.android.sdk.api.session.space.model.SpaceParentContent
import org.matrix.android.sdk.api.session.space.peeking.SpacePeekResult
+import org.matrix.android.sdk.api.session.user.model.User
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.room.RoomGetter
import org.matrix.android.sdk.internal.session.room.SpaceGetter
import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask
import org.matrix.android.sdk.internal.session.room.membership.leaving.LeaveRoomTask
+import org.matrix.android.sdk.internal.session.room.powerlevels.getRoomPowerLevels
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
import org.matrix.android.sdk.internal.session.space.peeking.PeekSpaceTask
@@ -83,7 +86,7 @@ internal class DefaultSpaceService @Inject constructor(
if (isPublic) {
this.roomAliasName = roomAliasLocalPart
this.powerLevelContentOverride = (powerLevelContentOverride ?: PowerLevelsContent()).copy(
- invite = if (isPublic) Role.Default.value else Role.Moderator.value
+ invite = UserPowerLevel.User.value
)
this.preset = CreateRoomPreset.PRESET_PUBLIC_CHAT
this.historyVisibility = RoomHistoryVisibility.WORLD_READABLE
@@ -253,15 +256,8 @@ internal class DefaultSpaceService @Inject constructor(
if (roomSummaryDataSource.getRoomSummary(parentSpaceId)?.membership != Membership.JOIN) {
throw UnsupportedOperationException("Cannot add canonical child if not member of parent")
}
- val powerLevelsEvent = stateEventDataSource.getStateEvent(
- roomId = parentSpaceId,
- eventType = EventType.STATE_ROOM_POWER_LEVELS,
- stateKey = QueryStringValue.IsEmpty
- )
- val powerLevelsContent = powerLevelsEvent?.content?.toModel()
- ?: throw UnsupportedOperationException("Cannot add canonical child, missing power level")
- val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent)
- if (!powerLevelsHelper.isUserAllowedToSend(userId, true, EventType.STATE_SPACE_CHILD)) {
+ val roomPowerLevels = stateEventDataSource.getRoomPowerLevels(parentSpaceId)
+ if (!roomPowerLevels.isUserAllowedToSend(userId, true, EventType.STATE_SPACE_CHILD)) {
throw UnsupportedOperationException("Cannot add canonical child, not enough power level")
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt
index 7359fdbd91..8f197706ff 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt
@@ -30,15 +30,13 @@ import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
-import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
-import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.widgets.WidgetManagementFailure
import org.matrix.android.sdk.api.session.widgets.model.Widget
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
+import org.matrix.android.sdk.internal.session.room.powerlevels.getRoomPowerLevels
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource
import org.matrix.android.sdk.internal.session.widgets.helper.WidgetFactory
@@ -200,12 +198,7 @@ internal class WidgetManager @Inject constructor(
}
fun hasPermissionsToHandleWidgets(roomId: String): Boolean {
- val powerLevelsEvent = stateEventDataSource.getStateEvent(
- roomId = roomId,
- eventType = EventType.STATE_ROOM_POWER_LEVELS,
- stateKey = QueryStringValue.IsEmpty
- )
- val powerLevelsContent = powerLevelsEvent?.content?.toModel() ?: return false
- return PowerLevelsHelper(powerLevelsContent).isUserAllowedToSend(userId, true, EventType.STATE_ROOM_WIDGET_LEGACY)
+ val roomPowerLevels = stateEventDataSource.getRoomPowerLevels(roomId)
+ return roomPowerLevels.isUserAllowedToSend(userId, true, EventType.STATE_ROOM_WIDGET_LEGACY)
}
}
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessorTest.kt
index 248c4b322d..bdfffa9d51 100644
--- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessorTest.kt
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessorTest.kt
@@ -33,7 +33,7 @@ import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.getTimelineEvent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields
import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSummaryEntity
@@ -255,9 +255,9 @@ class DefaultPollAggregationProcessorTest {
every { room.getTimelineEvent(eventId) } returns if (hasExistingTimelineEvent) A_TIMELINE_EVENT else null
}
- private fun mockRedactionPowerLevels(userId: String, isAbleToRedact: Boolean): PowerLevelsHelper {
- val powerLevelsHelper = mockk()
- every { powerLevelsHelper.isUserAbleToRedact(userId) } returns isAbleToRedact
- return powerLevelsHelper
+ private fun mockRedactionPowerLevels(userId: String, isAbleToRedact: Boolean): RoomPowerLevels {
+ val roomPowerLevels = mockk()
+ every { roomPowerLevels.isUserAbleToRedact(userId) } returns isAbleToRedact
+ return roomPowerLevels
}
}
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/create/DefaultCreateLocalRoomStateEventsTaskTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/create/DefaultCreateLocalRoomStateEventsTaskTest.kt
index 1c2cf293b6..0669776394 100644
--- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/create/DefaultCreateLocalRoomStateEventsTaskTest.kt
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/create/DefaultCreateLocalRoomStateEventsTaskTest.kt
@@ -376,8 +376,8 @@ internal class DefaultCreateLocalRoomStateEventsTaskTest {
powerLevelsContent.kick shouldBeEqualTo Role.Moderator.value
powerLevelsContent.invite shouldBeEqualTo Role.Moderator.value
powerLevelsContent.redact shouldBeEqualTo Role.Moderator.value
- powerLevelsContent.eventsDefault shouldBeEqualTo Role.Default.value
- powerLevelsContent.usersDefault shouldBeEqualTo Role.Default.value
+ powerLevelsContent.eventsDefault shouldBeEqualTo Role.User.value
+ powerLevelsContent.usersDefault shouldBeEqualTo Role.User.value
powerLevelsContent.stateDefault shouldBeEqualTo Role.Moderator.value
// Guest access
result.find { it.type == EventType.STATE_ROOM_GUEST_ACCESS }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
index 618b31796f..72b72990e8 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
@@ -110,7 +110,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageWithAttachme
import org.matrix.android.sdk.api.session.room.model.message.getFileUrl
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
import org.matrix.android.sdk.api.session.room.model.tombstone.RoomTombstoneContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.read.ReadService
import org.matrix.android.sdk.api.session.room.timeline.Timeline
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
@@ -304,11 +303,11 @@ class TimelineViewModel @AssistedInject constructor(
private fun observePowerLevel() {
if (room == null) return
PowerLevelsFlowFactory(room).createFlow()
- .onEach {
- val canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId)
+ .onEach { powerLevels ->
+ val canInvite = powerLevels.isUserAbleToInvite(session.myUserId)
val isAllowedToManageWidgets = session.widgetService().hasPermissionsToHandleWidgets(room.roomId)
- val isAllowedToStartWebRTCCall = PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, false, EventType.CALL_INVITE)
- val isAllowedToSetupEncryption = PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
+ val isAllowedToStartWebRTCCall = powerLevels.isUserAllowedToSend(session.myUserId, false, EventType.CALL_INVITE)
+ val isAllowedToSetupEncryption = powerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
setState {
copy(
canInvite = canInvite,
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
index 928adb63f4..00bc1890e7 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
@@ -69,7 +69,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
import org.matrix.android.sdk.api.session.room.model.message.MessageContentWithFormattedBody
import org.matrix.android.sdk.api.session.room.model.message.MessageType
import org.matrix.android.sdk.api.session.room.model.relation.shouldRenderInThread
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.send.UserDraft
import org.matrix.android.sdk.api.session.room.timeline.getRelationContent
import org.matrix.android.sdk.api.session.room.timeline.getTextEditableContent
@@ -183,7 +182,7 @@ class MessageComposerViewModel @AssistedInject constructor(
PowerLevelsFlowFactory(room).createFlow(),
room.flow().liveRoomSummary().unwrap()
) { pl, sum ->
- val canSendMessage = PowerLevelsHelper(pl).isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE)
+ val canSendMessage = pl.isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE)
if (canSendMessage) {
val isE2E = sum.isEncrypted
if (isE2E) {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
index 1028a0548f..8a4e3bb797 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
@@ -49,7 +49,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
import org.matrix.android.sdk.api.session.room.model.message.MessageType
import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent
import org.matrix.android.sdk.api.session.room.model.message.MessageWithAttachmentContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.session.room.timeline.hasBeenEdited
@@ -117,11 +117,10 @@ class MessageActionsViewModel @AssistedInject constructor(
return
}
PowerLevelsFlowFactory(room).createFlow()
- .onEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
- val canReact = powerLevelsHelper.isUserAllowedToSend(session.myUserId, false, EventType.REACTION)
- val canRedact = powerLevelsHelper.isUserAbleToRedact(session.myUserId)
- val canSendMessage = powerLevelsHelper.isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE)
+ .onEach { roomPowerLevels ->
+ val canReact = roomPowerLevels.isUserAllowedToSend(session.myUserId, false, EventType.REACTION)
+ val canRedact = roomPowerLevels.isUserAbleToRedact(session.myUserId)
+ val canSendMessage = roomPowerLevels.isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE)
val permissions = ActionPermissions(canSendMessage = canSendMessage, canRedact = canRedact, canReact = canReact)
setState {
copy(actionPermissions = permissions)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt
index 45ba700d1f..c36cd14641 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt
@@ -30,10 +30,11 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom
+import org.matrix.android.sdk.api.session.room.getRoomPowerLevels
import org.matrix.android.sdk.api.session.room.getStateEvent
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import javax.inject.Inject
@@ -303,9 +304,7 @@ class MergedHeaderItemFactory @Inject constructor(
collapsedEventIds.removeAll(mergedEventIds)
}
val mergeId = mergedEventIds.joinToString(separator = "_") { it.toString() }
- val powerLevelsHelper = activeSessionHolder.getSafeActiveSession()?.getRoom(event.roomId)
- ?.let { it.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)?.content?.toModel() }
- ?.let { PowerLevelsHelper(it) }
+ val roomPowerLevels = activeSessionHolder.getSafeActiveSession()?.getRoom(event.roomId)?.getRoomPowerLevels()
val currentUserId = activeSessionHolder.getSafeActiveSession()?.myUserId ?: ""
val attributes = MergedRoomCreationItem.Attributes(
isCollapsed = isCollapsed,
@@ -320,10 +319,10 @@ class MergedHeaderItemFactory @Inject constructor(
callback = callback,
currentUserId = currentUserId,
roomSummary = partialState.roomSummary,
- canInvite = powerLevelsHelper?.isUserAbleToInvite(currentUserId) ?: false,
- canChangeAvatar = powerLevelsHelper?.isUserAllowedToSend(currentUserId, true, EventType.STATE_ROOM_AVATAR) ?: false,
- canChangeTopic = powerLevelsHelper?.isUserAllowedToSend(currentUserId, true, EventType.STATE_ROOM_TOPIC) ?: false,
- canChangeName = powerLevelsHelper?.isUserAllowedToSend(currentUserId, true, EventType.STATE_ROOM_NAME) ?: false
+ canInvite = roomPowerLevels?.isUserAbleToInvite(currentUserId) ?: false,
+ canChangeAvatar = roomPowerLevels?.isUserAllowedToSend(currentUserId, true, EventType.STATE_ROOM_AVATAR) ?: false,
+ canChangeTopic = roomPowerLevels?.isUserAllowedToSend(currentUserId, true, EventType.STATE_ROOM_TOPIC) ?: false,
+ canChangeName = roomPowerLevels?.isUserAllowedToSend(currentUserId, true, EventType.STATE_ROOM_NAME) ?: false
)
MergedRoomCreationItem_()
.id(mergeId)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt
index bd1c903f1f..5a8d3fc41a 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt
@@ -41,7 +41,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomThirdPartyInviteContent
import org.matrix.android.sdk.api.session.room.model.RoomTopicContent
import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.session.widgets.model.WidgetContent
import timber.log.Timber
@@ -122,8 +122,8 @@ class NoticeEventFormatter @Inject constructor(
userIds.addAll(previousPowerLevelsContent.users.orEmpty().keys)
val diffs = ArrayList()
userIds.forEach { userId ->
- val from = PowerLevelsHelper(previousPowerLevelsContent).getUserRole(userId)
- val to = PowerLevelsHelper(powerLevelsContent).getUserRole(userId)
+ val from = RoomPowerLevels(previousPowerLevelsContent,null).getUserRole(userId)
+ val to = RoomPowerLevels(powerLevelsContent, null).getUserRole(userId)
if (from != to) {
val fromStr = roleFormatter.format(from)
val toStr = roleFormatter.format(to)
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt
index 82820e90cb..dfa1ec4549 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt
@@ -34,7 +34,7 @@ import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.getUserOrDefault
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.util.toMatrixItem
import timber.log.Timber
@@ -75,11 +75,10 @@ class LocationSharingViewModel @AssistedInject constructor(
private fun observePowerLevelsForLiveLocationSharing() {
PowerLevelsFlowFactory(room).createFlow()
.distinctUntilChanged()
- .setOnEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
+ .setOnEach { roomPowerLevels ->
val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO.values
.all { beaconInfoType ->
- powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType)
+ roomPowerLevels.isUserAllowedToSend(session.myUserId, true, beaconInfoType)
}
copy(canShareLiveLocation = canShareLiveLocation)
diff --git a/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt b/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt
index f065334ae7..689add249c 100644
--- a/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt
+++ b/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt
@@ -9,23 +9,40 @@ package im.vector.app.features.powerlevel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOn
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
+import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
+import org.matrix.android.sdk.api.session.room.model.create.getRoomCreateContentWithSender
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.mapOptional
-import org.matrix.android.sdk.flow.unwrap
class PowerLevelsFlowFactory(private val room: Room) {
- fun createFlow(): Flow {
- return room.flow()
+ fun createFlow(): Flow {
+ val flowRoom = room.flow()
+ val powerLevelsFlow = flowRoom
.liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
.mapOptional { it.content.toModel() }
.flowOn(Dispatchers.Default)
- .unwrap()
+
+ val roomCreateFlow = flowRoom
+ .liveStateEvent(EventType.STATE_ROOM_CREATE, QueryStringValue.IsEmpty)
+ .mapOptional { event ->
+ event.getRoomCreateContentWithSender()
+ }
+ .flowOn(Dispatchers.Default)
+
+ return combine(powerLevelsFlow, roomCreateFlow) { powerLevelsContent, roomCreateContent ->
+ RoomPowerLevels(
+ powerLevelsContent = powerLevelsContent.getOrNull(),
+ roomCreateContent = roomCreateContent.getOrNull()
+ )
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileAction.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileAction.kt
index 8e764470c7..ade308339e 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileAction.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileAction.kt
@@ -8,6 +8,7 @@
package im.vector.app.features.roommemberprofile
import im.vector.app.core.platform.VectorViewModelAction
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
sealed class RoomMemberProfileAction : VectorViewModelAction {
object RetryFetchingInfo : RoomMemberProfileAction()
@@ -18,7 +19,7 @@ sealed class RoomMemberProfileAction : VectorViewModelAction {
object InviteUser : RoomMemberProfileAction()
object VerifyUser : RoomMemberProfileAction()
object ShareRoomMemberProfile : RoomMemberProfileAction()
- data class SetPowerLevel(val previousValue: Int, val newValue: Int, val askForValidation: Boolean) : RoomMemberProfileAction()
+ data class SetPowerLevel(val previousValue: UserPowerLevel, val newValue: UserPowerLevel.Value, val askForValidation: Boolean) : RoomMemberProfileAction()
data class SetUserColorOverride(val newColorSpec: String) : RoomMemberProfileAction()
data class OpenOrCreateDm(val userId: String) : RoomMemberProfileAction()
}
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt
index 95ee18682e..f4420d6a42 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt
@@ -17,8 +17,8 @@ import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence
import im.vector.lib.strings.CommonStrings
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.room.model.Membership
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
import javax.inject.Inject
class RoomMemberProfileController @Inject constructor(
@@ -38,7 +38,7 @@ class RoomMemberProfileController @Inject constructor(
fun onOverrideColorClicked()
fun onJumpToReadReceiptClicked()
fun onMentionClicked()
- fun onEditPowerLevel(currentRole: Role)
+ fun onEditPowerLevel(userPowerLevel: UserPowerLevel)
fun onKickClicked(isSpace: Boolean)
fun onBanClicked(isSpace: Boolean, isUserBanned: Boolean)
fun onCancelInviteClicked()
@@ -243,11 +243,10 @@ class RoomMemberProfileController @Inject constructor(
}
private fun buildAdminSection(state: RoomMemberProfileViewState) {
- val powerLevelsContent = state.powerLevelsContent ?: return
val powerLevelsStr = state.userPowerLevelString() ?: return
- val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent)
- val userPowerLevel = powerLevelsHelper.getUserRole(state.userId)
- val myPowerLevel = powerLevelsHelper.getUserRole(session.myUserId)
+ val roomPowerLevels = state.roomPowerLevels ?: return
+ val userPowerLevel = roomPowerLevels.getUserPowerLevel(state.userId)
+ val myPowerLevel = roomPowerLevels.getUserPowerLevel(session.myUserId)
if ((!state.isMine && myPowerLevel <= userPowerLevel)) {
return
}
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt
index 29cb42a686..836e3857cc 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt
@@ -51,7 +51,7 @@ import im.vector.app.features.roommemberprofile.powerlevel.EditPowerLevelDialogs
import im.vector.lib.strings.CommonStrings
import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.session.crypto.model.UserVerificationLevel
-import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
import org.matrix.android.sdk.api.util.MatrixItem
import javax.inject.Inject
@@ -377,9 +377,9 @@ class RoomMemberProfileFragment :
.show()
}
- override fun onEditPowerLevel(currentRole: Role) {
- EditPowerLevelDialogs.showChoice(requireActivity(), CommonStrings.power_level_edit_title, currentRole) { newPowerLevel ->
- viewModel.handle(RoomMemberProfileAction.SetPowerLevel(currentRole.value, newPowerLevel, true))
+ override fun onEditPowerLevel(userPowerLevel: UserPowerLevel) {
+ EditPowerLevelDialogs.showChoice(requireActivity(), CommonStrings.power_level_edit_title, userPowerLevel) { newPowerLevel ->
+ viewModel.handle(RoomMemberProfileAction.SetPowerLevel(userPowerLevel, newPowerLevel, true))
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt
index d806f521ad..11bb19c51b 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt
@@ -8,6 +8,7 @@
package im.vector.app.features.roommemberprofile
import im.vector.app.core.platform.VectorViewEvents
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
/**
* Transient events for RoomMemberProfile.
@@ -22,8 +23,8 @@ sealed class RoomMemberProfileViewEvents : VectorViewEvents {
object OnInviteActionSuccess : RoomMemberProfileViewEvents()
object OnKickActionSuccess : RoomMemberProfileViewEvents()
object OnBanActionSuccess : RoomMemberProfileViewEvents()
- data class ShowPowerLevelValidation(val currentValue: Int, val newValue: Int) : RoomMemberProfileViewEvents()
- data class ShowPowerLevelDemoteWarning(val currentValue: Int, val newValue: Int) : RoomMemberProfileViewEvents()
+ data class ShowPowerLevelValidation(val currentValue: UserPowerLevel, val newValue: UserPowerLevel.Value) : RoomMemberProfileViewEvents()
+ data class ShowPowerLevelDemoteWarning(val currentValue: UserPowerLevel, val newValue: UserPowerLevel.Value) : RoomMemberProfileViewEvents()
data class StartVerification(
val userId: String,
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt
index 91024ee136..92ba7acfb5 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt
@@ -42,9 +42,9 @@ import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
+import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.RoomEncryptionAlgorithm
import org.matrix.android.sdk.api.session.room.model.RoomType
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.powerlevels.Role
import org.matrix.android.sdk.api.session.user.model.User
import org.matrix.android.sdk.api.util.toMatrixItem
@@ -233,15 +233,15 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
if (room == null || action.previousValue == action.newValue) {
return@withState
}
- val currentPowerLevelsContent = state.powerLevelsContent ?: return@withState
- val myPowerLevel = PowerLevelsHelper(currentPowerLevelsContent).getUserPowerLevelValue(session.myUserId)
+ val roomPowerLevels = state.roomPowerLevels ?: return@withState
+ val myPowerLevel = roomPowerLevels.getUserPowerLevel(session.myUserId)
if (action.askForValidation && action.newValue >= myPowerLevel) {
_viewEvents.post(RoomMemberProfileViewEvents.ShowPowerLevelValidation(action.previousValue, action.newValue))
} else if (action.askForValidation && state.isMine) {
_viewEvents.post(RoomMemberProfileViewEvents.ShowPowerLevelDemoteWarning(action.previousValue, action.newValue))
} else {
- val newPowerLevelsContent = currentPowerLevelsContent
- .setUserPowerLevel(state.userId, action.newValue)
+ val newPowerLevelsContent = (roomPowerLevels.powerLevelsContent ?: PowerLevelsContent())
+ .setUserPowerLevel(state.userId, action.newValue.value)
.toContent()
viewModelScope.launch {
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
@@ -361,19 +361,17 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
private fun observeRoomSummaryAndPowerLevels(room: Room) {
val roomSummaryLive = room.flow().liveRoomSummary().unwrap()
- val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow()
-
- powerLevelsContentLive
- .onEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
+ val powerLevelsFlow = PowerLevelsFlowFactory(room).createFlow()
+ powerLevelsFlow
+ .onEach { roomPowerLevels ->
val permissions = ActionPermissions(
- canKick = powerLevelsHelper.isUserAbleToKick(session.myUserId),
- canBan = powerLevelsHelper.isUserAbleToBan(session.myUserId),
- canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId),
- canEditPowerLevel = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_POWER_LEVELS)
+ canKick = roomPowerLevels.isUserAbleToKick(session.myUserId),
+ canBan = roomPowerLevels.isUserAbleToBan(session.myUserId),
+ canInvite = roomPowerLevels.isUserAbleToInvite(session.myUserId),
+ canEditPowerLevel = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_POWER_LEVELS)
)
setState {
- copy(powerLevelsContent = it, actionPermissions = permissions)
+ copy(roomPowerLevels = roomPowerLevels, actionPermissions = permissions)
}
}.launchIn(viewModelScope)
@@ -388,14 +386,14 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
copy(isRoomEncrypted = false)
}
}
- roomSummaryLive.combine(powerLevelsContentLive) { roomSummary, powerLevelsContent ->
+ roomSummaryLive.combine(powerLevelsFlow) { roomSummary, roomPowerLevels ->
val roomName = roomSummary.toMatrixItem().getBestName()
- val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent)
- when (val userPowerLevel = powerLevelsHelper.getUserRole(initialState.userId)) {
+ when (roomPowerLevels.getUserRole(initialState.userId)) {
+ Role.SuperAdmin,
+ Role.Creator,
Role.Admin -> stringProvider.getString(CommonStrings.room_member_power_level_admin_in, roomName)
Role.Moderator -> stringProvider.getString(CommonStrings.room_member_power_level_moderator_in, roomName)
- Role.Default -> stringProvider.getString(CommonStrings.room_member_power_level_default_in, roomName)
- is Role.Custom -> stringProvider.getString(CommonStrings.room_member_power_level_custom_in, userPowerLevel.value, roomName)
+ Role.User -> stringProvider.getString(CommonStrings.room_member_power_level_default_in, roomName)
}
}.execute {
copy(userPowerLevelString = it)
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewState.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewState.kt
index 7d550c891d..a51eeef8e3 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewState.kt
@@ -12,7 +12,7 @@ import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.Uninitialized
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
import org.matrix.android.sdk.api.session.room.model.Membership
-import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.util.MatrixItem
data class RoomMemberProfileViewState(
@@ -24,7 +24,7 @@ data class RoomMemberProfileViewState(
val isIgnored: Async = Uninitialized,
val isRoomEncrypted: Boolean = false,
val isAlgorithmSupported: Boolean = true,
- val powerLevelsContent: PowerLevelsContent? = null,
+ val roomPowerLevels: RoomPowerLevels? = null,
val userPowerLevelString: Async = Uninitialized,
val userMatrixItem: Async = Uninitialized,
val userMXCrossSigningInfo: MXCrossSigningInfo? = null,
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt
index ffe6314592..6d24f198f4 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt
@@ -19,6 +19,7 @@ import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.databinding.DialogEditPowerLevelBinding
import im.vector.lib.strings.CommonStrings
import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
object EditPowerLevelDialogs {
@@ -26,21 +27,21 @@ object EditPowerLevelDialogs {
fun showChoice(
activity: Activity,
@StringRes titleRes: Int,
- currentRole: Role,
- listener: (Int) -> Unit
+ currentPowerLevel: UserPowerLevel,
+ listener: (UserPowerLevel.Value) -> Unit
) {
val dialogLayout = activity.layoutInflater.inflate(R.layout.dialog_edit_power_level, null)
val views = DialogEditPowerLevelBinding.bind(dialogLayout)
views.powerLevelRadioGroup.setOnCheckedChangeListener { _, checkedId ->
views.powerLevelCustomEditLayout.isVisible = checkedId == R.id.powerLevelCustomRadio
}
- views.powerLevelCustomEdit.setText("${currentRole.value}")
-
+ val currentRole = Role.getSuggestedRole(currentPowerLevel)
when (currentRole) {
+ Role.Creator -> views.powerLevelAdminRadio.isChecked = true
+ Role.SuperAdmin -> views.powerLevelAdminRadio.isChecked = true
Role.Admin -> views.powerLevelAdminRadio.isChecked = true
Role.Moderator -> views.powerLevelModeratorRadio.isChecked = true
- Role.Default -> views.powerLevelDefaultRadio.isChecked = true
- else -> views.powerLevelCustomRadio.isChecked = true
+ Role.User -> views.powerLevelDefaultRadio.isChecked = true
}
MaterialAlertDialogBuilder(activity)
@@ -48,14 +49,14 @@ object EditPowerLevelDialogs {
.setView(dialogLayout)
.setPositiveButton(CommonStrings.edit) { _, _ ->
val newValue = when (views.powerLevelRadioGroup.checkedRadioButtonId) {
- R.id.powerLevelAdminRadio -> Role.Admin.value
- R.id.powerLevelModeratorRadio -> Role.Moderator.value
- R.id.powerLevelDefaultRadio -> Role.Default.value
- else -> {
- views.powerLevelCustomEdit.text?.toString()?.toInt() ?: currentRole.value
- }
+ R.id.powerLevelAdminRadio -> UserPowerLevel.Admin
+ R.id.powerLevelModeratorRadio -> UserPowerLevel.Moderator
+ R.id.powerLevelDefaultRadio -> UserPowerLevel.User
+ else -> null
+ }
+ if(newValue != null) {
+ listener(newValue)
}
- listener(newValue)
}
.setNegativeButton(CommonStrings.action_cancel, null)
.setOnKeyListener(DialogInterface.OnKeyListener
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt
index 83b1c5a950..deb609509a 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt
@@ -39,7 +39,7 @@ import org.matrix.android.sdk.api.session.room.getStateEvent
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.state.isPublic
import org.matrix.android.sdk.flow.FlowRoom
import org.matrix.android.sdk.flow.flow
@@ -115,9 +115,8 @@ class RoomProfileViewModel @AssistedInject constructor(
private fun observePowerLevels() {
val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow()
powerLevelsContentLive
- .onEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
- val canUpdateRoomState = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
+ .onEach { roomPowerLevels ->
+ val canUpdateRoomState = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
setState {
copy(canUpdateRoomState = canUpdateRoomState)
}
@@ -158,10 +157,9 @@ class RoomProfileViewModel @AssistedInject constructor(
private fun observePermissions() {
PowerLevelsFlowFactory(room)
.createFlow()
- .setOnEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
+ .setOnEach { roomPowerLevels ->
val permissions = RoomProfileViewState.ActionPermissions(
- canEnableEncryption = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
+ canEnableEncryption = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
)
copy(actionPermissions = permissions)
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt
index a80e7b2050..73f8e92434 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt
@@ -29,7 +29,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.mapOptional
import org.matrix.android.sdk.flow.unwrap
@@ -127,10 +127,9 @@ class RoomAliasViewModel @AssistedInject constructor(
private fun observePowerLevel() {
PowerLevelsFlowFactory(room)
.createFlow()
- .onEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
+ .onEach { roomPowerLevels ->
val permissions = RoomAliasViewState.ActionPermissions(
- canChangeCanonicalAlias = powerLevelsHelper.isUserAllowedToSend(
+ canChangeCanonicalAlias = roomPowerLevels.isUserAllowedToSend(
userId = session.myUserId,
isState = true,
eventType = EventType.STATE_ROOM_CANONICAL_ALIAS
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt
index df697bd501..acfdbb8b1c 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt
@@ -29,7 +29,7 @@ import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.unwrap
@@ -62,12 +62,10 @@ class RoomBannedMemberListViewModel @AssistedInject constructor(
)
}
- val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow()
-
- powerLevelsContentLive
- .setOnEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
- copy(canUserBan = powerLevelsHelper.isUserAbleToBan(session.myUserId))
+ val powerLevelsFlow = PowerLevelsFlowFactory(room).createFlow()
+ powerLevelsFlow
+ .setOnEach { roomPowerLevels ->
+ copy(canUserBan = roomPowerLevels.isUserAbleToBan(session.myUserId))
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListComparator.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListComparator.kt
new file mode 100644
index 0000000000..a4ce99f63d
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListComparator.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020-2024 New Vector Ltd.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
+ * Please see LICENSE files in the repository root for full details.
+ */
+
+package im.vector.app.features.roomprofile.members
+
+import javax.inject.Inject
+
+class RoomMemberListComparator @Inject constructor() : Comparator {
+
+ override fun compare(leftRoomMember: RoomMemberWithPowerLevel?, rightRoomMember: RoomMemberWithPowerLevel?): Int {
+ return when (leftRoomMember) {
+ null ->
+ when (rightRoomMember) {
+ null -> 0
+ else -> 1
+ }
+ else ->
+ when (rightRoomMember) {
+ null -> -1
+ else ->
+ when {
+ leftRoomMember.powerLevel > rightRoomMember.powerLevel -> 1
+ leftRoomMember.powerLevel < rightRoomMember.powerLevel -> -1
+ leftRoomMember.summary.displayName.isNullOrBlank() ->
+ when {
+ rightRoomMember.summary.displayName.isNullOrBlank() -> {
+ // No display names, compare ids
+ leftRoomMember.summary.userId.compareTo(rightRoomMember.summary.userId)
+ }
+ else -> 1
+ }
+ else ->
+ when {
+ rightRoomMember.summary.displayName.isNullOrBlank() -> -1
+ else -> {
+ when (leftRoomMember.summary.displayName) {
+ rightRoomMember.summary.displayName ->
+ // Same display name, compare id
+ leftRoomMember.summary.userId.compareTo(rightRoomMember.summary.userId)
+ else ->
+ leftRoomMember.summary.displayName!!.compareTo(rightRoomMember.summary.displayName!!, true)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
index 88f55aac70..24d2dddc8e 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
@@ -16,11 +16,13 @@ import im.vector.app.core.extensions.join
import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.home.AvatarRenderer
+import im.vector.app.features.roomprofile.permissions.RoleFormatter
import me.gujun.android.span.span
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomThirdPartyInviteContent
+import org.matrix.android.sdk.api.session.room.powerlevels.Role
import org.matrix.android.sdk.api.util.MatrixItem
import org.matrix.android.sdk.api.util.toMatrixItem
import javax.inject.Inject
@@ -29,7 +31,8 @@ class RoomMemberListController @Inject constructor(
private val avatarRenderer: AvatarRenderer,
private val stringProvider: StringProvider,
private val colorProvider: ColorProvider,
- private val roomMemberSummaryFilter: RoomMemberSummaryFilter
+ private val roomMemberSummaryFilter: RoomMemberSummaryFilter,
+ private val roleFormatter: RoleFormatter,
) : TypedEpoxyController() {
interface Callback {
@@ -56,13 +59,13 @@ class RoomMemberListController @Inject constructor(
.orEmpty()
var threePidInvitesDone = filteredThreePidInvites.isEmpty()
- for ((powerLevelCategory, roomMemberList) in roomMembersByPowerLevel) {
- val filteredRoomMemberList = roomMemberList.filter { roomMemberSummaryFilter.test(it) }
+ for ((category, roomMemberList) in roomMembersByPowerLevel) {
+ val filteredRoomMemberList = roomMemberList.filter { roomMemberSummaryFilter.test(it.summary) }
if (filteredRoomMemberList.isEmpty()) {
continue
}
- if (powerLevelCategory == RoomMemberListCategories.USER && !threePidInvitesDone) {
+ if (category == RoomMemberListCategories.USER && !threePidInvitesDone) {
// If there is no regular invite, display threepid invite before the regular user
buildProfileSection(
stringProvider.getString(RoomMemberListCategories.INVITE.titleRes)
@@ -73,20 +76,20 @@ class RoomMemberListController @Inject constructor(
}
buildProfileSection(
- stringProvider.getString(powerLevelCategory.titleRes)
+ stringProvider.getString(category.titleRes)
)
filteredRoomMemberList.join(
each = { _, roomMember ->
- buildRoomMember(roomMember, powerLevelCategory, host, data)
+ buildRoomMember(roomMember, host, data)
},
between = { _, roomMemberBefore ->
dividerItem {
- id("divider_${roomMemberBefore.userId}")
+ id("divider_${roomMemberBefore.summary.userId}")
}
}
)
- if (powerLevelCategory == RoomMemberListCategories.INVITE && !threePidInvitesDone) {
+ if (category == RoomMemberListCategories.INVITE && !threePidInvitesDone) {
// Display the threepid invite after the regular invite
dividerItem {
id("divider_threepidinvites")
@@ -108,24 +111,24 @@ class RoomMemberListController @Inject constructor(
}
private fun buildRoomMember(
- roomMember: RoomMemberSummary,
- powerLevelCategory: RoomMemberListCategories,
+ roomMember: RoomMemberWithPowerLevel,
host: RoomMemberListController,
data: RoomMemberListViewState
) {
- val powerLabel = stringProvider.getString(powerLevelCategory.titleRes)
+ val role = Role.getSuggestedRole(roomMember.powerLevel)
+ val powerLabel = roleFormatter.format(role)
profileMatrixItemWithPowerLevelWithPresence {
- id(roomMember.userId)
- matrixItem(roomMember.toMatrixItem())
+ id(roomMember.summary.userId)
+ matrixItem(roomMember.summary.toMatrixItem())
avatarRenderer(host.avatarRenderer)
- userVerificationLevel(data.trustLevelMap.invoke()?.get(roomMember.userId))
+ userVerificationLevel(data.trustLevelMap.invoke()?.get(roomMember.summary.userId))
clickListener {
- host.callback?.onRoomMemberClicked(roomMember)
+ host.callback?.onRoomMemberClicked(roomMember.summary)
}
showPresence(true)
- userPresence(roomMember.userPresence)
- ignoredUser(roomMember.userId in data.ignoredUserIds)
+ userPresence(roomMember.summary.userPresence)
+ ignoredUser(roomMember.summary.userId in data.ignoredUserIds)
powerLevelLabel(
span {
span(powerLabel) {
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt
index 465da6a9c2..2974e10649 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt
@@ -31,22 +31,19 @@ import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.api.session.crypto.model.UserVerificationLevel
import org.matrix.android.sdk.api.session.events.model.EventType
-import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
-import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.flow.flow
-import org.matrix.android.sdk.flow.mapOptional
import org.matrix.android.sdk.flow.unwrap
import timber.log.Timber
class RoomMemberListViewModel @AssistedInject constructor(
@Assisted initialState: RoomMemberListViewState,
- private val roomMemberSummaryComparator: RoomMemberSummaryComparator,
+ private val roomMemberListComparator: RoomMemberListComparator,
private val session: Session
) :
VectorViewModel(initialState) {
@@ -75,14 +72,12 @@ class RoomMemberListViewModel @AssistedInject constructor(
memberships = Membership.activeMemberships()
}
+ val powerLevelsFlow = PowerLevelsFlowFactory(room).createFlow()
combine(
roomFlow.liveRoomMembers(roomMemberQueryParams),
- roomFlow
- .liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
- .mapOptional { it.content.toModel() }
- .unwrap()
- ) { roomMembers, powerLevelsContent ->
- buildRoomMemberSummaries(powerLevelsContent, roomMembers)
+ powerLevelsFlow,
+ ) { roomMembers, roomPowerLevels ->
+ buildRoomMemberSummaries(roomPowerLevels, roomMembers)
}
.execute { async ->
copy(roomMemberSummaries = async)
@@ -143,10 +138,10 @@ class RoomMemberListViewModel @AssistedInject constructor(
private fun observePowerLevel() {
PowerLevelsFlowFactory(room).createFlow()
- .onEach {
+ .onEach { roomPowerLevels ->
val permissions = ActionPermissions(
- canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId),
- canRevokeThreePidInvite = PowerLevelsHelper(it).isUserAllowedToSend(
+ canInvite = roomPowerLevels.isUserAbleToInvite(session.myUserId),
+ canRevokeThreePidInvite = roomPowerLevels.isUserAllowedToSend(
userId = session.myUserId,
isState = true,
eventType = EventType.STATE_ROOM_THIRD_PARTY_INVITE
@@ -184,31 +179,34 @@ class RoomMemberListViewModel @AssistedInject constructor(
}
}
- private fun buildRoomMemberSummaries(powerLevelsContent: PowerLevelsContent, roomMembers: List): RoomMemberSummaries {
- val admins = ArrayList()
- val moderators = ArrayList()
- val users = ArrayList(roomMembers.size)
- val customs = ArrayList()
- val invites = ArrayList()
- val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent)
+ private fun buildRoomMemberSummaries(roomPowerLevels: RoomPowerLevels, roomMembers: List): RoomMembersByRole {
+ val admins = ArrayList()
+ val moderators = ArrayList()
+ val users = ArrayList(roomMembers.size)
+ val invites = ArrayList()
roomMembers
.forEach { roomMember ->
- val userRole = powerLevelsHelper.getUserRole(roomMember.userId)
+ val powerLevel = roomPowerLevels.getUserPowerLevel(roomMember.userId)
+ val userRole = Role.getSuggestedRole(powerLevel)
+ val roomMemberWithPowerLevel = RoomMemberWithPowerLevel(
+ powerLevel = powerLevel,
+ summary = roomMember,
+ )
when {
- roomMember.membership == Membership.INVITE -> invites.add(roomMember)
- userRole == Role.Admin -> admins.add(roomMember)
- userRole == Role.Moderator -> moderators.add(roomMember)
- userRole == Role.Default -> users.add(roomMember)
- else -> customs.add(roomMember)
+ roomMember.membership == Membership.INVITE -> invites.add(roomMemberWithPowerLevel)
+ userRole == Role.SuperAdmin ||
+ userRole == Role.Creator ||
+ userRole == Role.Admin -> admins.add(roomMemberWithPowerLevel)
+ userRole == Role.Moderator -> moderators.add(roomMemberWithPowerLevel)
+ userRole == Role.User -> users.add(roomMemberWithPowerLevel)
}
}
return listOf(
- RoomMemberListCategories.ADMIN to admins.sortedWith(roomMemberSummaryComparator),
- RoomMemberListCategories.MODERATOR to moderators.sortedWith(roomMemberSummaryComparator),
- RoomMemberListCategories.CUSTOM to customs.sortedWith(roomMemberSummaryComparator),
- RoomMemberListCategories.INVITE to invites.sortedWith(roomMemberSummaryComparator),
- RoomMemberListCategories.USER to users.sortedWith(roomMemberSummaryComparator)
+ RoomMemberListCategories.ADMIN to admins.sortedWith(roomMemberListComparator),
+ RoomMemberListCategories.MODERATOR to moderators.sortedWith(roomMemberListComparator),
+ RoomMemberListCategories.INVITE to invites.sortedWith(roomMemberListComparator),
+ RoomMemberListCategories.USER to users.sortedWith(roomMemberListComparator)
)
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewState.kt
index 90da131cb5..d68a9fceba 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewState.kt
@@ -18,11 +18,12 @@ import org.matrix.android.sdk.api.session.crypto.model.UserVerificationLevel
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
data class RoomMemberListViewState(
val roomId: String,
val roomSummary: Async = Uninitialized,
- val roomMemberSummaries: Async = Uninitialized,
+ val roomMemberSummaries: Async = Uninitialized,
val areAllMembersLoaded: Boolean = false,
val ignoredUserIds: List = emptyList(),
val filter: String = "",
@@ -41,12 +42,16 @@ data class ActionPermissions(
val canRevokeThreePidInvite: Boolean = false
)
-typealias RoomMemberSummaries = List>>
+data class RoomMemberWithPowerLevel(
+ val powerLevel: UserPowerLevel,
+ val summary: RoomMemberSummary,
+)
+
+typealias RoomMembersByRole = List>>
enum class RoomMemberListCategories(@StringRes val titleRes: Int) {
ADMIN(CommonStrings.room_member_power_level_admins),
MODERATOR(CommonStrings.room_member_power_level_moderators),
- CUSTOM(CommonStrings.room_member_power_level_custom),
INVITE(CommonStrings.room_member_power_level_invites),
USER(CommonStrings.room_member_power_level_users)
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberSummaryComparator.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberSummaryComparator.kt
deleted file mode 100644
index fbff99b287..0000000000
--- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberSummaryComparator.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2020-2024 New Vector Ltd.
- *
- * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
- * Please see LICENSE files in the repository root for full details.
- */
-
-package im.vector.app.features.roomprofile.members
-
-import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
-import javax.inject.Inject
-
-class RoomMemberSummaryComparator @Inject constructor() : Comparator {
-
- override fun compare(leftRoomMemberSummary: RoomMemberSummary?, rightRoomMemberSummary: RoomMemberSummary?): Int {
- return when (leftRoomMemberSummary) {
- null ->
- when (rightRoomMemberSummary) {
- null -> 0
- else -> 1
- }
- else ->
- when (rightRoomMemberSummary) {
- null -> -1
- else ->
- when {
- leftRoomMemberSummary.displayName.isNullOrBlank() ->
- when {
- rightRoomMemberSummary.displayName.isNullOrBlank() -> {
- // No display names, compare ids
- leftRoomMemberSummary.userId.compareTo(rightRoomMemberSummary.userId)
- }
- else -> 1
- }
- else ->
- when {
- rightRoomMemberSummary.displayName.isNullOrBlank() -> -1
- else -> {
- when (leftRoomMemberSummary.displayName) {
- rightRoomMemberSummary.displayName ->
- // Same display name, compare id
- leftRoomMemberSummary.userId.compareTo(rightRoomMemberSummary.userId)
- else ->
- leftRoomMemberSummary.displayName!!.compareTo(rightRoomMemberSummary.displayName!!, true)
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoleFormatter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoleFormatter.kt
index 6bc62cb53d..4febb822ad 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoleFormatter.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoleFormatter.kt
@@ -19,8 +19,9 @@ class RoleFormatter @Inject constructor(
return when (role) {
Role.Admin -> stringProvider.getString(CommonStrings.power_level_admin)
Role.Moderator -> stringProvider.getString(CommonStrings.power_level_moderator)
- Role.Default -> stringProvider.getString(CommonStrings.power_level_default)
- is Role.Custom -> stringProvider.getString(CommonStrings.power_level_custom, role.value)
+ Role.User -> stringProvider.getString(CommonStrings.power_level_default)
+ Role.Creator -> stringProvider.getString(CommonStrings.power_level_owner)
+ Role.SuperAdmin -> stringProvider.getString(CommonStrings.power_level_owner)
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsAction.kt
index a8eb77bd03..cb4376c98f 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsAction.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsAction.kt
@@ -8,9 +8,10 @@
package im.vector.app.features.roomprofile.permissions
import im.vector.app.core.platform.VectorViewModelAction
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
sealed class RoomPermissionsAction : VectorViewModelAction {
object ToggleShowAllPermissions : RoomPermissionsAction()
- data class UpdatePermission(val editablePermission: EditablePermission, val powerLevel: Int) : RoomPermissionsAction()
+ data class UpdatePermission(val editablePermission: EditablePermission, val powerLevel: UserPowerLevel.Value) : RoomPermissionsAction()
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt
index 2e5d89e409..e5255eb435 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt
@@ -26,6 +26,7 @@ import org.matrix.android.sdk.api.session.room.model.redactOrDefault
import org.matrix.android.sdk.api.session.room.model.stateDefaultOrDefault
import org.matrix.android.sdk.api.session.room.model.usersDefaultOrDefault
import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
import javax.inject.Inject
class RoomPermissionsController @Inject constructor(
@@ -34,7 +35,7 @@ class RoomPermissionsController @Inject constructor(
) : TypedEpoxyController() {
interface Callback {
- fun onEditPermission(editablePermission: EditablePermission, currentRole: Role)
+ fun onEditPermission(editablePermission: EditablePermission, currentPowerLevel: UserPowerLevel)
fun toggleShowAllPermissions()
}
@@ -165,7 +166,8 @@ class RoomPermissionsController @Inject constructor(
editable: Boolean,
isSpace: Boolean
) {
- val currentRole = getCurrentRole(editablePermission, content)
+ val currentPowerLevel = getPowerLevel(editablePermission, content)
+ val currentRole = Role.getSuggestedRole(currentPowerLevel)
buildProfileAction(
id = editablePermission.labelResId.toString(),
title = stringProvider.getString(
@@ -177,12 +179,12 @@ class RoomPermissionsController @Inject constructor(
action = {
callback
?.takeIf { editable }
- ?.onEditPermission(editablePermission, currentRole)
+ ?.onEditPermission(editablePermission, currentPowerLevel)
}
)
}
- private fun getCurrentRole(editablePermission: EditablePermission, content: PowerLevelsContent): Role {
+ private fun getPowerLevel(editablePermission: EditablePermission, content: PowerLevelsContent): UserPowerLevel.Value {
val value = when (editablePermission) {
is EditablePermission.EventTypeEditablePermission -> content.events?.get(editablePermission.eventType) ?: content.stateDefaultOrDefault()
is EditablePermission.DefaultRole -> content.usersDefaultOrDefault()
@@ -194,20 +196,6 @@ class RoomPermissionsController @Inject constructor(
is EditablePermission.RemoveMessagesSentByOthers -> content.redactOrDefault()
is EditablePermission.NotifyEveryone -> content.notificationLevel(PowerLevelsContent.NOTIFICATIONS_ROOM_KEY)
}
-
- return Role.fromValue(
- value,
- when (editablePermission) {
- is EditablePermission.EventTypeEditablePermission -> content.stateDefaultOrDefault()
- is EditablePermission.DefaultRole -> Role.Default.value
- is EditablePermission.SendMessages -> Role.Default.value
- is EditablePermission.InviteUsers -> Role.Moderator.value
- is EditablePermission.ChangeSettings -> Role.Moderator.value
- is EditablePermission.KickUsers -> Role.Moderator.value
- is EditablePermission.BanUsers -> Role.Moderator.value
- is EditablePermission.RemoveMessagesSentByOthers -> Role.Moderator.value
- is EditablePermission.NotifyEveryone -> Role.Moderator.value
- }
- )
+ return UserPowerLevel.Value(value)
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt
index 5d92a96b5f..ea1afbcfc5 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt
@@ -26,7 +26,7 @@ import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.roommemberprofile.powerlevel.EditPowerLevelDialogs
import im.vector.app.features.roomprofile.RoomProfileArgs
import im.vector.lib.strings.CommonStrings
-import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
import org.matrix.android.sdk.api.util.toMatrixItem
import javax.inject.Inject
@@ -93,8 +93,8 @@ class RoomPermissionsFragment :
}
}
- override fun onEditPermission(editablePermission: EditablePermission, currentRole: Role) {
- EditPowerLevelDialogs.showChoice(requireActivity(), editablePermission.labelResId, currentRole) { newPowerLevel ->
+ override fun onEditPermission(editablePermission: EditablePermission, currentPowerLevel: UserPowerLevel) {
+ EditPowerLevelDialogs.showChoice(requireActivity(), editablePermission.labelResId, currentPowerLevel) { newPowerLevel ->
viewModel.handle(RoomPermissionsAction.UpdatePermission(editablePermission, newPowerLevel))
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt
index 0b942d78cb..3757a1ddd0 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt
@@ -9,6 +9,7 @@ package im.vector.app.features.roomprofile.permissions
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -24,7 +25,6 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.unwrap
@@ -61,19 +61,23 @@ class RoomPermissionsViewModel @AssistedInject constructor(
private fun observePowerLevel() {
PowerLevelsFlowFactory(room)
.createFlow()
- .onEach { powerLevelContent ->
- val powerLevelsHelper = PowerLevelsHelper(powerLevelContent)
+ .onEach { roomPowerLevels ->
val permissions = RoomPermissionsViewState.ActionPermissions(
- canChangePowerLevels = powerLevelsHelper.isUserAllowedToSend(
+ canChangePowerLevels = roomPowerLevels.isUserAllowedToSend(
userId = session.myUserId,
isState = true,
eventType = EventType.STATE_ROOM_POWER_LEVELS
)
)
+ val powerLevelsContent = roomPowerLevels.powerLevelsContent
setState {
copy(
actionPermissions = permissions,
- currentPowerLevelsContent = Success(powerLevelContent)
+ currentPowerLevelsContent = if (powerLevelsContent != null) {
+ Success(powerLevelsContent)
+ } else {
+ Uninitialized
+ }
)
}
}.launchIn(viewModelScope)
@@ -94,26 +98,26 @@ class RoomPermissionsViewModel @AssistedInject constructor(
private fun updatePermission(action: RoomPermissionsAction.UpdatePermission) {
withState { state ->
- val currentPowerLevel = state.currentPowerLevelsContent.invoke() ?: return@withState
+ val currentPowerLevelsContent = state.currentPowerLevelsContent.invoke() ?: return@withState
postLoading(true)
viewModelScope.launch {
try {
val newPowerLevelsContent = when (action.editablePermission) {
- is EditablePermission.EventTypeEditablePermission -> currentPowerLevel.copy(
- events = currentPowerLevel.events.orEmpty().toMutableMap().apply {
- put(action.editablePermission.eventType, action.powerLevel)
+ is EditablePermission.EventTypeEditablePermission -> currentPowerLevelsContent.copy(
+ events = currentPowerLevelsContent.events.orEmpty().toMutableMap().apply {
+ put(action.editablePermission.eventType, action.powerLevel.value)
}
)
- is EditablePermission.DefaultRole -> currentPowerLevel.copy(usersDefault = action.powerLevel)
- is EditablePermission.SendMessages -> currentPowerLevel.copy(eventsDefault = action.powerLevel)
- is EditablePermission.InviteUsers -> currentPowerLevel.copy(invite = action.powerLevel)
- is EditablePermission.ChangeSettings -> currentPowerLevel.copy(stateDefault = action.powerLevel)
- is EditablePermission.KickUsers -> currentPowerLevel.copy(kick = action.powerLevel)
- is EditablePermission.BanUsers -> currentPowerLevel.copy(ban = action.powerLevel)
- is EditablePermission.RemoveMessagesSentByOthers -> currentPowerLevel.copy(redact = action.powerLevel)
- is EditablePermission.NotifyEveryone -> currentPowerLevel.copy(
- notifications = currentPowerLevel.notifications.orEmpty().toMutableMap().apply {
- put(PowerLevelsContent.NOTIFICATIONS_ROOM_KEY, action.powerLevel)
+ is EditablePermission.DefaultRole -> currentPowerLevelsContent.copy(usersDefault = action.powerLevel.value)
+ is EditablePermission.SendMessages -> currentPowerLevelsContent.copy(eventsDefault = action.powerLevel.value)
+ is EditablePermission.InviteUsers -> currentPowerLevelsContent.copy(invite = action.powerLevel.value)
+ is EditablePermission.ChangeSettings -> currentPowerLevelsContent.copy(stateDefault = action.powerLevel.value)
+ is EditablePermission.KickUsers -> currentPowerLevelsContent.copy(kick = action.powerLevel.value)
+ is EditablePermission.BanUsers -> currentPowerLevelsContent.copy(ban = action.powerLevel.value)
+ is EditablePermission.RemoveMessagesSentByOthers -> currentPowerLevelsContent.copy(redact = action.powerLevel.value)
+ is EditablePermission.NotifyEveryone -> currentPowerLevelsContent.copy(
+ notifications = currentPowerLevelsContent.notifications.orEmpty().toMutableMap().apply {
+ put(PowerLevelsContent.NOTIFICATIONS_ROOM_KEY, action.powerLevel.value)
}
)
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
index af043b9ab2..188068afb4 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
@@ -32,7 +32,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent
import org.matrix.android.sdk.api.session.room.model.RoomGuestAccessContent
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.mapOptional
import org.matrix.android.sdk.flow.unwrap
@@ -115,28 +114,26 @@ class RoomSettingsViewModel @AssistedInject constructor(
)
}
- val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow()
-
- powerLevelsContentLive
- .onEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
+ val powerLevelsFlow = PowerLevelsFlowFactory(room).createFlow()
+ powerLevelsFlow
+ .onEach { roomPowerLevels ->
val permissions = RoomSettingsViewState.ActionPermissions(
- canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR),
- canChangeName = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME),
- canChangeTopic = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC),
- canChangeHistoryVisibility = powerLevelsHelper.isUserAllowedToSend(
+ canChangeAvatar = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR),
+ canChangeName = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME),
+ canChangeTopic = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC),
+ canChangeHistoryVisibility = roomPowerLevels.isUserAllowedToSend(
session.myUserId, true,
EventType.STATE_ROOM_HISTORY_VISIBILITY
),
- canChangeJoinRule = powerLevelsHelper.isUserAllowedToSend(
+ canChangeJoinRule = roomPowerLevels.isUserAllowedToSend(
session.myUserId, true,
EventType.STATE_ROOM_JOIN_RULES
) &&
- powerLevelsHelper.isUserAllowedToSend(
+ roomPowerLevels.isUserAllowedToSend(
session.myUserId, true,
EventType.STATE_ROOM_GUEST_ACCESS
),
- canAddChildren = powerLevelsHelper.isUserAllowedToSend(
+ canAddChildren = roomPowerLevels.isUserAllowedToSend(
session.myUserId, true,
EventType.STATE_SPACE_CHILD
)
diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt
index 404cfac9de..cebfb63f1f 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt
@@ -32,7 +32,6 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.getRoomSummary
import org.matrix.android.sdk.api.session.room.model.Membership
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.powerlevels.Role
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
import org.matrix.android.sdk.flow.flow
@@ -74,20 +73,19 @@ class SpaceMenuViewModel @AssistedInject constructor(
PowerLevelsFlowFactory(room)
.createFlow()
- .onEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
+ .onEach { roomPowerLevels ->
- val canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId)
- val canAddChild = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_SPACE_CHILD)
+ val canInvite = roomPowerLevels.isUserAbleToInvite(session.myUserId)
+ val canAddChild = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_SPACE_CHILD)
- val canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR)
- val canChangeName = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME)
- val canChangeTopic = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC)
+ val canChangeAvatar = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR)
+ val canChangeName = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME)
+ val canChangeTopic = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC)
- val isAdmin = powerLevelsHelper.getUserRole(session.myUserId) is Role.Admin
+ val isAdmin = roomPowerLevels.getUserRole(session.myUserId) == Role.Admin
val otherAdminCount = roomSummary?.otherMemberIds
- ?.map { powerLevelsHelper.getUserRole(it) }
- ?.count { it is Role.Admin }
+ ?.map { roomPowerLevels.getUserRole(it) }
+ ?.count { it == Role.Admin }
?: 0
val isLastAdmin = isAdmin && otherAdminCount == 0
diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModelTask.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModelTask.kt
index bf91be4fa0..ca65b99fd4 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModelTask.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModelTask.kt
@@ -27,6 +27,7 @@ import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
import org.matrix.android.sdk.api.session.room.model.create.RestrictedRoomPreset
import org.matrix.android.sdk.api.session.room.powerlevels.Role
+import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel
import org.matrix.android.sdk.api.session.space.CreateSpaceParams
import timber.log.Timber
import javax.inject.Inject
@@ -65,7 +66,7 @@ class CreateSpaceViewModelTask @Inject constructor(
if (params.isPublic) {
this.roomAliasName = params.spaceAlias
this.powerLevelContentOverride = (powerLevelContentOverride ?: PowerLevelsContent()).copy(
- invite = Role.Default.value
+ invite = UserPowerLevel.User.value
)
this.preset = CreateRoomPreset.PRESET_PUBLIC_CHAT
this.historyVisibility = RoomHistoryVisibility.WORLD_READABLE
@@ -79,7 +80,7 @@ class CreateSpaceViewModelTask @Inject constructor(
}
)
this.powerLevelContentOverride = (powerLevelContentOverride ?: PowerLevelsContent()).copy(
- invite = Role.Moderator.value
+ invite = UserPowerLevel.Moderator.value
)
}
})
diff --git a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt
index ae112908fc..3627dd5469 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt
@@ -36,7 +36,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.RoomType
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
import org.matrix.android.sdk.flow.flow
import timber.log.Timber
@@ -96,16 +95,14 @@ class SpaceDirectoryViewModel @AssistedInject constructor(
private fun observePermissions() {
val room = session.getRoom(initialState.spaceId) ?: return
- val powerLevelsContentLive = PowerLevelsFlowFactory(room).createFlow()
+ val powerLevelsFlow = PowerLevelsFlowFactory(room).createFlow()
- powerLevelsContentLive
- .onEach {
- val powerLevelsHelper = PowerLevelsHelper(it)
+ powerLevelsFlow
+ .onEach { roomPowerLevels ->
setState {
copy(
- canAddRooms = powerLevelsHelper.isUserAllowedToSend(
- session.myUserId, true,
- EventType.STATE_SPACE_CHILD
+ canAddRooms = roomPowerLevels.isUserAllowedToSend(
+ userId = session.myUserId, isState = true, eventType = EventType.STATE_SPACE_CHILD
)
)
}
diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt
index de68b697ef..b8a3bbd07d 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt
@@ -31,10 +31,11 @@ import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom
+import org.matrix.android.sdk.api.session.room.getRoomPowerLevels
import org.matrix.android.sdk.api.session.room.getStateEvent
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.room.powerlevels.Role
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
import org.matrix.android.sdk.flow.flow
@@ -50,14 +51,12 @@ class SpaceLeaveAdvancedViewModel @AssistedInject constructor(
init {
val space = session.getRoom(initialState.spaceId)
val spaceSummary = space?.roomSummary()
-
- val powerLevelsEvent = space?.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
- powerLevelsEvent?.content?.toModel()?.let { powerLevelsContent ->
- val powerLevelsHelper = PowerLevelsHelper(powerLevelsContent)
- val isAdmin = powerLevelsHelper.getUserRole(session.myUserId) is Role.Admin
+ val roomPowerLevels = space?.getRoomPowerLevels()
+ roomPowerLevels?.let {
+ val isAdmin = roomPowerLevels.getUserRole(session.myUserId) == Role.Admin
val otherAdminCount = spaceSummary?.otherMemberIds
- ?.map { powerLevelsHelper.getUserRole(it) }
- ?.count { it is Role.Admin }
+ ?.map { roomPowerLevels.getUserRole(it) }
+ ?.count { it == Role.Admin }
?: 0
val isLastAdmin = isAdmin && otherAdminCount == 0
setState {
diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleListController.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleListController.kt
index 1011952528..f8b5fada1a 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleListController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleListController.kt
@@ -54,7 +54,7 @@ class SpacePeopleListController @Inject constructor(
memberSummaries.forEach { memberEntry ->
val filtered = memberEntry.second
- .filter { roomMemberSummaryFilter.test(it) }
+ .filter { roomMemberSummaryFilter.test(it.summary) }
if (filtered.isNotEmpty()) {
dividerItem {
id("divider_type_${memberEntry.first.titleRes}")
@@ -65,10 +65,10 @@ class SpacePeopleListController @Inject constructor(
.join(
each = { _, roomMember ->
profileMatrixItemWithPowerLevel {
- id(roomMember.userId)
- matrixItem(roomMember.toMatrixItem())
+ id(roomMember.summary.userId)
+ matrixItem(roomMember.summary.toMatrixItem())
avatarRenderer(host.avatarRenderer)
- userVerificationLevel(data.trustLevelMap.invoke()?.get(roomMember.userId))
+ userVerificationLevel(data.trustLevelMap.invoke()?.get(roomMember.summary.userId))
.apply {
val pl = host.toPowerLevelLabel(memberEntry.first)
if (memberEntry.first == RoomMemberListCategories.INVITE) {
@@ -106,13 +106,13 @@ class SpacePeopleListController @Inject constructor(
}
clickListener {
- host.listener?.onSpaceMemberClicked(roomMember)
+ host.listener?.onSpaceMemberClicked(roomMember.summary)
}
}
},
between = { _, roomMemberBefore ->
dividerItem {
- id("divider_${roomMemberBefore.userId}")
+ id("divider_${roomMemberBefore.summary.userId}")
}
}
)
diff --git a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt
index 09b23bbed8..f5b6a0a06c 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt
@@ -23,7 +23,7 @@ import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.getRoomSummary
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
class ShareSpaceViewModel @AssistedInject constructor(
@Assisted private val initialState: ShareSpaceViewState,
@@ -52,11 +52,10 @@ class ShareSpaceViewModel @AssistedInject constructor(
val room = session.getRoom(initialState.spaceId) ?: return
PowerLevelsFlowFactory(room)
.createFlow()
- .onEach { powerLevelContent ->
- val powerLevelsHelper = PowerLevelsHelper(powerLevelContent)
+ .onEach { roomPowerLevels ->
setState {
copy(
- canInviteByMxId = powerLevelsHelper.isUserAbleToInvite(session.myUserId)
+ canInviteByMxId = roomPowerLevels.isUserAbleToInvite(session.myUserId)
)
}
}
diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt
index 233cb82d5d..973ea11f47 100644
--- a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt
@@ -33,10 +33,11 @@ import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.Room
+import org.matrix.android.sdk.api.session.room.getRoomPowerLevels
import org.matrix.android.sdk.api.session.room.getStateEvent
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.unwrap
import timber.log.Timber
@@ -139,12 +140,8 @@ class StartVoiceBroadcastUseCase @Inject constructor(
@VisibleForTesting
fun assertHasEnoughPowerLevels(room: Room) {
- val powerLevelsHelper = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
- ?.content
- ?.toModel()
- ?.let { PowerLevelsHelper(it) }
-
- if (powerLevelsHelper?.isUserAllowedToSend(session.myUserId, true, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO) != true) {
+ val roomPowerLevels = room.getRoomPowerLevels()
+ if (!roomPowerLevels.isUserAllowedToSend(session.myUserId, true, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO)) {
Timber.d("## StartVoiceBroadcastUseCase: Cannot start voice broadcast: no permission")
throw VoiceBroadcastFailure.RecordingError.NoPermission
}
diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt
index 61f79662b0..326567fb07 100644
--- a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt
+++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt
@@ -25,10 +25,11 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom
+import org.matrix.android.sdk.api.session.room.getRoomPowerLevels
import org.matrix.android.sdk.api.session.room.getStateEvent
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.widgets.WidgetPostAPIMediator
import org.matrix.android.sdk.api.util.JsonDict
import timber.log.Timber
@@ -146,13 +147,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(
Timber.d("## canSendEvent() : eventType $eventType isState $isState")
- val powerLevelsEvent = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
- val powerLevelsContent = powerLevelsEvent?.content?.toModel()
- val canSend = if (powerLevelsContent == null) {
- false
- } else {
- PowerLevelsHelper(powerLevelsContent).isUserAllowedToSend(session.myUserId, isState, eventType)
- }
+ val roomPowerLevels = room.getRoomPowerLevels()
+ val canSend = roomPowerLevels.isUserAllowedToSend(session.myUserId, isState, eventType)
if (canSend) {
Timber.d("## canSendEvent() returns true")
widgetPostAPIMediator.sendBoolResponse(true, eventData)
diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt
index 6580b52fca..1778423db7 100644
--- a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt
@@ -19,9 +19,11 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
+import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import im.vector.app.features.widgets.permissions.WidgetPermissionsHelper
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.Session
@@ -31,7 +33,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
-import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
+import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels
import org.matrix.android.sdk.api.session.widgets.WidgetManagementFailure
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.mapOptional
@@ -102,11 +104,10 @@ class WidgetViewModel @AssistedInject constructor(
if (room == null) {
return
}
- room.flow().liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
- .mapOptional { it.content.toModel() }
- .unwrap()
- .map {
- PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, true, null)
+ PowerLevelsFlowFactory(room)
+ .createFlow()
+ .map { roomPowerLevels ->
+ roomPowerLevels.isUserAllowedToSend(session.myUserId, true, null)
}
.setOnEach {
copy(canManageWidgets = it)
diff --git a/vector/src/test/java/im/vector/app/features/MemberListViewModelTest.kt b/vector/src/test/java/im/vector/app/features/MemberListViewModelTest.kt
index 18ea98db3e..0f540bd2cd 100644
--- a/vector/src/test/java/im/vector/app/features/MemberListViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/MemberListViewModelTest.kt
@@ -13,7 +13,7 @@ import com.airbnb.mvrx.test.MavericksTestRule
import im.vector.app.features.roomprofile.RoomProfileArgs
import im.vector.app.features.roomprofile.members.RoomMemberListViewModel
import im.vector.app.features.roomprofile.members.RoomMemberListViewState
-import im.vector.app.features.roomprofile.members.RoomMemberSummaryComparator
+import im.vector.app.features.roomprofile.members.RoomMemberListComparator
import im.vector.app.test.test
import im.vector.app.test.testCoroutineDispatchers
import io.mockk.coEvery
@@ -266,7 +266,7 @@ class MemberListViewModelTest {
private fun createViewModel(): RoomMemberListViewModel {
return RoomMemberListViewModel(
RoomMemberListViewState(args),
- RoomMemberSummaryComparator(),
+ RoomMemberListComparator(),
fakeSession,
)
}