fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.6.25 (#4936)

Fix broken API changes:
- `RoomInfo.isPublic` is now optional, so we need to assume its default value in some places of the app.
- `RoomInfo.userPowerLevels` is now `RoomInfo.roomPowerLevels` and also contains this info.
- `ClientBuilder` now uses a `DecryptionSettings` value.
- The call widget settings provider now internally uses a different Rust type.
- `Client.clearCache` now takes a `syncService` so it can stop it.

---

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
This commit is contained in:
renovate[bot] 2025-06-25 19:25:42 +00:00 committed by GitHub
parent ac49975419
commit a10db58872
28 changed files with 148 additions and 60 deletions

View file

@ -78,7 +78,8 @@ private suspend fun showLeaveRoomAlert(
val roomInfo = room.roomInfoFlow.first() val roomInfo = room.roomInfoFlow.first()
confirmation.value = when { confirmation.value = when {
roomInfo.isDm -> Dm(roomId) roomInfo.isDm -> Dm(roomId)
!roomInfo.isPublic -> PrivateRoom(roomId) // If unknown, assume the room is private
roomInfo.isPublic == null || roomInfo.isPublic == false -> PrivateRoom(roomId)
roomInfo.joinedMembersCount == 1L -> LastUserInRoom(roomId) roomInfo.joinedMembersCount == 1L -> LastUserInRoom(roomId)
else -> Generic(roomId) else -> Generic(roomId)
} }

View file

@ -59,7 +59,7 @@ class RolesAndPermissionsNode @AssistedInject constructor(
lifecycleScope.launch { lifecycleScope.launch {
room.roomInfoFlow room.roomInfoFlow
.filter { info -> .filter { info ->
info.userPowerLevels[room.sessionId] != RoomMember.Role.ADMIN.powerLevel info.roomPowerLevels?.users?.get(room.sessionId) != RoomMember.Role.ADMIN.powerLevel
} }
.take(1) .take(1)
.onEach { navigateUp() } .onEach { navigateUp() }

View file

@ -110,8 +110,8 @@ class RolesAndPermissionsPresenter @Inject constructor(
} }
private fun RoomInfo.userCountWithRole(userIds: List<UserId>, role: RoomMember.Role): Int { private fun RoomInfo.userCountWithRole(userIds: List<UserId>, role: RoomMember.Role): Int {
return this.userPowerLevels.count { (userId, level) -> return this.roomPowerLevels?.users?.count { (userId, level) ->
RoomMember.Role.forPowerLevel(level) == role && userId in userIds RoomMember.Role.forPowerLevel(level) == role && userId in userIds
} } ?: 0
} }
} }

View file

@ -109,7 +109,7 @@ class ChangeRolesPresenter @AssistedInject constructor(
val roomInfo by room.roomInfoFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState()
fun canChangeMemberRole(userId: UserId): Boolean { fun canChangeMemberRole(userId: UserId): Boolean {
// An admin can't remove or demote another admin // An admin can't remove or demote another admin
val powerLevel = roomInfo.userPowerLevels[userId] ?: 0L val powerLevel = roomInfo.roomPowerLevels?.users?.get(userId) ?: 0L
return RoomMember.Role.forPowerLevel(powerLevel) != RoomMember.Role.ADMIN return RoomMember.Role.forPowerLevel(powerLevel) != RoomMember.Role.ADMIN
} }

View file

@ -16,14 +16,17 @@ import io.element.android.features.roomdetails.impl.members.aRoomMemberList
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues
import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.testCoroutineDispatchers import io.element.android.tests.testutils.testCoroutineDispatchers
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
@ -142,7 +145,7 @@ class ChangeRolesPresenterTest {
fun `present - UserSelectionToggle adds and removes users from the selected user list`() = runTest { fun `present - UserSelectionToggle adds and removes users from the selected user list`() = runTest {
val room = FakeJoinedRoom().apply { val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.ADMIN)))
} }
val presenter = createChangeRolesPresenter(room = room) val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -164,7 +167,7 @@ class ChangeRolesPresenterTest {
fun `present - hasPendingChanges is true when the initial selected users don't match the new ones`() = runTest { fun `present - hasPendingChanges is true when the initial selected users don't match the new ones`() = runTest {
val room = FakeJoinedRoom().apply { val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.ADMIN)))
} }
val presenter = createChangeRolesPresenter(room = room) val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -193,7 +196,7 @@ class ChangeRolesPresenterTest {
fun `present - Exit will display success if no pending changes`() = runTest { fun `present - Exit will display success if no pending changes`() = runTest {
val room = FakeJoinedRoom().apply { val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.ADMIN)))
} }
val presenter = createChangeRolesPresenter(room = room) val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -213,7 +216,7 @@ class ChangeRolesPresenterTest {
fun `present - CancelExit will remove exit confirmation`() = runTest { fun `present - CancelExit will remove exit confirmation`() = runTest {
val room = FakeJoinedRoom().apply { val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.ADMIN)))
} }
val presenter = createChangeRolesPresenter(room = room) val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -239,7 +242,7 @@ class ChangeRolesPresenterTest {
fun `present - Exit will display a confirmation dialog if there are pending changes, calling it again will actually exit`() = runTest { fun `present - Exit will display a confirmation dialog if there are pending changes, calling it again will actually exit`() = runTest {
val room = FakeJoinedRoom().apply { val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.ADMIN)))
} }
val presenter = createChangeRolesPresenter(room = room) val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -270,7 +273,7 @@ class ChangeRolesPresenterTest {
baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }), baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }),
).apply { ).apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.ADMIN)))
} }
val presenter = createChangeRolesPresenter(role = RoomMember.Role.ADMIN, room = room) val presenter = createChangeRolesPresenter(role = RoomMember.Role.ADMIN, room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -299,7 +302,7 @@ class ChangeRolesPresenterTest {
fun `present - CancelSave will remove the confirmation dialog`() = runTest { fun `present - CancelSave will remove the confirmation dialog`() = runTest {
val room = FakeJoinedRoom().apply { val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.ADMIN)))
} }
val presenter = createChangeRolesPresenter(role = RoomMember.Role.ADMIN, room = room) val presenter = createChangeRolesPresenter(role = RoomMember.Role.ADMIN, room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -328,7 +331,7 @@ class ChangeRolesPresenterTest {
baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }), baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }),
).apply { ).apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 50))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.MODERATOR)))
} }
val presenter = createChangeRolesPresenter( val presenter = createChangeRolesPresenter(
role = RoomMember.Role.MODERATOR, role = RoomMember.Role.MODERATOR,
@ -361,7 +364,7 @@ class ChangeRolesPresenterTest {
updateUserRoleResult = { Result.failure(IllegalStateException("Failed")) } updateUserRoleResult = { Result.failure(IllegalStateException("Failed")) }
).apply { ).apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 50))) givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.MODERATOR)))
} }
val presenter = createChangeRolesPresenter(role = RoomMember.Role.MODERATOR, room = room) val presenter = createChangeRolesPresenter(role = RoomMember.Role.MODERATOR, room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -385,6 +388,16 @@ class ChangeRolesPresenterTest {
} }
} }
private fun roomPowerLevelsWithRole(
role: RoomMember.Role,
userId: UserId = A_USER_ID,
): RoomPowerLevels {
return RoomPowerLevels(
values = defaultRoomPowerLevelValues(),
users = persistentMapOf(userId to role.powerLevel)
)
}
private fun TestScope.createChangeRolesPresenter( private fun TestScope.createChangeRolesPresenter(
role: RoomMember.Role = RoomMember.Role.ADMIN, role: RoomMember.Role = RoomMember.Role.ADMIN,
room: FakeJoinedRoom = FakeJoinedRoom(), room: FakeJoinedRoom = FakeJoinedRoom(),

View file

@ -21,7 +21,7 @@ import io.element.android.libraries.matrix.api.room.RoomMember.Role.USER
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevels import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues
import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Test import org.junit.Test
@ -296,7 +296,7 @@ class ChangeBaseRoomPermissionsPresenterTest {
analyticsService = analyticsService, analyticsService = analyticsService,
) )
private fun defaultPermissions() = defaultRoomPowerLevels() private fun defaultPermissions() = defaultRoomPowerLevelValues()
private suspend fun TurbineTestContext<ChangeRoomPermissionsState>.awaitUpdatedItem(): ChangeRoomPermissionsState { private suspend fun TurbineTestContext<ChangeRoomPermissionsState>.awaitUpdatedItem(): ChangeRoomPermissionsState {
skipItems(1) skipItems(1)

View file

@ -172,7 +172,7 @@ jsoup = "org.jsoup:jsoup:1.21.1"
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
molecule-runtime = "app.cash.molecule:molecule-runtime:2.1.0" molecule-runtime = "app.cash.molecule:molecule-runtime:2.1.0"
timber = "com.jakewharton.timber:timber:5.0.1" timber = "com.jakewharton.timber:timber:5.0.1"
matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.6.23" matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.6.25"
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }

View file

@ -27,5 +27,5 @@ fun BaseRoom.toAnalyticsViewRoom(
} }
private fun BaseRoom.toActiveSpace(): ViewRoom.ActiveSpace { private fun BaseRoom.toActiveSpace(): ViewRoom.ActiveSpace {
return if (info().isPublic) ViewRoom.ActiveSpace.Public else ViewRoom.ActiveSpace.Private return if (info().isPublic == true) ViewRoom.ActiveSpace.Public else ViewRoom.ActiveSpace.Private
} }

View file

@ -14,10 +14,10 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableMap
@Immutable @Immutable
data class RoomInfo( data class RoomInfo(
@ -28,7 +28,7 @@ data class RoomInfo(
val rawName: String?, val rawName: String?,
val topic: String?, val topic: String?,
val avatarUrl: String?, val avatarUrl: String?,
val isPublic: Boolean, val isPublic: Boolean?,
val isDirect: Boolean, val isDirect: Boolean,
val isEncrypted: Boolean?, val isEncrypted: Boolean?,
val joinRule: JoinRule?, val joinRule: JoinRule?,
@ -48,7 +48,7 @@ data class RoomInfo(
val activeMembersCount: Long, val activeMembersCount: Long,
val invitedMembersCount: Long, val invitedMembersCount: Long,
val joinedMembersCount: Long, val joinedMembersCount: Long,
val userPowerLevels: ImmutableMap<UserId, Long>, val roomPowerLevels: RoomPowerLevels?,
val highlightCount: Long, val highlightCount: Long,
val notificationCount: Long, val notificationCount: Long,
val userDefinedNotificationMode: RoomNotificationMode?, val userDefinedNotificationMode: RoomNotificationMode?,

View file

@ -22,7 +22,7 @@ import kotlinx.coroutines.flow.map
*/ */
fun BaseRoom.usersWithRole(role: RoomMember.Role): Flow<ImmutableList<RoomMember>> { fun BaseRoom.usersWithRole(role: RoomMember.Role): Flow<ImmutableList<RoomMember>> {
return roomInfoFlow return roomInfoFlow
.map { it.userPowerLevels.filter { (_, powerLevel) -> RoomMember.Role.forPowerLevel(powerLevel) == role } } .map { it.roomPowerLevels?.users.orEmpty().filter { (_, powerLevel) -> RoomMember.Role.forPowerLevel(powerLevel) == role } }
.combine(membersStateFlow) { powerLevels, membersState -> .combine(membersStateFlow) { powerLevels, membersState ->
membersState.activeRoomMembers() membersState.activeRoomMembers()
.filter { powerLevels.containsKey(it.userId) } .filter { powerLevels.containsKey(it.userId) }

View file

@ -0,0 +1,16 @@
/*
* 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 io.element.android.libraries.matrix.api.room.powerlevels
import io.element.android.libraries.matrix.api.core.UserId
import kotlinx.collections.immutable.ImmutableMap
data class RoomPowerLevels(
val values: RoomPowerLevelsValues,
val users: ImmutableMap<UserId, Long>,
)

View file

@ -33,5 +33,5 @@ data class RoomPreviewInfo(
/** the membership of the current user. */ /** the membership of the current user. */
val membership: CurrentUserMembership?, val membership: CurrentUserMembership?,
/** The room's join rule. */ /** The room's join rule. */
val joinRule: JoinRule, val joinRule: JoinRule?,
) )

View file

@ -129,7 +129,7 @@ class RustMatrixClient(
private val sessionStore: SessionStore, private val sessionStore: SessionStore,
private val appCoroutineScope: CoroutineScope, private val appCoroutineScope: CoroutineScope,
private val sessionDelegate: RustClientSessionDelegate, private val sessionDelegate: RustClientSessionDelegate,
innerSyncService: ClientSyncService, private val innerSyncService: ClientSyncService,
dispatchers: CoroutineDispatchers, dispatchers: CoroutineDispatchers,
baseCacheDirectory: File, baseCacheDirectory: File,
clock: SystemClock, clock: SystemClock,
@ -531,7 +531,7 @@ class RustMatrixClient(
} }
override suspend fun clearCache() { override suspend fun clearCache() {
innerClient.clearCaches() innerClient.clearCaches(innerSyncService)
destroy() destroy()
} }

View file

@ -34,6 +34,7 @@ import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder
import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.use
import timber.log.Timber import timber.log.Timber
import uniffi.matrix_sdk_crypto.CollectStrategy import uniffi.matrix_sdk_crypto.CollectStrategy
import uniffi.matrix_sdk_crypto.DecryptionSettings
import uniffi.matrix_sdk_crypto.TrustRequirement import uniffi.matrix_sdk_crypto.TrustRequirement
import java.io.File import java.io.File
import javax.inject.Inject import javax.inject.Inject
@ -120,12 +121,14 @@ class RustMatrixClientFactory @Inject constructor(
CollectStrategy.ERROR_ON_VERIFIED_USER_PROBLEM CollectStrategy.ERROR_ON_VERIFIED_USER_PROBLEM
} }
) )
.roomDecryptionTrustRequirement( .decryptionSettings(
trustRequirement = if (featureFlagService.isFeatureEnabled(FeatureFlags.OnlySignedDeviceIsolationMode)) { DecryptionSettings(
TrustRequirement.CROSS_SIGNED_OR_LEGACY senderDeviceTrustRequirement = if (featureFlagService.isFeatureEnabled(FeatureFlags.OnlySignedDeviceIsolationMode)) {
} else { TrustRequirement.CROSS_SIGNED_OR_LEGACY
TrustRequirement.UNTRUSTED } else {
} TrustRequirement.UNTRUSTED
}
)
) )
.enableShareHistoryOnInvite(featureFlagService.isFeatureEnabled(FeatureFlags.EnableKeyShareOnInvite)) .enableShareHistoryOnInvite(featureFlagService.isFeatureEnabled(FeatureFlags.EnableKeyShareOnInvite))
.run { .run {

View file

@ -139,7 +139,7 @@ class JoinedRustRoom(
} }
init { init {
val powerLevelChanges = roomInfoFlow.map { it.userPowerLevels }.distinctUntilChanged() val powerLevelChanges = roomInfoFlow.map { it.roomPowerLevels }.distinctUntilChanged()
val membershipChanges = liveTimeline.membershipChangeEventReceived.onStart { emit(Unit) } val membershipChanges = liveTimeline.membershipChangeEventReceived.onStart { emit(Unit) }
combine(membershipChanges, powerLevelChanges) { _, _ -> } combine(membershipChanges, powerLevelChanges) { _, _ -> }
// Skip initial one // Skip initial one

View file

@ -14,12 +14,13 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.impl.room.history.map import io.element.android.libraries.matrix.impl.room.history.map
import io.element.android.libraries.matrix.impl.room.join.map import io.element.android.libraries.matrix.impl.room.join.map
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsValuesMapper
import io.element.android.libraries.matrix.impl.room.tombstone.map import io.element.android.libraries.matrix.impl.room.tombstone.map
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentMap import kotlinx.collections.immutable.toPersistentMap
import org.matrix.rustcomponents.sdk.Membership import org.matrix.rustcomponents.sdk.Membership
@ -28,6 +29,7 @@ import uniffi.matrix_sdk_base.EncryptionState
import org.matrix.rustcomponents.sdk.Membership as RustMembership import org.matrix.rustcomponents.sdk.Membership as RustMembership
import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo
import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode
import org.matrix.rustcomponents.sdk.RoomPowerLevels as RustRoomPowerLevels
class RoomInfoMapper { class RoomInfoMapper {
fun map(rustRoomInfo: RustRoomInfo): RoomInfo = rustRoomInfo.let { fun map(rustRoomInfo: RustRoomInfo): RoomInfo = rustRoomInfo.let {
@ -55,7 +57,7 @@ class RoomInfoMapper {
activeMembersCount = it.activeMembersCount.toLong(), activeMembersCount = it.activeMembersCount.toLong(),
invitedMembersCount = it.invitedMembersCount.toLong(), invitedMembersCount = it.invitedMembersCount.toLong(),
joinedMembersCount = it.joinedMembersCount.toLong(), joinedMembersCount = it.joinedMembersCount.toLong(),
userPowerLevels = mapPowerLevels(it.userPowerLevels), roomPowerLevels = it.powerLevels?.let(::mapPowerLevels),
highlightCount = it.highlightCount.toLong(), highlightCount = it.highlightCount.toLong(),
notificationCount = it.notificationCount.toLong(), notificationCount = it.notificationCount.toLong(),
userDefinedNotificationMode = it.cachedUserDefinedNotificationMode?.map(), userDefinedNotificationMode = it.cachedUserDefinedNotificationMode?.map(),
@ -96,6 +98,9 @@ fun RoomHero.map(): MatrixUser = MatrixUser(
avatarUrl = avatarUrl avatarUrl = avatarUrl
) )
fun mapPowerLevels(powerLevels: Map<String, Long>): ImmutableMap<UserId, Long> { fun mapPowerLevels(roomPowerLevels: RustRoomPowerLevels): RoomPowerLevels {
return powerLevels.mapKeys { (key, _) -> UserId(key) }.toPersistentMap() return RoomPowerLevels(
values = RoomPowerLevelsValuesMapper.map(roomPowerLevels.values()),
users = roomPowerLevels.userPowerLevels().mapKeys { (key, _) -> UserId(key) }.toPersistentMap()
)
} }

View file

@ -27,7 +27,7 @@ object RoomPreviewInfoMapper {
roomType = info.roomType.map(), roomType = info.roomType.map(),
isHistoryWorldReadable = info.isHistoryWorldReadable.orFalse(), isHistoryWorldReadable = info.isHistoryWorldReadable.orFalse(),
membership = info.membership?.map(), membership = info.membership?.map(),
joinRule = info.joinRule.map(), joinRule = info.joinRule?.map(),
) )
} }
} }

View file

@ -16,11 +16,11 @@ import io.element.android.libraries.matrix.api.widget.CallWidgetSettingsProvider
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import org.matrix.rustcomponents.sdk.EncryptionSystem
import org.matrix.rustcomponents.sdk.VirtualElementCallWidgetOptions
import org.matrix.rustcomponents.sdk.newVirtualElementCallWidget import org.matrix.rustcomponents.sdk.newVirtualElementCallWidget
import uniffi.matrix_sdk.EncryptionSystem
import uniffi.matrix_sdk.VirtualElementCallWidgetOptions
import javax.inject.Inject import javax.inject.Inject
import org.matrix.rustcomponents.sdk.Intent as CallIntent import uniffi.matrix_sdk.Intent as CallIntent
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultCallWidgetSettingsProvider @Inject constructor( class DefaultCallWidgetSettingsProvider @Inject constructor(
@ -50,6 +50,7 @@ class DefaultCallWidgetSettingsProvider @Inject constructor(
parentUrl = null, parentUrl = null,
hideHeader = true, hideHeader = true,
controlledMediaDevices = true, controlledMediaDevices = true,
header = null,
) )
val rustWidgetSettings = newVirtualElementCallWidget(options) val rustWidgetSettings = newVirtualElementCallWidget(options)
return MatrixWidgetSettings.fromRustWidgetSettings(rustWidgetSettings) return MatrixWidgetSettings.fromRustWidgetSettings(rustWidgetSettings)

View file

@ -52,7 +52,6 @@ fun aRustNotificationRoomInfo(
isEncrypted: Boolean? = true, isEncrypted: Boolean? = true,
isDirect: Boolean = false, isDirect: Boolean = false,
joinRule: JoinRule? = null, joinRule: JoinRule? = null,
isPublic: Boolean = true,
) = NotificationRoomInfo( ) = NotificationRoomInfo(
displayName = displayName, displayName = displayName,
avatarUrl = avatarUrl, avatarUrl = avatarUrl,
@ -61,7 +60,6 @@ fun aRustNotificationRoomInfo(
isEncrypted = isEncrypted, isEncrypted = isEncrypted,
isDirect = isDirect, isDirect = isDirect,
joinRule = joinRule, joinRule = joinRule,
isPublic = isPublic,
) )
fun aRustNotificationEventTimeline( fun aRustNotificationEventTimeline(

View file

@ -8,6 +8,7 @@
package io.element.android.libraries.matrix.impl.fixtures.factories package io.element.android.libraries.matrix.impl.fixtures.factories
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiRoomPowerLevels
import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_ROOM_NAME
import org.matrix.rustcomponents.sdk.JoinRule import org.matrix.rustcomponents.sdk.JoinRule
@ -17,6 +18,7 @@ import org.matrix.rustcomponents.sdk.RoomHistoryVisibility
import org.matrix.rustcomponents.sdk.RoomInfo import org.matrix.rustcomponents.sdk.RoomInfo
import org.matrix.rustcomponents.sdk.RoomMember import org.matrix.rustcomponents.sdk.RoomMember
import org.matrix.rustcomponents.sdk.RoomNotificationMode import org.matrix.rustcomponents.sdk.RoomNotificationMode
import org.matrix.rustcomponents.sdk.RoomPowerLevels
import org.matrix.rustcomponents.sdk.SuccessorRoom import org.matrix.rustcomponents.sdk.SuccessorRoom
import uniffi.matrix_sdk_base.EncryptionState import uniffi.matrix_sdk_base.EncryptionState
@ -39,7 +41,7 @@ fun aRustRoomInfo(
activeMembersCount: ULong = 0uL, activeMembersCount: ULong = 0uL,
invitedMembersCount: ULong = 0uL, invitedMembersCount: ULong = 0uL,
joinedMembersCount: ULong = 0uL, joinedMembersCount: ULong = 0uL,
userPowerLevels: Map<String, Long> = mapOf(), roomPowerLevels: RoomPowerLevels = FakeFfiRoomPowerLevels(),
highlightCount: ULong = 0uL, highlightCount: ULong = 0uL,
notificationCount: ULong = 0uL, notificationCount: ULong = 0uL,
userDefinedNotificationMode: RoomNotificationMode? = null, userDefinedNotificationMode: RoomNotificationMode? = null,
@ -73,7 +75,7 @@ fun aRustRoomInfo(
activeMembersCount = activeMembersCount, activeMembersCount = activeMembersCount,
invitedMembersCount = invitedMembersCount, invitedMembersCount = invitedMembersCount,
joinedMembersCount = joinedMembersCount, joinedMembersCount = joinedMembersCount,
userPowerLevels = userPowerLevels, powerLevels = roomPowerLevels,
highlightCount = highlightCount, highlightCount = highlightCount,
notificationCount = notificationCount, notificationCount = notificationCount,
cachedUserDefinedNotificationMode = userDefinedNotificationMode, cachedUserDefinedNotificationMode = userDefinedNotificationMode,

View file

@ -25,6 +25,7 @@ import org.matrix.rustcomponents.sdk.PusherKind
import org.matrix.rustcomponents.sdk.RoomDirectorySearch import org.matrix.rustcomponents.sdk.RoomDirectorySearch
import org.matrix.rustcomponents.sdk.Session import org.matrix.rustcomponents.sdk.Session
import org.matrix.rustcomponents.sdk.SessionVerificationController import org.matrix.rustcomponents.sdk.SessionVerificationController
import org.matrix.rustcomponents.sdk.SyncService
import org.matrix.rustcomponents.sdk.SyncServiceBuilder import org.matrix.rustcomponents.sdk.SyncServiceBuilder
import org.matrix.rustcomponents.sdk.TaskHandle import org.matrix.rustcomponents.sdk.TaskHandle
import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate
@ -62,7 +63,7 @@ class FakeFfiClient(
) = Unit ) = Unit
override suspend fun deletePusher(identifiers: PusherIdentifiers) = Unit override suspend fun deletePusher(identifiers: PusherIdentifiers) = Unit
override suspend fun clearCaches() = simulateLongTask { clearCachesResult() } override suspend fun clearCaches(syncService: SyncService?) = simulateLongTask { clearCachesResult() }
override suspend fun setUtdDelegate(utdDelegate: UnableToDecryptDelegate) = withUtdHook(utdDelegate) override suspend fun setUtdDelegate(utdDelegate: UnableToDecryptDelegate) = withUtdHook(utdDelegate)
override suspend fun getSessionVerificationController(): SessionVerificationController = FakeFfiSessionVerificationController() override suspend fun getSessionVerificationController(): SessionVerificationController = FakeFfiSessionVerificationController()
override suspend fun ignoredUsers(): List<String> { override suspend fun ignoredUsers(): List<String> {

View file

@ -18,7 +18,7 @@ import org.matrix.rustcomponents.sdk.RequestConfig
import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder
import uniffi.matrix_sdk.BackupDownloadStrategy import uniffi.matrix_sdk.BackupDownloadStrategy
import uniffi.matrix_sdk_crypto.CollectStrategy import uniffi.matrix_sdk_crypto.CollectStrategy
import uniffi.matrix_sdk_crypto.TrustRequirement import uniffi.matrix_sdk_crypto.DecryptionSettings
class FakeFfiClientBuilder : ClientBuilder(NoPointer) { class FakeFfiClientBuilder : ClientBuilder(NoPointer) {
override fun addRootCertificates(certificates: List<ByteArray>) = this override fun addRootCertificates(certificates: List<ByteArray>) = this
@ -27,7 +27,7 @@ class FakeFfiClientBuilder : ClientBuilder(NoPointer) {
override fun backupDownloadStrategy(backupDownloadStrategy: BackupDownloadStrategy) = this override fun backupDownloadStrategy(backupDownloadStrategy: BackupDownloadStrategy) = this
override fun disableAutomaticTokenRefresh() = this override fun disableAutomaticTokenRefresh() = this
override fun disableBuiltInRootCertificates() = this override fun disableBuiltInRootCertificates() = this
override fun roomDecryptionTrustRequirement(trustRequirement: TrustRequirement) = this override fun decryptionSettings(decryptionSettings: DecryptionSettings): ClientBuilder = this
override fun disableSslVerification() = this override fun disableSslVerification() = this
override fun homeserverUrl(url: String) = this override fun homeserverUrl(url: String) = this
override fun sessionPassphrase(passphrase: String?) = this override fun sessionPassphrase(passphrase: String?) = this

View file

@ -0,0 +1,33 @@
/*
* 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 io.element.android.libraries.matrix.impl.fixtures.fakes
import org.matrix.rustcomponents.sdk.NoPointer
import org.matrix.rustcomponents.sdk.RoomPowerLevels
import org.matrix.rustcomponents.sdk.RoomPowerLevelsValues
class FakeFfiRoomPowerLevels(
private val values: RoomPowerLevelsValues = defaultFfiRoomPowerLevelValues(),
private val users: Map<String, Long> = emptyMap(),
) : RoomPowerLevels(NoPointer) {
override fun values(): RoomPowerLevelsValues = values
override fun userPowerLevels(): Map<String, Long> = users
}
fun defaultFfiRoomPowerLevelValues() = RoomPowerLevelsValues(
ban = 50,
invite = 0,
kick = 50,
eventsDefault = 0,
redact = 50,
roomName = 100,
roomAvatar = 100,
roomTopic = 100,
stateDefault = 0,
usersDefault = 0,
)

View file

@ -16,10 +16,12 @@ import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomHero import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomHero
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomInfo import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomInfo
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomMember import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomMember
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiRoomPowerLevels
import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_AVATAR_URL
import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_ROOM_ALIAS import io.element.android.libraries.matrix.test.A_ROOM_ALIAS
@ -28,8 +30,9 @@ import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_3 import io.element.android.libraries.matrix.test.A_USER_ID_3
import io.element.android.libraries.matrix.test.A_USER_ID_6 import io.element.android.libraries.matrix.test.A_USER_ID_6
import io.element.android.libraries.matrix.test.room.aRoomMember import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableMap
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList
import org.junit.Test import org.junit.Test
import org.matrix.rustcomponents.sdk.Membership import org.matrix.rustcomponents.sdk.Membership
@ -64,7 +67,7 @@ class RoomInfoMapperTest {
activeMembersCount = 2uL, activeMembersCount = 2uL,
invitedMembersCount = 3uL, invitedMembersCount = 3uL,
joinedMembersCount = 4uL, joinedMembersCount = 4uL,
userPowerLevels = mapOf(A_USER_ID_6.value to 50L), roomPowerLevels = FakeFfiRoomPowerLevels(users = mapOf(A_USER_ID_6.value to 50L)),
highlightCount = 10uL, highlightCount = 10uL,
notificationCount = 11uL, notificationCount = 11uL,
userDefinedNotificationMode = RustRoomNotificationMode.MUTE, userDefinedNotificationMode = RustRoomNotificationMode.MUTE,
@ -99,7 +102,10 @@ class RoomInfoMapperTest {
activeMembersCount = 2L, activeMembersCount = 2L,
invitedMembersCount = 3L, invitedMembersCount = 3L,
joinedMembersCount = 4L, joinedMembersCount = 4L,
userPowerLevels = mapOf(A_USER_ID_6 to 50L).toImmutableMap(), roomPowerLevels = RoomPowerLevels(
values = defaultRoomPowerLevelValues(),
users = persistentMapOf(A_USER_ID_6 to 50L)
),
highlightCount = 10L, highlightCount = 10L,
notificationCount = 11L, notificationCount = 11L,
userDefinedNotificationMode = RoomNotificationMode.MUTE, userDefinedNotificationMode = RoomNotificationMode.MUTE,
@ -149,7 +155,7 @@ class RoomInfoMapperTest {
activeMembersCount = 2uL, activeMembersCount = 2uL,
invitedMembersCount = 3uL, invitedMembersCount = 3uL,
joinedMembersCount = 4uL, joinedMembersCount = 4uL,
userPowerLevels = emptyMap(), roomPowerLevels = FakeFfiRoomPowerLevels(),
highlightCount = 10uL, highlightCount = 10uL,
notificationCount = 11uL, notificationCount = 11uL,
userDefinedNotificationMode = null, userDefinedNotificationMode = null,
@ -184,7 +190,10 @@ class RoomInfoMapperTest {
activeMembersCount = 2L, activeMembersCount = 2L,
invitedMembersCount = 3L, invitedMembersCount = 3L,
joinedMembersCount = 4L, joinedMembersCount = 4L,
userPowerLevels = emptyMap<UserId, Long>().toImmutableMap(), roomPowerLevels = RoomPowerLevels(
values = defaultRoomPowerLevelValues(),
users = persistentMapOf(),
),
highlightCount = 10L, highlightCount = 10L,
notificationCount = 11L, notificationCount = 11L,
userDefinedNotificationMode = null, userDefinedNotificationMode = null,

View file

@ -225,7 +225,7 @@ class FakeBaseRoom(
override fun predecessorRoom(): PredecessorRoom? = predecessorRoomResult() override fun predecessorRoom(): PredecessorRoom? = predecessorRoomResult()
} }
fun defaultRoomPowerLevels() = RoomPowerLevelsValues( fun defaultRoomPowerLevelValues() = RoomPowerLevelsValues(
ban = 50, ban = 50,
invite = 0, invite = 0,
kick = 50, kick = 50,

View file

@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_AVATAR_URL
@ -24,7 +25,6 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_ROOM_NAME
import io.element.android.libraries.matrix.test.A_ROOM_RAW_NAME import io.element.android.libraries.matrix.test.A_ROOM_RAW_NAME
import io.element.android.libraries.matrix.test.A_ROOM_TOPIC import io.element.android.libraries.matrix.test.A_ROOM_TOPIC
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
@ -52,7 +52,10 @@ fun aRoomInfo(
notificationCount: Long = 0, notificationCount: Long = 0,
userDefinedNotificationMode: RoomNotificationMode? = null, userDefinedNotificationMode: RoomNotificationMode? = null,
hasRoomCall: Boolean = false, hasRoomCall: Boolean = false,
userPowerLevels: ImmutableMap<UserId, Long> = persistentMapOf(), roomPowerLevels: RoomPowerLevels = RoomPowerLevels(
values = defaultRoomPowerLevelValues(),
users = persistentMapOf(),
),
activeRoomCallParticipants: List<UserId> = emptyList(), activeRoomCallParticipants: List<UserId> = emptyList(),
heroes: List<MatrixUser> = emptyList(), heroes: List<MatrixUser> = emptyList(),
pinnedEventIds: List<EventId> = emptyList(), pinnedEventIds: List<EventId> = emptyList(),
@ -86,7 +89,7 @@ fun aRoomInfo(
notificationCount = notificationCount, notificationCount = notificationCount,
userDefinedNotificationMode = userDefinedNotificationMode, userDefinedNotificationMode = userDefinedNotificationMode,
hasRoomCall = hasRoomCall, hasRoomCall = hasRoomCall,
userPowerLevels = userPowerLevels, roomPowerLevels = roomPowerLevels,
activeRoomCallParticipants = activeRoomCallParticipants.toImmutableList(), activeRoomCallParticipants = activeRoomCallParticipants.toImmutableList(),
heroes = heroes.toImmutableList(), heroes = heroes.toImmutableList(),
pinnedEventIds = pinnedEventIds.toImmutableList(), pinnedEventIds = pinnedEventIds.toImmutableList(),

View file

@ -18,6 +18,7 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.message.RoomMessage import io.element.android.libraries.matrix.api.room.message.RoomMessage
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
@ -29,7 +30,6 @@ import io.element.android.libraries.matrix.test.A_ROOM_RAW_NAME
import io.element.android.libraries.matrix.test.A_ROOM_TOPIC import io.element.android.libraries.matrix.test.A_ROOM_TOPIC
import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList
@ -65,7 +65,10 @@ fun aRoomSummary(
notificationCount: Long = 0, notificationCount: Long = 0,
userDefinedNotificationMode: RoomNotificationMode? = null, userDefinedNotificationMode: RoomNotificationMode? = null,
hasRoomCall: Boolean = false, hasRoomCall: Boolean = false,
userPowerLevels: ImmutableMap<UserId, Long> = persistentMapOf(), roomPowerLevels: RoomPowerLevels = RoomPowerLevels(
values = defaultRoomPowerLevelValues(),
users = persistentMapOf(),
),
activeRoomCallParticipants: List<UserId> = emptyList(), activeRoomCallParticipants: List<UserId> = emptyList(),
heroes: List<MatrixUser> = emptyList(), heroes: List<MatrixUser> = emptyList(),
pinnedEventIds: List<EventId> = emptyList(), pinnedEventIds: List<EventId> = emptyList(),
@ -97,7 +100,7 @@ fun aRoomSummary(
activeMembersCount = activeMembersCount, activeMembersCount = activeMembersCount,
invitedMembersCount = invitedMembersCount, invitedMembersCount = invitedMembersCount,
joinedMembersCount = joinedMembersCount, joinedMembersCount = joinedMembersCount,
userPowerLevels = userPowerLevels, roomPowerLevels = roomPowerLevels,
highlightCount = highlightCount, highlightCount = highlightCount,
notificationCount = notificationCount, notificationCount = notificationCount,
userDefinedNotificationMode = userDefinedNotificationMode, userDefinedNotificationMode = userDefinedNotificationMode,

View file

@ -106,7 +106,7 @@ fun BaseRoom.userPowerLevelAsState(updateKey: Long): State<Long> {
@Composable @Composable
fun BaseRoom.isOwnUserAdmin(): Boolean { fun BaseRoom.isOwnUserAdmin(): Boolean {
val roomInfo by roomInfoFlow.collectAsState() val roomInfo by roomInfoFlow.collectAsState()
val powerLevel = roomInfo.userPowerLevels[sessionId] ?: 0L val powerLevel = roomInfo.roomPowerLevels?.users?.get(sessionId) ?: 0L
return RoomMember.Role.forPowerLevel(powerLevel) == RoomMember.Role.ADMIN return RoomMember.Role.forPowerLevel(powerLevel) == RoomMember.Role.ADMIN
} }