change(roles and permissions): update change permission design
This commit is contained in:
@@ -23,7 +23,6 @@ import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.rolesandpermissions.api.ChangeRoomMemberRolesEntryPoint
|
||||
import io.element.android.features.rolesandpermissions.api.ChangeRoomMemberRolesListType
|
||||
import io.element.android.features.rolesandpermissions.impl.permissions.ChangeRoomPermissionsNode
|
||||
import io.element.android.features.rolesandpermissions.impl.permissions.ChangeRoomPermissionsSection
|
||||
import io.element.android.features.rolesandpermissions.impl.root.RolesAndPermissionsNode
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
@@ -59,7 +58,7 @@ class RolesAndPermissionsFlowNode(
|
||||
data object ModeratorList : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data class ChangeRoomPermissions(val section: ChangeRoomPermissionsSection) : NavTarget
|
||||
data object ChangeRoomPermissions: NavTarget
|
||||
}
|
||||
|
||||
override fun onBuilt() {
|
||||
@@ -84,17 +83,10 @@ class RolesAndPermissionsFlowNode(
|
||||
backstack.push(NavTarget.ModeratorList)
|
||||
}
|
||||
|
||||
override fun openEditRoomDetailsPermissions() {
|
||||
backstack.push(NavTarget.ChangeRoomPermissions(ChangeRoomPermissionsSection.RoomDetails))
|
||||
override fun openEditPermissions() {
|
||||
backstack.push(NavTarget.ChangeRoomPermissions)
|
||||
}
|
||||
|
||||
override fun openMessagesAndContentPermissions() {
|
||||
backstack.push(NavTarget.ChangeRoomPermissions(ChangeRoomPermissionsSection.MessagesAndContent))
|
||||
}
|
||||
|
||||
override fun openModerationPermissions() {
|
||||
backstack.push(NavTarget.ChangeRoomPermissions(ChangeRoomPermissionsSection.MembershipModeration))
|
||||
}
|
||||
}
|
||||
createNode<RolesAndPermissionsNode>(
|
||||
buildContext = buildContext,
|
||||
@@ -118,11 +110,7 @@ class RolesAndPermissionsFlowNode(
|
||||
)
|
||||
}
|
||||
is NavTarget.ChangeRoomPermissions -> {
|
||||
val inputs = ChangeRoomPermissionsNode.Inputs(navTarget.section)
|
||||
createNode<ChangeRoomPermissionsNode>(
|
||||
buildContext = buildContext,
|
||||
plugins = listOf(inputs),
|
||||
)
|
||||
createNode<ChangeRoomPermissionsNode>(buildContext = buildContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
|
||||
package io.element.android.features.rolesandpermissions.impl.permissions
|
||||
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
|
||||
interface ChangeRoomPermissionsEvent {
|
||||
data class ChangeMinimumRoleForAction(val action: RoomPermissionType, val role: RoomMember.Role) : ChangeRoomPermissionsEvent
|
||||
data class ChangeMinimumRoleForAction(val action: RoomPermissionType, val role: SelectableRole) : ChangeRoomPermissionsEvent
|
||||
data object Save : ChangeRoomPermissionsEvent
|
||||
data object Exit : ChangeRoomPermissionsEvent
|
||||
data object ResetPendingActions : ChangeRoomPermissionsEvent
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
package io.element.android.features.rolesandpermissions.impl.permissions
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
@@ -16,25 +15,15 @@ import com.bumble.appyx.core.plugin.Plugin
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.libraries.architecture.NodeInputs
|
||||
import io.element.android.libraries.architecture.inputs
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@ContributesNode(RoomScope::class)
|
||||
@AssistedInject
|
||||
class ChangeRoomPermissionsNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
presenterFactory: ChangeRoomPermissionsPresenter.Factory,
|
||||
private val presenter: ChangeRoomPermissionsPresenter,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
@Parcelize
|
||||
data class Inputs(
|
||||
val section: ChangeRoomPermissionsSection,
|
||||
) : NodeInputs, Parcelable
|
||||
|
||||
private val inputs: Inputs = inputs()
|
||||
private val presenter = presenterFactory.create(inputs.section)
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
@@ -46,10 +35,3 @@ class ChangeRoomPermissionsNode(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
enum class ChangeRoomPermissionsSection : Parcelable {
|
||||
RoomDetails,
|
||||
MessagesAndContent,
|
||||
MembershipModeration,
|
||||
}
|
||||
|
||||
@@ -15,50 +15,50 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.features.rolesandpermissions.impl.analytics.trackPermissionChangeAnalytics
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AssistedInject
|
||||
@Inject
|
||||
class ChangeRoomPermissionsPresenter(
|
||||
@Assisted private val section: ChangeRoomPermissionsSection,
|
||||
private val room: JoinedRoom,
|
||||
private val analyticsService: AnalyticsService,
|
||||
) : Presenter<ChangeRoomPermissionsState> {
|
||||
companion object {
|
||||
internal fun itemsForSection(section: ChangeRoomPermissionsSection) = when (section) {
|
||||
ChangeRoomPermissionsSection.RoomDetails -> persistentListOf(
|
||||
private fun itemsForSection(section: RoomPermissionsSection) = when (section) {
|
||||
RoomPermissionsSection.RoomDetails -> persistentListOf(
|
||||
RoomPermissionType.ROOM_NAME,
|
||||
RoomPermissionType.ROOM_AVATAR,
|
||||
RoomPermissionType.ROOM_TOPIC,
|
||||
)
|
||||
ChangeRoomPermissionsSection.MessagesAndContent -> persistentListOf(
|
||||
RoomPermissionsSection.MessagesAndContent -> persistentListOf(
|
||||
RoomPermissionType.SEND_EVENTS,
|
||||
RoomPermissionType.REDACT_EVENTS,
|
||||
)
|
||||
ChangeRoomPermissionsSection.MembershipModeration -> persistentListOf(
|
||||
RoomPermissionsSection.MembershipModeration -> persistentListOf(
|
||||
RoomPermissionType.INVITE,
|
||||
RoomPermissionType.KICK,
|
||||
RoomPermissionType.BAN,
|
||||
)
|
||||
}
|
||||
}
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(section: ChangeRoomPermissionsSection): ChangeRoomPermissionsPresenter
|
||||
|
||||
internal fun buildItems(forSpace: Boolean) = persistentMapOf(
|
||||
RoomPermissionsSection.RoomDetails to itemsForSection(RoomPermissionsSection.RoomDetails),
|
||||
RoomPermissionsSection.MessagesAndContent to itemsForSection(RoomPermissionsSection.MessagesAndContent),
|
||||
RoomPermissionsSection.MembershipModeration to itemsForSection(RoomPermissionsSection.MembershipModeration),
|
||||
)
|
||||
}
|
||||
|
||||
private val items: ImmutableList<RoomPermissionType> = itemsForSection(section)
|
||||
private val items = buildItems(forSpace = room.info().isSpace)
|
||||
|
||||
private var initialPermissions by mutableStateOf<RoomPowerLevelsValues?>(null)
|
||||
private var currentPermissions by mutableStateOf<RoomPowerLevelsValues?>(null)
|
||||
@@ -80,15 +80,20 @@ class ChangeRoomPermissionsPresenter(
|
||||
fun handleEvent(event: ChangeRoomPermissionsEvent) {
|
||||
when (event) {
|
||||
is ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction -> {
|
||||
val powerLevel = when (event.role) {
|
||||
SelectableRole.Admin -> RoomMember.Role.Admin.powerLevel
|
||||
SelectableRole.Moderator -> RoomMember.Role.Moderator.powerLevel
|
||||
SelectableRole.Everyone -> RoomMember.Role.User.powerLevel
|
||||
}
|
||||
currentPermissions = when (event.action) {
|
||||
RoomPermissionType.BAN -> currentPermissions?.copy(ban = event.role.powerLevel)
|
||||
RoomPermissionType.INVITE -> currentPermissions?.copy(invite = event.role.powerLevel)
|
||||
RoomPermissionType.KICK -> currentPermissions?.copy(kick = event.role.powerLevel)
|
||||
RoomPermissionType.SEND_EVENTS -> currentPermissions?.copy(sendEvents = event.role.powerLevel)
|
||||
RoomPermissionType.REDACT_EVENTS -> currentPermissions?.copy(redactEvents = event.role.powerLevel)
|
||||
RoomPermissionType.ROOM_NAME -> currentPermissions?.copy(roomName = event.role.powerLevel)
|
||||
RoomPermissionType.ROOM_AVATAR -> currentPermissions?.copy(roomAvatar = event.role.powerLevel)
|
||||
RoomPermissionType.ROOM_TOPIC -> currentPermissions?.copy(roomTopic = event.role.powerLevel)
|
||||
RoomPermissionType.BAN -> currentPermissions?.copy(ban = powerLevel)
|
||||
RoomPermissionType.INVITE -> currentPermissions?.copy(invite = powerLevel)
|
||||
RoomPermissionType.KICK -> currentPermissions?.copy(kick = powerLevel)
|
||||
RoomPermissionType.SEND_EVENTS -> currentPermissions?.copy(sendEvents = powerLevel)
|
||||
RoomPermissionType.REDACT_EVENTS -> currentPermissions?.copy(redactEvents = powerLevel)
|
||||
RoomPermissionType.ROOM_NAME -> currentPermissions?.copy(roomName = powerLevel)
|
||||
RoomPermissionType.ROOM_AVATAR -> currentPermissions?.copy(roomAvatar = powerLevel)
|
||||
RoomPermissionType.ROOM_TOPIC -> currentPermissions?.copy(roomTopic = powerLevel)
|
||||
}
|
||||
}
|
||||
is ChangeRoomPermissionsEvent.Save -> coroutineScope.save()
|
||||
@@ -106,9 +111,8 @@ class ChangeRoomPermissionsPresenter(
|
||||
}
|
||||
}
|
||||
return ChangeRoomPermissionsState(
|
||||
section = section,
|
||||
currentPermissions = currentPermissions,
|
||||
items = items,
|
||||
itemsBySection = items,
|
||||
hasChanges = hasChanges,
|
||||
saveAction = saveAction,
|
||||
confirmExitAction = confirmExitAction,
|
||||
|
||||
@@ -7,19 +7,71 @@
|
||||
|
||||
package io.element.android.features.rolesandpermissions.impl.permissions
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import io.element.android.features.rolesandpermissions.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.designsystem.components.preferences.DropdownOption
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
|
||||
data class ChangeRoomPermissionsState(
|
||||
val section: ChangeRoomPermissionsSection,
|
||||
val currentPermissions: RoomPowerLevelsValues?,
|
||||
val items: ImmutableList<RoomPermissionType>,
|
||||
val itemsBySection: ImmutableMap<RoomPermissionsSection, ImmutableList<RoomPermissionType>>,
|
||||
val hasChanges: Boolean,
|
||||
val saveAction: AsyncAction<Unit>,
|
||||
val confirmExitAction: AsyncAction<Unit>,
|
||||
val eventSink: (ChangeRoomPermissionsEvent) -> Unit,
|
||||
)
|
||||
){
|
||||
fun selectedRoleForType(type: RoomPermissionType): SelectableRole? {
|
||||
if(currentPermissions == null) return null
|
||||
val role = when (type) {
|
||||
RoomPermissionType.BAN -> RoomMember.Role.forPowerLevel(currentPermissions.ban)
|
||||
RoomPermissionType.INVITE -> RoomMember.Role.forPowerLevel(currentPermissions.invite)
|
||||
RoomPermissionType.KICK -> RoomMember.Role.forPowerLevel(currentPermissions.kick)
|
||||
RoomPermissionType.SEND_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.sendEvents)
|
||||
RoomPermissionType.REDACT_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.redactEvents)
|
||||
RoomPermissionType.ROOM_NAME -> RoomMember.Role.forPowerLevel(currentPermissions.roomName)
|
||||
RoomPermissionType.ROOM_AVATAR -> RoomMember.Role.forPowerLevel(currentPermissions.roomAvatar)
|
||||
RoomPermissionType.ROOM_TOPIC -> RoomMember.Role.forPowerLevel(currentPermissions.roomTopic)
|
||||
}
|
||||
return when(role){
|
||||
is RoomMember.Role.Owner,
|
||||
RoomMember.Role.Admin -> SelectableRole.Admin
|
||||
RoomMember.Role.Moderator -> SelectableRole.Moderator
|
||||
RoomMember.Role.User -> SelectableRole.Everyone
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum class RoomPermissionsSection {
|
||||
RoomDetails,
|
||||
MessagesAndContent,
|
||||
MembershipModeration,
|
||||
}
|
||||
|
||||
enum class SelectableRole: DropdownOption {
|
||||
Admin {
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
override fun getText(): String = stringResource(R.string.screen_room_member_list_role_administrator)
|
||||
},
|
||||
Moderator {
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
override fun getText(): String = stringResource(R.string.screen_room_member_list_role_moderator)
|
||||
},
|
||||
Everyone {
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
override fun getText(): String = stringResource(R.string.screen_room_change_permissions_everyone)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum class RoomPermissionType {
|
||||
BAN,
|
||||
|
||||
@@ -11,41 +11,33 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableMap
|
||||
|
||||
class ChangeRoomPermissionsStateProvider : PreviewParameterProvider<ChangeRoomPermissionsState> {
|
||||
override val values: Sequence<ChangeRoomPermissionsState>
|
||||
get() = sequenceOf(
|
||||
aChangeRoomPermissionsState(section = ChangeRoomPermissionsSection.RoomDetails),
|
||||
aChangeRoomPermissionsState(section = ChangeRoomPermissionsSection.MessagesAndContent),
|
||||
aChangeRoomPermissionsState(section = ChangeRoomPermissionsSection.MembershipModeration),
|
||||
aChangeRoomPermissionsState(section = ChangeRoomPermissionsSection.RoomDetails, hasChanges = true),
|
||||
aChangeRoomPermissionsState(section = ChangeRoomPermissionsSection.RoomDetails, hasChanges = true, saveAction = AsyncAction.Loading),
|
||||
aChangeRoomPermissionsState(),
|
||||
aChangeRoomPermissionsState(hasChanges = true),
|
||||
aChangeRoomPermissionsState(hasChanges = true, saveAction = AsyncAction.Loading),
|
||||
aChangeRoomPermissionsState(
|
||||
section = ChangeRoomPermissionsSection.RoomDetails,
|
||||
hasChanges = true,
|
||||
saveAction = AsyncAction.Failure(IllegalStateException("Failed to save changes"))
|
||||
),
|
||||
aChangeRoomPermissionsState(
|
||||
section = ChangeRoomPermissionsSection.RoomDetails,
|
||||
hasChanges = true,
|
||||
confirmExitAction = AsyncAction.ConfirmingNoParams,
|
||||
),
|
||||
aChangeRoomPermissionsState(hasChanges = true, confirmExitAction = AsyncAction.ConfirmingNoParams),
|
||||
)
|
||||
}
|
||||
|
||||
internal fun aChangeRoomPermissionsState(
|
||||
section: ChangeRoomPermissionsSection,
|
||||
currentPermissions: RoomPowerLevelsValues = previewPermissions(),
|
||||
items: List<RoomPermissionType> = ChangeRoomPermissionsPresenter.itemsForSection(section),
|
||||
itemsBySection: Map<RoomPermissionsSection, ImmutableList<RoomPermissionType>> = ChangeRoomPermissionsPresenter.buildItems(false),
|
||||
hasChanges: Boolean = false,
|
||||
saveAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||
confirmExitAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||
eventSink: (ChangeRoomPermissionsEvent) -> Unit = {},
|
||||
) = ChangeRoomPermissionsState(
|
||||
section = section,
|
||||
currentPermissions = currentPermissions,
|
||||
items = items.toImmutableList(),
|
||||
itemsBySection = itemsBySection.toImmutableMap(),
|
||||
hasChanges = hasChanges,
|
||||
saveAction = saveAction,
|
||||
confirmExitAction = confirmExitAction,
|
||||
|
||||
@@ -23,6 +23,7 @@ import io.element.android.libraries.designsystem.components.async.AsyncActionVie
|
||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
|
||||
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceDropdown
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.IconSource
|
||||
@@ -36,6 +37,7 @@ import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -50,13 +52,8 @@ fun ChangeRoomPermissionsView(
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
val title = when (state.section) {
|
||||
ChangeRoomPermissionsSection.RoomDetails -> stringResource(R.string.screen_room_change_permissions_room_details)
|
||||
ChangeRoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_change_permissions_messages_and_content)
|
||||
ChangeRoomPermissionsSection.MembershipModeration -> stringResource(R.string.screen_room_change_permissions_member_moderation)
|
||||
}
|
||||
TopAppBar(
|
||||
titleStr = title,
|
||||
titleStr = stringResource(R.string.screen_room_roles_and_permissions_permissions_header),
|
||||
navigationIcon = {
|
||||
BackButton(onClick = { state.eventSink(ChangeRoomPermissionsEvent.Exit) })
|
||||
},
|
||||
@@ -75,29 +72,25 @@ fun ChangeRoomPermissionsView(
|
||||
.padding(padding)
|
||||
.fillMaxSize()
|
||||
) {
|
||||
for ((index, permissionItem) in state.items.withIndex()) {
|
||||
state.itemsBySection.onEachIndexed { index, (section, items) ->
|
||||
item {
|
||||
ListSectionHeader(titleForSection(item = permissionItem), hasDivider = index > 0)
|
||||
SelectRoleItem(
|
||||
permissionsItem = permissionItem,
|
||||
role = RoomMember.Role.Admin,
|
||||
currentPermissions = state.currentPermissions
|
||||
) { item, role ->
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(item, role))
|
||||
}
|
||||
SelectRoleItem(
|
||||
permissionsItem = permissionItem,
|
||||
role = RoomMember.Role.Moderator,
|
||||
currentPermissions = state.currentPermissions
|
||||
) { item, role ->
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(item, role))
|
||||
}
|
||||
SelectRoleItem(
|
||||
permissionsItem = permissionItem,
|
||||
role = RoomMember.Role.User,
|
||||
currentPermissions = state.currentPermissions
|
||||
) { item, role ->
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(item, role))
|
||||
ListSectionHeader(titleForSection(section), hasDivider = index>0)
|
||||
}
|
||||
for (permissionType in items) {
|
||||
item {
|
||||
PreferenceDropdown(
|
||||
title = titleForType(permissionType),
|
||||
selectedOption = state.selectedRoleForType(permissionType),
|
||||
options = SelectableRole.entries.toImmutableList(),
|
||||
onSelectOption = { role ->
|
||||
state.eventSink(
|
||||
ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(
|
||||
action = permissionType,
|
||||
role = role
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,47 +119,15 @@ fun ChangeRoomPermissionsView(
|
||||
onErrorDismiss = {},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SelectRoleItem(
|
||||
permissionsItem: RoomPermissionType,
|
||||
role: RoomMember.Role,
|
||||
currentPermissions: RoomPowerLevelsValues?,
|
||||
onClick: (RoomPermissionType, RoomMember.Role) -> Unit
|
||||
) {
|
||||
val title = when (role) {
|
||||
RoomMember.Role.Admin -> stringResource(R.string.screen_room_change_permissions_administrators)
|
||||
RoomMember.Role.Moderator -> stringResource(R.string.screen_room_change_permissions_moderators)
|
||||
RoomMember.Role.User -> stringResource(R.string.screen_room_change_permissions_everyone)
|
||||
else -> error("Unsupported role selected: $role")
|
||||
}
|
||||
ListItem(
|
||||
headlineContent = { Text(text = title) },
|
||||
trailingContent = if (currentPermissions?.isSelected(permissionsItem, role).orFalse()) {
|
||||
ListItemContent.Icon(IconSource.Vector(CompoundIcons.Check()))
|
||||
} else {
|
||||
null
|
||||
},
|
||||
style = ListItemStyle.Primary,
|
||||
onClick = { onClick(permissionsItem, role) },
|
||||
)
|
||||
}
|
||||
|
||||
private fun RoomPowerLevelsValues.isSelected(item: RoomPermissionType, role: RoomMember.Role): Boolean {
|
||||
return when (item) {
|
||||
RoomPermissionType.BAN -> RoomMember.Role.forPowerLevel(ban) == role
|
||||
RoomPermissionType.INVITE -> RoomMember.Role.forPowerLevel(invite) == role
|
||||
RoomPermissionType.KICK -> RoomMember.Role.forPowerLevel(kick) == role
|
||||
RoomPermissionType.SEND_EVENTS -> RoomMember.Role.forPowerLevel(sendEvents) == role
|
||||
RoomPermissionType.REDACT_EVENTS -> RoomMember.Role.forPowerLevel(redactEvents) == role
|
||||
RoomPermissionType.ROOM_NAME -> RoomMember.Role.forPowerLevel(roomName) == role
|
||||
RoomPermissionType.ROOM_AVATAR -> RoomMember.Role.forPowerLevel(roomAvatar) == role
|
||||
RoomPermissionType.ROOM_TOPIC -> RoomMember.Role.forPowerLevel(roomTopic) == role
|
||||
}
|
||||
private fun titleForSection(section: RoomPermissionsSection): String = when (section) {
|
||||
RoomPermissionsSection.RoomDetails -> stringResource(R.string.screen_room_change_permissions_room_details)
|
||||
RoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_change_permissions_messages_and_content)
|
||||
RoomPermissionsSection.MembershipModeration -> stringResource(R.string.screen_room_change_permissions_member_moderation)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun titleForSection(item: RoomPermissionType): String = when (item) {
|
||||
private fun titleForType(type: RoomPermissionType): String = when (type) {
|
||||
RoomPermissionType.INVITE -> stringResource(R.string.screen_room_change_permissions_invite_people)
|
||||
RoomPermissionType.KICK -> stringResource(R.string.screen_room_change_permissions_remove_people)
|
||||
RoomPermissionType.BAN -> stringResource(R.string.screen_room_change_permissions_ban_people)
|
||||
|
||||
@@ -39,9 +39,8 @@ class RolesAndPermissionsNode(
|
||||
interface Callback : Plugin, RolesAndPermissionsNavigator {
|
||||
override fun openAdminList()
|
||||
override fun openModeratorList()
|
||||
override fun openEditRoomDetailsPermissions()
|
||||
override fun openMessagesAndContentPermissions()
|
||||
override fun openModerationPermissions()
|
||||
override fun openEditPermissions()
|
||||
|
||||
override fun onBackClick() {}
|
||||
}
|
||||
|
||||
@@ -85,7 +84,5 @@ interface RolesAndPermissionsNavigator {
|
||||
fun onBackClick() {}
|
||||
fun openAdminList() {}
|
||||
fun openModeratorList() {}
|
||||
fun openEditRoomDetailsPermissions() {}
|
||||
fun openMessagesAndContentPermissions() {}
|
||||
fun openModerationPermissions() {}
|
||||
fun openEditPermissions() {}
|
||||
}
|
||||
|
||||
@@ -78,25 +78,16 @@ fun RolesAndPermissionsView(
|
||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Edit()))
|
||||
)
|
||||
}
|
||||
ListSectionHeader(title = stringResource(R.string.screen_room_roles_and_permissions_permissions_header), hasDivider = true)
|
||||
HorizontalDivider()
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_room_details)) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Info())),
|
||||
onClick = { rolesAndPermissionsNavigator.openEditRoomDetailsPermissions() },
|
||||
)
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_messages_and_content)) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Chat())),
|
||||
onClick = { rolesAndPermissionsNavigator.openMessagesAndContentPermissions() },
|
||||
)
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_member_moderation)) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.User())),
|
||||
onClick = { rolesAndPermissionsNavigator.openModerationPermissions() },
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_permissions_header)) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Settings())),
|
||||
onClick = { rolesAndPermissionsNavigator.openEditPermissions() },
|
||||
)
|
||||
HorizontalDivider()
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_reset)) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Delete())),
|
||||
onClick = { state.eventSink(RolesAndPermissionsEvents.ResetPermissions) },
|
||||
style = ListItemStyle.Destructive,
|
||||
)
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
package io.element.android.libraries.designsystem.components.preferences
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
@@ -26,6 +28,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
||||
@@ -33,6 +36,7 @@ import io.element.android.libraries.designsystem.components.preferences.componen
|
||||
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.ListItem
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.toEnabledColor
|
||||
@@ -144,6 +148,15 @@ private fun <T : DropdownOption> DropdownTrailingContent(
|
||||
style = ElementTheme.typography.fontBodyMdRegular
|
||||
)
|
||||
},
|
||||
trailingIcon = {
|
||||
if(option == selectedOption){
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Check(),
|
||||
contentDescription = null,
|
||||
tint = ElementTheme.colors.iconSuccessPrimary,
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
onSelectOption(option)
|
||||
onExpandedChange(false)
|
||||
|
||||
Reference in New Issue
Block a user