Merge pull request #5950 from element-hq/feature/fga/iterate_permissions_screen
Changes : iterate again on permissions
This commit is contained in:
+2
-2
@@ -85,7 +85,7 @@ sealed interface ListItemContent {
|
||||
data class Text(val text: String) : ListItemContent
|
||||
|
||||
/** Displays any custom content. */
|
||||
data class Custom(val content: @Composable () -> Unit) : ListItemContent
|
||||
data class Custom(val content: @Composable (enabled: Boolean) -> Unit) : ListItemContent
|
||||
|
||||
/** Displays a badge. */
|
||||
data object Badge : ListItemContent
|
||||
@@ -131,7 +131,7 @@ sealed interface ListItemContent {
|
||||
is Counter -> {
|
||||
CounterAtom(count = count)
|
||||
}
|
||||
is Custom -> content()
|
||||
is Custom -> content(isItemEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -43,7 +43,6 @@ fun PreferenceCheckbox(
|
||||
leadingContent = preferenceIcon(
|
||||
icon = icon,
|
||||
iconResourceId = iconResourceId,
|
||||
enabled = enabled,
|
||||
showIconAreaIfNoIcon = showIconAreaIfNoIcon,
|
||||
),
|
||||
headlineContent = {
|
||||
|
||||
+17
-7
@@ -40,7 +40,7 @@ import io.element.android.libraries.designsystem.theme.components.DropdownMenuIt
|
||||
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
|
||||
import io.element.android.libraries.designsystem.toIconSecondaryEnabledColor
|
||||
import io.element.android.libraries.designsystem.toSecondaryEnabledColor
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -64,7 +64,6 @@ fun <T : DropdownOption> PreferenceDropdown(
|
||||
leadingContent = preferenceIcon(
|
||||
icon = icon,
|
||||
iconResourceId = iconResourceId,
|
||||
enabled = enabled,
|
||||
showIconAreaIfNoIcon = showIconAreaIfNoIcon,
|
||||
),
|
||||
headlineContent = {
|
||||
@@ -72,7 +71,6 @@ fun <T : DropdownOption> PreferenceDropdown(
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = title,
|
||||
color = enabled.toEnabledColor(),
|
||||
)
|
||||
},
|
||||
supportingContent = supportingText?.let {
|
||||
@@ -80,22 +78,23 @@ fun <T : DropdownOption> PreferenceDropdown(
|
||||
Text(
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
text = it,
|
||||
color = enabled.toSecondaryEnabledColor(),
|
||||
)
|
||||
}
|
||||
},
|
||||
trailingContent = ListItemContent.Custom(
|
||||
content = {
|
||||
content = { enabled ->
|
||||
DropdownTrailingContent(
|
||||
selectedOption = selectedOption,
|
||||
options = options,
|
||||
onSelectOption = onSelectOption,
|
||||
expanded = isDropdownExpanded,
|
||||
onExpandedChange = { isDropdownExpanded = it },
|
||||
enabled = enabled,
|
||||
modifier = Modifier.fillMaxSize(0.3f)
|
||||
)
|
||||
}
|
||||
),
|
||||
enabled = enabled,
|
||||
onClick = { isDropdownExpanded = true }.takeIf { !isDropdownExpanded },
|
||||
)
|
||||
}
|
||||
@@ -118,6 +117,7 @@ private fun <T : DropdownOption> DropdownTrailingContent(
|
||||
expanded: Boolean,
|
||||
onExpandedChange: (Boolean) -> Unit,
|
||||
onSelectOption: (T) -> Unit,
|
||||
enabled: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(
|
||||
@@ -129,7 +129,7 @@ private fun <T : DropdownOption> DropdownTrailingContent(
|
||||
text = selectedOption?.getText().orEmpty(),
|
||||
maxLines = 1,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
color = enabled.toSecondaryEnabledColor(),
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
textAlign = TextAlign.End,
|
||||
modifier = Modifier.weight(1f),
|
||||
@@ -137,7 +137,7 @@ private fun <T : DropdownOption> DropdownTrailingContent(
|
||||
Icon(
|
||||
imageVector = CompoundIcons.ChevronDown(),
|
||||
contentDescription = null,
|
||||
tint = ElementTheme.colors.iconSecondary,
|
||||
tint = enabled.toIconSecondaryEnabledColor(),
|
||||
)
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
@@ -146,6 +146,7 @@ private fun <T : DropdownOption> DropdownTrailingContent(
|
||||
) {
|
||||
options.forEach { option ->
|
||||
DropdownMenuItem(
|
||||
enabled = enabled,
|
||||
text = {
|
||||
Text(
|
||||
text = option.getText(),
|
||||
@@ -206,5 +207,14 @@ internal fun PreferenceDropdownPreview() = ElementThemedPreview {
|
||||
options = options,
|
||||
onSelectOption = {},
|
||||
)
|
||||
PreferenceDropdown(
|
||||
title = "Dropdown",
|
||||
supportingText = "Options for dropdown",
|
||||
icon = CompoundIcons.Threads(),
|
||||
selectedOption = options.first(),
|
||||
options = options,
|
||||
onSelectOption = {},
|
||||
enabled = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -44,7 +44,6 @@ fun PreferenceSlide(
|
||||
leadingContent = preferenceIcon(
|
||||
icon = icon,
|
||||
iconResourceId = iconResourceId,
|
||||
enabled = enabled,
|
||||
showIconAreaIfNoIcon = showIconAreaIfNoIcon,
|
||||
),
|
||||
headlineContent = {
|
||||
|
||||
-1
@@ -42,7 +42,6 @@ fun PreferenceSwitch(
|
||||
leadingContent = preferenceIcon(
|
||||
icon = icon,
|
||||
iconResourceId = iconResourceId,
|
||||
enabled = enabled,
|
||||
showIconAreaIfNoIcon = showIconAreaIfNoIcon,
|
||||
),
|
||||
headlineContent = {
|
||||
|
||||
+1
-2
@@ -34,11 +34,10 @@ fun preferenceIcon(
|
||||
@DrawableRes iconResourceId: Int? = null,
|
||||
showIconBadge: Boolean = false,
|
||||
tintColor: Color? = null,
|
||||
enabled: Boolean = true,
|
||||
showIconAreaIfNoIcon: Boolean = false,
|
||||
): ListItemContent.Custom? {
|
||||
return if (icon != null || iconResourceId != null || showIconAreaIfNoIcon) {
|
||||
ListItemContent.Custom {
|
||||
ListItemContent.Custom { enabled ->
|
||||
PreferenceIcon(
|
||||
icon = icon,
|
||||
iconResourceId = iconResourceId,
|
||||
|
||||
+16
-5
@@ -21,6 +21,20 @@ fun RoomInfo.getAvatarData(size: AvatarSize) = AvatarData(
|
||||
size = size,
|
||||
)
|
||||
|
||||
/**
|
||||
* Returns the power level of the user in the room.
|
||||
* If the user is a creator and [RoomInfo.privilegedCreatorRole] is true, returns the power level of [RoomMember.Role.Owner].
|
||||
* Otherwise, checks the room's power levels for the user's power level.
|
||||
* If no specific power level is set for the user, defaults to 0.
|
||||
*/
|
||||
fun RoomInfo.powerLevelOf(userId: UserId): Long {
|
||||
return if (privilegedCreatorRole && creators.contains(userId)) {
|
||||
RoomMember.Role.Owner(isCreator = true).powerLevel
|
||||
} else {
|
||||
roomPowerLevels?.powerLevelOf(userId = userId) ?: 0L
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the role of the user in the room.
|
||||
* If the user is a creator and [RoomInfo.privilegedCreatorRole] is true, returns [RoomMember.Role.Owner].
|
||||
@@ -28,9 +42,6 @@ fun RoomInfo.getAvatarData(size: AvatarSize) = AvatarData(
|
||||
* If no specific power level is set for the user, defaults to [RoomMember.Role.User].
|
||||
*/
|
||||
fun RoomInfo.roleOf(userId: UserId): RoomMember.Role {
|
||||
return if (privilegedCreatorRole && creators.contains(userId)) {
|
||||
RoomMember.Role.Owner(isCreator = true)
|
||||
} else {
|
||||
roomPowerLevels?.roleOf(userId) ?: RoomMember.Role.User
|
||||
}
|
||||
val powerLevel = powerLevelOf(userId = userId)
|
||||
return RoomMember.Role.forPowerLevel(powerLevel)
|
||||
}
|
||||
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-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.ui.room
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.produceState
|
||||
import io.element.android.libraries.matrix.api.room.BaseRoom
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.ui.model.roleOf
|
||||
|
||||
@Composable
|
||||
fun BaseRoom.userPowerLevelAsState(updateKey: Long): State<Long> {
|
||||
return produceState(initialValue = 0, key1 = updateKey) {
|
||||
value = userRole(sessionId)
|
||||
.getOrDefault(RoomMember.Role.User)
|
||||
.powerLevel
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BaseRoom.isOwnUserAdmin(): Boolean {
|
||||
val roomInfo by roomInfoFlow.collectAsState()
|
||||
val role = roomInfo.roleOf(sessionId)
|
||||
return role == RoomMember.Role.Admin || role is RoomMember.Role.Owner
|
||||
}
|
||||
Reference in New Issue
Block a user