fix: rely only on RoomMember Role values instead of using the powerLevel.

This commit is contained in:
ganfra 2025-12-01 16:08:11 +01:00
parent 7a1dd24dbd
commit a91c78b56f
10 changed files with 84 additions and 122 deletions

View file

@ -79,18 +79,13 @@ class ChangeRolesPresenter(
val usersWithRole = produceState<ImmutableList<MatrixUser>>(initialValue = persistentListOf()) {
// If the role is admin, we need to include the owners as well since they implicitly have admin role
val owners = if (role == RoomMember.Role.Admin) {
combine(
room.usersWithRole(RoomMember.Role.Owner(isCreator = true)),
room.usersWithRole(RoomMember.Role.Owner(isCreator = false)),
) { creators, superAdmins ->
creators + superAdmins
}
room.usersWithRole { role -> role is RoomMember.Role.Owner }
} else {
emptyFlow()
}
combine(
owners,
room.usersWithRole(role),
room.usersWithRole { it == role },
) { owners, users ->
owners + users
}.map { members -> members.map { it.toMatrixUser() } }

View file

@ -22,12 +22,10 @@ import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.activeRoomMembers
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
import io.element.android.libraries.matrix.api.room.powerlevels.userCountWithRole
import io.element.android.libraries.matrix.ui.model.roleOf
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.CoroutineScope
@ -43,32 +41,14 @@ class RolesAndPermissionsPresenter(
override fun present(): RolesAndPermissionsState {
val coroutineScope = rememberCoroutineScope()
val roomInfo by room.roomInfoFlow.collectAsState()
val roomMembers by room.membersStateFlow.collectAsState()
// Get the list of active room members (joined or invited), in order to filter members present in the power
// level state Event.
val activeRoomMemberIds by remember {
derivedStateOf {
roomMembers.activeRoomMembers().map { it.userId }
}
}
val moderatorCount by remember {
derivedStateOf {
roomInfo.userCountWithRole(activeRoomMemberIds, RoomMember.Role.Moderator)
}
}
room.userCountWithRole { role -> role is RoomMember.Role.Moderator }
}.collectAsState(null)
val adminCount by remember {
derivedStateOf {
val admins = roomInfo.userCountWithRole(activeRoomMemberIds, RoomMember.Role.Admin)
val ownersCount = if (roomInfo.privilegedCreatorRole) {
val superAdmins = roomInfo.userCountWithRole(activeRoomMemberIds, RoomMember.Role.Owner(isCreator = false))
val creators = roomInfo.userCountWithRole(activeRoomMemberIds, RoomMember.Role.Owner(isCreator = true))
superAdmins + creators
} else {
0
}
admins + ownersCount
}
}
room.userCountWithRole { role -> role is RoomMember.Role.Admin || role is RoomMember.Role.Owner }
}.collectAsState(null)
val canDemoteSelf = remember { derivedStateOf { roomInfo.roleOf(room.sessionId) !is RoomMember.Role.Owner } }
val changeOwnRoleAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
val resetPermissionsAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
@ -122,8 +102,4 @@ class RolesAndPermissionsPresenter(
room.resetPowerLevels()
}
}
private fun RoomInfo.userCountWithRole(userIds: List<UserId>, role: RoomMember.Role): Int {
return usersWithRole(role).filter { it in userIds }.size
}
}

View file

@ -12,8 +12,8 @@ import io.element.android.libraries.architecture.AsyncAction
data class RolesAndPermissionsState(
val roomSupportsOwnerRole: Boolean,
val adminCount: Int,
val moderatorCount: Int,
val adminCount: Int?,
val moderatorCount: Int?,
val canDemoteSelf: Boolean,
val changeOwnRoleAction: AsyncAction<Unit>,
val resetPermissionsAction: AsyncAction<Unit>,

View file

@ -63,13 +63,17 @@ fun RolesAndPermissionsView(
ListItem(
headlineContent = { Text(adminsTitle) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Admin())),
trailingContent = ListItemContent.Text("${state.adminCount}"),
trailingContent = state.adminCount?.let { adminCount ->
ListItemContent.Text("$adminCount")
},
onClick = { rolesAndPermissionsNavigator.openAdminList() },
)
ListItem(
headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_moderators)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.ChatProblem())),
trailingContent = ListItemContent.Text("${state.moderatorCount}"),
trailingContent = state.moderatorCount?.let { moderationCount ->
ListItemContent.Text("$moderationCount")
},
onClick = { rolesAndPermissionsNavigator.openModeratorList() },
)
if (state.canDemoteSelf) {