change(space settings): manage permissions
This commit is contained in:
@@ -17,11 +17,14 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.zacsweers.metro.Inject
|
||||
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||
import im.vector.app.features.analytics.plan.JoinedRoom.Trigger
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.features.invite.api.SeenInvitesStore
|
||||
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
|
||||
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
|
||||
import io.element.android.features.invite.api.toInviteData
|
||||
import io.element.android.features.space.impl.settings.SpaceSettingsPermissions
|
||||
import io.element.android.features.space.impl.settings.spaceSettingsPermissions
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.coroutine.mapState
|
||||
@@ -33,6 +36,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
|
||||
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
||||
import io.element.android.libraries.matrix.api.room.join.JoinRoom
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceRoomList
|
||||
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
|
||||
@@ -50,6 +54,7 @@ import kotlin.jvm.optionals.getOrNull
|
||||
@Inject
|
||||
class SpacePresenter(
|
||||
private val spaceRoomList: SpaceRoomList,
|
||||
private val room: JoinedRoom,
|
||||
private val client: MatrixClient,
|
||||
private val seenInvitesStore: SeenInvitesStore,
|
||||
private val joinRoom: JoinRoom,
|
||||
@@ -82,6 +87,9 @@ class SpacePresenter(
|
||||
}
|
||||
}.collectAsState()
|
||||
|
||||
val permissions by room.permissionsAsState(SpaceSettingsPermissions.DEFAULT) { perms ->
|
||||
perms.spaceSettingsPermissions()
|
||||
}
|
||||
val isSpaceSettingsEnabled by remember {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.SpaceSettings)
|
||||
}.collectAsState(false)
|
||||
@@ -136,7 +144,7 @@ class SpacePresenter(
|
||||
joinActions = joinActions.toImmutableMap(),
|
||||
acceptDeclineInviteState = acceptDeclineInviteState,
|
||||
topicViewerState = topicViewerState,
|
||||
canAccessSpaceSettings = isSpaceSettingsEnabled,
|
||||
canAccessSpaceSettings = isSpaceSettingsEnabled && permissions.hasAny,
|
||||
eventSink = ::handleEvent,
|
||||
)
|
||||
}
|
||||
@@ -150,7 +158,7 @@ class SpacePresenter(
|
||||
joinRoom.invoke(
|
||||
roomIdOrAlias = spaceRoom.roomId.toRoomIdOrAlias(),
|
||||
serverNames = spaceRoom.via,
|
||||
trigger = JoinedRoom.Trigger.SpaceHierarchy,
|
||||
trigger = Trigger.SpaceHierarchy,
|
||||
).onFailure {
|
||||
setJoinActions(joinActions + mapOf(spaceRoom.roomId to AsyncAction.Failure(it)))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations 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.features.space.impl.settings
|
||||
|
||||
import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions
|
||||
import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions
|
||||
import io.element.android.libraries.matrix.api.room.StateEventType
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions
|
||||
|
||||
data class SpaceSettingsPermissions(
|
||||
val canEditDetails: Boolean,
|
||||
val canManageRolesAndPermissions: Boolean,
|
||||
val canManageSecurityAndPrivacy: Boolean,
|
||||
){
|
||||
|
||||
val hasAny = canEditDetails || canManageRolesAndPermissions || canManageSecurityAndPrivacy
|
||||
|
||||
companion object {
|
||||
val DEFAULT = SpaceSettingsPermissions(
|
||||
canEditDetails = false,
|
||||
canManageRolesAndPermissions = false,
|
||||
canManageSecurityAndPrivacy = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun RoomPermissions.spaceSettingsPermissions(): SpaceSettingsPermissions {
|
||||
return SpaceSettingsPermissions(
|
||||
canEditDetails = roomDetailsEditPermissions().hasAny,
|
||||
canManageRolesAndPermissions = canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS),
|
||||
canManageSecurityAndPrivacy = securityAndPrivacyPermissions().hasAny,
|
||||
)
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import androidx.compose.runtime.getValue
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.ui.room.isOwnUserAdmin
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState
|
||||
|
||||
@Inject
|
||||
class SpaceSettingsPresenter(
|
||||
@@ -23,15 +23,18 @@ class SpaceSettingsPresenter(
|
||||
@Composable
|
||||
override fun present(): SpaceSettingsState {
|
||||
val roomInfo by room.roomInfoFlow.collectAsState()
|
||||
val isUserAdmin = room.isOwnUserAdmin()
|
||||
val permissions by room.permissionsAsState(SpaceSettingsPermissions.DEFAULT) { perms ->
|
||||
perms.spaceSettingsPermissions()
|
||||
}
|
||||
return SpaceSettingsState(
|
||||
roomId = room.roomId,
|
||||
name = roomInfo.name.orEmpty(),
|
||||
canonicalAlias = roomInfo.canonicalAlias,
|
||||
avatarUrl = roomInfo.avatarUrl,
|
||||
memberCount = roomInfo.activeMembersCount,
|
||||
showRolesAndPermissions = isUserAdmin,
|
||||
showSecurityAndPrivacy = isUserAdmin,
|
||||
canEditDetails = permissions.canEditDetails,
|
||||
showRolesAndPermissions = permissions.canManageRolesAndPermissions,
|
||||
showSecurityAndPrivacy = permissions.canManageSecurityAndPrivacy,
|
||||
eventSink = {},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ data class SpaceSettingsState(
|
||||
val canonicalAlias: RoomAlias?,
|
||||
val avatarUrl: String?,
|
||||
val memberCount: Long,
|
||||
val canEditDetails: Boolean,
|
||||
val showRolesAndPermissions: Boolean,
|
||||
val showSecurityAndPrivacy: Boolean,
|
||||
val eventSink: (SpaceSettingsEvents) -> Unit
|
||||
|
||||
@@ -30,6 +30,7 @@ fun aSpaceSettingsState(
|
||||
memberCount: Long = 100,
|
||||
showRolesAndPermissions: Boolean = false,
|
||||
showSecurityAndPrivacy: Boolean = false,
|
||||
canEditDetails: Boolean = false,
|
||||
eventSink: (SpaceSettingsEvents) -> Unit = {},
|
||||
) = SpaceSettingsState(
|
||||
roomId = roomId,
|
||||
@@ -37,6 +38,7 @@ fun aSpaceSettingsState(
|
||||
canonicalAlias = alias,
|
||||
avatarUrl = avatarUrl,
|
||||
memberCount = memberCount,
|
||||
canEditDetails = canEditDetails,
|
||||
showRolesAndPermissions = showRolesAndPermissions,
|
||||
showSecurityAndPrivacy = showSecurityAndPrivacy,
|
||||
eventSink = eventSink,
|
||||
|
||||
@@ -73,6 +73,7 @@ fun SpaceSettingsView(
|
||||
name = state.name,
|
||||
avatarUrl = state.avatarUrl,
|
||||
canonicalAlias = state.canonicalAlias?.value,
|
||||
canEditDetails = state.canEditDetails,
|
||||
onSpaceInfoClick = onSpaceInfoClick,
|
||||
)
|
||||
Section(isVisible = state.showSecurityAndPrivacy, content = {
|
||||
@@ -101,12 +102,13 @@ private fun SpaceInfoSection(
|
||||
name: String,
|
||||
avatarUrl: String?,
|
||||
canonicalAlias: String?,
|
||||
canEditDetails: Boolean,
|
||||
onSpaceInfoClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onSpaceInfoClick)
|
||||
.clickable(enabled = canEditDetails, onClick = onSpaceInfoClick)
|
||||
.padding(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user