change(room permissions): fix some role&permissions inconsistencies after last changes
This commit is contained in:
@@ -36,6 +36,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.usersWithRole
|
||||
import io.element.android.libraries.matrix.api.room.toMatrixUser
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.libraries.matrix.ui.model.powerLevelOf
|
||||
import io.element.android.libraries.matrix.ui.model.roleOf
|
||||
import io.element.android.libraries.matrix.ui.room.PowerLevelRoomMemberComparator
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
@@ -124,9 +125,10 @@ class ChangeRolesPresenter(
|
||||
|
||||
val roomInfo by room.roomInfoFlow.collectAsState()
|
||||
fun canChangeMemberRole(userId: UserId): Boolean {
|
||||
val currentUserRole = roomInfo.roleOf(room.sessionId)
|
||||
val otherUserRole = roomInfo.roleOf(userId)
|
||||
return currentUserRole.powerLevel > otherUserRole.powerLevel
|
||||
val currentUserPowerLevel = roomInfo.powerLevelOf(room.sessionId)
|
||||
val otherUserPowerLevel = roomInfo.powerLevelOf(userId)
|
||||
return currentUserPowerLevel > otherUserPowerLevel &&
|
||||
currentUserPowerLevel >= role.powerLevel
|
||||
}
|
||||
|
||||
fun handleEvent(event: ChangeRolesEvent) {
|
||||
|
||||
@@ -28,6 +28,7 @@ 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.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -49,7 +50,16 @@ class RolesAndPermissionsPresenter(
|
||||
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 availableDemoteActions by remember {
|
||||
derivedStateOf {
|
||||
val currentRole = roomInfo.roleOf(room.sessionId)
|
||||
when (currentRole) {
|
||||
is RoomMember.Role.Admin -> persistentListOf(DemoteActions.ToModerator, DemoteActions.ToMember)
|
||||
is RoomMember.Role.Moderator -> persistentListOf(DemoteActions.ToMember)
|
||||
else -> persistentListOf()
|
||||
}
|
||||
}
|
||||
}
|
||||
val changeOwnRoleAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
|
||||
val resetPermissionsAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
|
||||
|
||||
@@ -78,7 +88,7 @@ class RolesAndPermissionsPresenter(
|
||||
roomSupportsOwnerRole = roomInfo.privilegedCreatorRole,
|
||||
adminCount = adminCount,
|
||||
moderatorCount = moderatorCount,
|
||||
canDemoteSelf = canDemoteSelf.value,
|
||||
availableDemoteActions = availableDemoteActions,
|
||||
changeOwnRoleAction = changeOwnRoleAction.value,
|
||||
resetPermissionsAction = resetPermissionsAction.value,
|
||||
eventSink = ::handleEvent,
|
||||
|
||||
@@ -8,14 +8,24 @@
|
||||
|
||||
package io.element.android.features.rolesandpermissions.impl.root
|
||||
|
||||
import io.element.android.features.rolesandpermissions.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class RolesAndPermissionsState(
|
||||
val roomSupportsOwnerRole: Boolean,
|
||||
val adminCount: Int?,
|
||||
val moderatorCount: Int?,
|
||||
val canDemoteSelf: Boolean,
|
||||
val availableDemoteActions: ImmutableList<DemoteActions>,
|
||||
val changeOwnRoleAction: AsyncAction<Unit>,
|
||||
val resetPermissionsAction: AsyncAction<Unit>,
|
||||
val eventSink: (RolesAndPermissionsEvents) -> Unit,
|
||||
)
|
||||
) {
|
||||
val canDemoteSelf = availableDemoteActions.isNotEmpty()
|
||||
}
|
||||
|
||||
enum class DemoteActions(val role: RoomMember.Role, val titleRes: Int) {
|
||||
ToModerator(RoomMember.Role.Moderator, R.string.screen_room_roles_and_permissions_change_role_demote_to_moderator),
|
||||
ToMember(RoomMember.Role.User, R.string.screen_room_roles_and_permissions_change_role_demote_to_member)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ package io.element.android.features.rolesandpermissions.impl.root
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
class RolesAndPermissionsStateProvider : PreviewParameterProvider<RolesAndPermissionsState> {
|
||||
override val values: Sequence<RolesAndPermissionsState>
|
||||
@@ -46,7 +47,7 @@ class RolesAndPermissionsStateProvider : PreviewParameterProvider<RolesAndPermis
|
||||
moderatorCount = 2,
|
||||
resetPermissionsAction = AsyncAction.Failure(IllegalStateException("Failed to reset permissions")),
|
||||
),
|
||||
aRolesAndPermissionsState(canDemoteSelf = false),
|
||||
aRolesAndPermissionsState(availableDemoteActions = emptyList()),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -54,14 +55,14 @@ internal fun aRolesAndPermissionsState(
|
||||
roomSupportsOwners: Boolean = true,
|
||||
adminCount: Int = 0,
|
||||
moderatorCount: Int = 0,
|
||||
canDemoteSelf: Boolean = true,
|
||||
availableDemoteActions: List<DemoteActions> = listOf(DemoteActions.ToModerator, DemoteActions.ToMember),
|
||||
changeOwnRoleAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||
resetPermissionsAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||
eventSink: (RolesAndPermissionsEvents) -> Unit = {},
|
||||
) = RolesAndPermissionsState(
|
||||
roomSupportsOwnerRole = roomSupportsOwners,
|
||||
adminCount = adminCount,
|
||||
canDemoteSelf = canDemoteSelf,
|
||||
availableDemoteActions = availableDemoteActions.toImmutableList(),
|
||||
moderatorCount = moderatorCount,
|
||||
changeOwnRoleAction = changeOwnRoleAction,
|
||||
resetPermissionsAction = resetPermissionsAction,
|
||||
|
||||
@@ -39,8 +39,8 @@ import io.element.android.libraries.designsystem.theme.components.ListSectionHea
|
||||
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.components.hide
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Composable
|
||||
fun RolesAndPermissionsView(
|
||||
@@ -117,6 +117,7 @@ fun RolesAndPermissionsView(
|
||||
when (state.changeOwnRoleAction) {
|
||||
is AsyncAction.Confirming -> {
|
||||
ChangeOwnRoleBottomSheet(
|
||||
availableDemoteActions = state.availableDemoteActions,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
}
|
||||
@@ -136,6 +137,7 @@ fun RolesAndPermissionsView(
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun ChangeOwnRoleBottomSheet(
|
||||
availableDemoteActions: ImmutableList<DemoteActions>,
|
||||
eventSink: (RolesAndPermissionsEvents) -> Unit,
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
@@ -164,24 +166,17 @@ private fun ChangeOwnRoleBottomSheet(
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_change_role_demote_to_moderator)) },
|
||||
onClick = {
|
||||
sheetState.hide(coroutineScope) {
|
||||
eventSink(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.Moderator))
|
||||
}
|
||||
},
|
||||
style = ListItemStyle.Destructive,
|
||||
)
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_change_role_demote_to_member)) },
|
||||
onClick = {
|
||||
sheetState.hide(coroutineScope) {
|
||||
eventSink(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.User))
|
||||
}
|
||||
},
|
||||
style = ListItemStyle.Destructive,
|
||||
)
|
||||
for (demoteAction in availableDemoteActions) {
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(demoteAction.titleRes)) },
|
||||
onClick = {
|
||||
sheetState.hide(coroutineScope) {
|
||||
eventSink(RolesAndPermissionsEvents.DemoteSelfTo(demoteAction.role))
|
||||
}
|
||||
},
|
||||
style = ListItemStyle.Destructive,
|
||||
)
|
||||
}
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(CommonStrings.action_cancel)) },
|
||||
onClick = ::dismiss,
|
||||
|
||||
Reference in New Issue
Block a user