Merge pull request #5908 from element-hq/feature/fga/space_settings_iteration
Change : space settings iteration
This commit is contained in:
commit
f29b0e399a
78 changed files with 428 additions and 205 deletions
|
|
@ -8,6 +8,19 @@
|
|||
|
||||
package io.element.android.features.rolesandpermissions.api
|
||||
|
||||
import io.element.android.libraries.architecture.SimpleFeatureEntryPoint
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import io.element.android.libraries.architecture.FeatureEntryPoint
|
||||
|
||||
fun interface RolesAndPermissionsEntryPoint : SimpleFeatureEntryPoint
|
||||
fun interface RolesAndPermissionsEntryPoint : FeatureEntryPoint {
|
||||
interface Callback : Plugin {
|
||||
fun onDone()
|
||||
}
|
||||
|
||||
fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
callback: Callback,
|
||||
): Node
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@ import io.element.android.libraries.di.RoomScope
|
|||
|
||||
@ContributesBinding(RoomScope::class)
|
||||
class DefaultRolesAndPermissionsEntryPoint : RolesAndPermissionsEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
|
||||
return parentNode.createNode<RolesAndPermissionsFlowNode>(buildContext)
|
||||
override fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
callback: RolesAndPermissionsEntryPoint.Callback,
|
||||
): Node {
|
||||
return parentNode.createNode<RolesAndPermissionsFlowNode>(buildContext, listOf(callback))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ import androidx.compose.foundation.layout.statusBarsPadding
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
|
|
@ -25,17 +28,24 @@ import dev.zacsweers.metro.Assisted
|
|||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.rolesandpermissions.api.ChangeRoomMemberRolesListType
|
||||
import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEntryPoint
|
||||
import io.element.android.features.rolesandpermissions.impl.permissions.ChangeRoomPermissionsNode
|
||||
import io.element.android.features.rolesandpermissions.impl.roles.ChangeRolesNode
|
||||
import io.element.android.features.rolesandpermissions.impl.root.RolesAndPermissionsNode
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncIndicator
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncIndicatorHost
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncIndicatorState
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.canEditRolesAndPermissions
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.permissionsFlow
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
|
|
@ -44,6 +54,7 @@ import kotlinx.parcelize.Parcelize
|
|||
class RolesAndPermissionsFlowNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val room: JoinedRoom,
|
||||
) : BaseFlowNode<RolesAndPermissionsFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
initialElement = NavTarget.Root,
|
||||
|
|
@ -66,6 +77,7 @@ class RolesAndPermissionsFlowNode(
|
|||
data object ChangeRoomPermissions : NavTarget
|
||||
}
|
||||
|
||||
private val callback: RolesAndPermissionsEntryPoint.Callback = callback()
|
||||
private val asyncIndicatorState = AsyncIndicatorState()
|
||||
|
||||
override fun onBuilt() {
|
||||
|
|
@ -76,6 +88,15 @@ class RolesAndPermissionsFlowNode(
|
|||
onChangeComplete(changesSaved)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||
room.permissionsFlow(false) { perms -> perms.canEditRolesAndPermissions() }
|
||||
.filter { canEdit -> !canEdit }
|
||||
.first()
|
||||
// If the user can no longer edit roles and permissions, exit the flow
|
||||
callback.onDone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onChangeComplete(changesSaved: Boolean) {
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ internal fun AnalyticsService.trackPermissionChangeAnalytics(initial: RoomPowerL
|
|||
if (updated.kick != initial?.kick) {
|
||||
capture(RoomModeration(RoomModeration.Action.ChangePermissionsKickMembers, analyticsMemberRoleForPowerLevel(updated.kick)))
|
||||
}
|
||||
if (updated.sendEvents != initial?.sendEvents) {
|
||||
capture(RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, analyticsMemberRoleForPowerLevel(updated.sendEvents)))
|
||||
if (updated.eventsDefault != initial?.eventsDefault) {
|
||||
capture(RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, analyticsMemberRoleForPowerLevel(updated.eventsDefault)))
|
||||
}
|
||||
if (updated.redactEvents != initial?.redactEvents) {
|
||||
capture(RoomModeration(RoomModeration.Action.ChangePermissionsRedactMessages, analyticsMemberRoleForPowerLevel(updated.redactEvents)))
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ class ChangeRoomPermissionsPresenter(
|
|||
) : Presenter<ChangeRoomPermissionsState> {
|
||||
companion object {
|
||||
private fun itemsForSection(section: RoomPermissionsSection) = when (section) {
|
||||
RoomPermissionsSection.SpaceDetails,
|
||||
RoomPermissionsSection.RoomDetails -> persistentListOf(
|
||||
RoomPermissionsSection.EditDetails -> persistentListOf(
|
||||
RoomPermissionType.ROOM_NAME,
|
||||
RoomPermissionType.ROOM_AVATAR,
|
||||
RoomPermissionType.ROOM_TOPIC,
|
||||
|
|
@ -46,19 +45,23 @@ class ChangeRoomPermissionsPresenter(
|
|||
RoomPermissionType.SEND_EVENTS,
|
||||
RoomPermissionType.REDACT_EVENTS,
|
||||
)
|
||||
RoomPermissionsSection.MembershipModeration -> persistentListOf(
|
||||
RoomPermissionsSection.ManageMembers -> persistentListOf(
|
||||
RoomPermissionType.INVITE,
|
||||
RoomPermissionType.KICK,
|
||||
RoomPermissionType.BAN,
|
||||
)
|
||||
RoomPermissionsSection.ManageSpace -> persistentListOf(
|
||||
RoomPermissionType.SPACE_MANAGE_ROOMS,
|
||||
RoomPermissionType.CHANGE_SETTINGS,
|
||||
)
|
||||
}
|
||||
|
||||
private fun RoomPermissionsSection.shouldShow(isSpace: Boolean): Boolean {
|
||||
return when (this) {
|
||||
RoomPermissionsSection.RoomDetails -> !isSpace
|
||||
RoomPermissionsSection.MembershipModeration -> true
|
||||
RoomPermissionsSection.EditDetails -> true
|
||||
RoomPermissionsSection.ManageMembers -> true
|
||||
RoomPermissionsSection.MessagesAndContent -> !isSpace
|
||||
RoomPermissionsSection.SpaceDetails -> isSpace
|
||||
RoomPermissionsSection.ManageSpace -> isSpace
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,11 +102,13 @@ class ChangeRoomPermissionsPresenter(
|
|||
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.SEND_EVENTS -> currentPermissions?.copy(eventsDefault = 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)
|
||||
RoomPermissionType.SPACE_MANAGE_ROOMS -> currentPermissions?.copy(spaceChild = powerLevel)
|
||||
RoomPermissionType.CHANGE_SETTINGS -> currentPermissions?.copy(stateDefault = powerLevel)
|
||||
}
|
||||
}
|
||||
is ChangeRoomPermissionsEvent.Save -> coroutineScope.save()
|
||||
|
|
|
|||
|
|
@ -32,11 +32,13 @@ data class ChangeRoomPermissionsState(
|
|||
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.SEND_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.eventsDefault)
|
||||
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)
|
||||
RoomPermissionType.SPACE_MANAGE_ROOMS -> RoomMember.Role.forPowerLevel(currentPermissions.spaceChild)
|
||||
RoomPermissionType.CHANGE_SETTINGS -> RoomMember.Role.forPowerLevel(currentPermissions.stateDefault)
|
||||
}
|
||||
return when (role) {
|
||||
is RoomMember.Role.Owner,
|
||||
|
|
@ -48,10 +50,10 @@ data class ChangeRoomPermissionsState(
|
|||
}
|
||||
|
||||
enum class RoomPermissionsSection {
|
||||
SpaceDetails,
|
||||
RoomDetails,
|
||||
ManageMembers,
|
||||
EditDetails,
|
||||
MessagesAndContent,
|
||||
MembershipModeration,
|
||||
ManageSpace
|
||||
}
|
||||
|
||||
enum class SelectableRole : DropdownOption {
|
||||
|
|
@ -80,5 +82,7 @@ enum class RoomPermissionType {
|
|||
REDACT_EVENTS,
|
||||
ROOM_NAME,
|
||||
ROOM_AVATAR,
|
||||
ROOM_TOPIC
|
||||
ROOM_TOPIC,
|
||||
SPACE_MANAGE_ROOMS,
|
||||
CHANGE_SETTINGS,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class ChangeRoomPermissionsStateProvider : PreviewParameterProvider<ChangeRoomPe
|
|||
saveAction = AsyncAction.Failure(IllegalStateException("Failed to save changes"))
|
||||
),
|
||||
aChangeRoomPermissionsState(hasChanges = true, saveAction = AsyncAction.ConfirmingCancellation),
|
||||
aChangeRoomPermissionsState(itemsBySection = ChangeRoomPermissionsPresenter.buildItems(isSpace = true)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -51,12 +52,13 @@ private fun previewPermissions(): RoomPowerLevelsValues {
|
|||
ban = RoomMember.Role.User.powerLevel,
|
||||
// MessagesAndContent section
|
||||
redactEvents = RoomMember.Role.Moderator.powerLevel,
|
||||
sendEvents = RoomMember.Role.Admin.powerLevel,
|
||||
eventsDefault = RoomMember.Role.Admin.powerLevel,
|
||||
// RoomDetails section
|
||||
roomName = RoomMember.Role.Admin.powerLevel,
|
||||
roomAvatar = RoomMember.Role.Moderator.powerLevel,
|
||||
roomTopic = RoomMember.Role.User.powerLevel,
|
||||
// SpaceManagement section
|
||||
spaceChild = RoomMember.Role.Moderator.powerLevel,
|
||||
stateDefault = RoomMember.Role.Moderator.powerLevel,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,10 +110,10 @@ fun ChangeRoomPermissionsView(
|
|||
|
||||
@Composable
|
||||
private fun titleForSection(section: RoomPermissionsSection): String = when (section) {
|
||||
RoomPermissionsSection.SpaceDetails -> stringResource(R.string.screen_room_roles_and_permissions_space_details)
|
||||
RoomPermissionsSection.RoomDetails -> stringResource(R.string.screen_room_roles_and_permissions_room_details)
|
||||
RoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_roles_and_permissions_messages_and_content)
|
||||
RoomPermissionsSection.MembershipModeration -> stringResource(R.string.screen_room_roles_and_permissions_member_moderation)
|
||||
RoomPermissionsSection.EditDetails -> stringResource(R.string.screen_room_change_permissions_room_details)
|
||||
RoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_change_permissions_messages_and_content)
|
||||
RoomPermissionsSection.ManageMembers -> stringResource(R.string.screen_room_change_permissions_member_moderation)
|
||||
RoomPermissionsSection.ManageSpace -> stringResource(R.string.screen_room_change_permissions_manage_space)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -126,6 +126,8 @@ private fun titleForType(type: RoomPermissionType): String = when (type) {
|
|||
RoomPermissionType.ROOM_NAME -> stringResource(R.string.screen_room_change_permissions_room_name)
|
||||
RoomPermissionType.ROOM_AVATAR -> stringResource(R.string.screen_room_change_permissions_room_avatar)
|
||||
RoomPermissionType.ROOM_TOPIC -> stringResource(R.string.screen_room_change_permissions_room_topic)
|
||||
RoomPermissionType.SPACE_MANAGE_ROOMS -> stringResource(R.string.screen_room_change_permissions_manage_space_rooms)
|
||||
RoomPermissionType.CHANGE_SETTINGS -> stringResource(R.string.screen_room_change_permissions_change_settings)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ package io.element.android.features.rolesandpermissions.impl.root
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
|
|
@ -20,14 +19,6 @@ import dev.zacsweers.metro.AssistedInject
|
|||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
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
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@ContributesNode(RoomScope::class)
|
||||
@AssistedInject
|
||||
|
|
@ -35,7 +26,6 @@ class RolesAndPermissionsNode(
|
|||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val presenter: RolesAndPermissionsPresenter,
|
||||
private val room: BaseRoom,
|
||||
) : Node(buildContext, plugins = plugins), RolesAndPermissionsNavigator {
|
||||
interface Callback : Plugin, RolesAndPermissionsNavigator {
|
||||
override fun openAdminList()
|
||||
|
|
@ -54,22 +44,6 @@ class RolesAndPermissionsNode(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onBuilt() {
|
||||
super.onBuilt()
|
||||
|
||||
// If the user is not an admin anymore, exit this section since they won't have permissions to use it
|
||||
lifecycleScope.launch {
|
||||
room.roomInfoFlow
|
||||
.filter { info ->
|
||||
val role = info.roleOf(room.sessionId)
|
||||
role != RoomMember.Role.Admin && role !is RoomMember.Role.Owner
|
||||
}
|
||||
.take(1)
|
||||
.onEach { navigateUp() }
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Správce"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Vykázat lidi"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Změnit nastavení"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Odstranit zprávy"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Člen"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Pozvat přátele"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Správa prostoru"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Spravovat místnosti"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Spravovat členy"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Zprávy a obsah"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Moderátor"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Změnit název místnosti"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Změnit téma místnosti"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Odeslat zprávy"</string>
|
||||
<string name="screen_room_change_permissions_title">"Oprávnění"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Upravit správce"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"Tuto akci nebudete moci vrátit zpět. Upravujete oprávnění uživatele, tak aby měl stejnou úroveň jako vy."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Přidat správce?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Peakasutajad"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Suhtluskeelu seadmine"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Muuda seadistusi"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Eemalda sõnumid"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Liikmed"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Osalejate kutsumine"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Halda kogukonda"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Halda jututuba"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Liikmete haldus"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Sõnumid ja sisu"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Moderaatorid"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Jututoa nime muutmine"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Jututoa teema muutmine"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Sõnumite saatmine"</string>
|
||||
<string name="screen_room_change_permissions_title">"Õigused"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Muuda peakasutajaid"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"Kuna sa annad teisele kasutajale sinu õigustega võrreldes samad õigused, siis sa ei saa seda muudatust hiljem tagasi pöörata."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Lisame peakasutaja?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Ylläpitäjä"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Porttikieltojen antaminen"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Asetusten muuttaminen"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Viestien poistaminen"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Jäsen"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Ihmisten kutsuminen ja liittymispyyntöjen hyväksyminen"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Tilan hallitseminen"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Huoneiden hallitseminen"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Jäsenien hallinta"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Viestit ja sisältö"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Valvoja"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Huoneen nimen vaihtaminen"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Huoneen aiheen vaihtaminen"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Viestien lähettäminen"</string>
|
||||
<string name="screen_room_change_permissions_title">"Oikeudet"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Muokkaa ylläpitäjiä"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"Et voi peruuttaa tätä toimenpidettä. Ylennät käyttäjän samalle oikeustasolle kuin sinä."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Lisätäänkö ylläpitäjä?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Administrateurs"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Bannir des participants"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Changer les paramètres"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Supprimer des messages"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Membre"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Inviter des personnes"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Gérer l’espace"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Gérer les salons"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Gérer les membres"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Messages et contenus"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Modérateurs"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Changer le nom du salon"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Changer le sujet du salon"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Envoyer des messages"</string>
|
||||
<string name="screen_room_change_permissions_title">"Autorisations"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Modifier les administrateurs"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"Vous ne pourrez pas annuler cette action. Vous êtes en train de promouvoir l’utilisateur pour qu’il ait le même niveau que vous."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Ajouter un administrateur ?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Adminisztrátor"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Emberek kitiltása"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Beállítások módosítása"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Üzenetek eltávolítása"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Tag"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Emberek meghívása"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Tér kezelése"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Szobák kezelése"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Tagok kezelése"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Üzenetek és tartalom"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Moderátor"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Szoba nevének módosítása"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Szoba témájának módosítása"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Üzenetek küldése"</string>
|
||||
<string name="screen_room_change_permissions_title">"Jogosultságok"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Adminisztrátorok szerkesztése"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"Ezt a műveletet nem fogja tudja visszavonni. Ugyanarra a szintre lépteti elő a felhasználót, mint amellyel Ön is rendelkezik."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Adminisztrátor hozzáadása?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Amministratore"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Escludi membri"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Modifica impostazioni"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Rimuovi messaggi"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Membro"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Invita persone"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Gestire lo spazio"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Gestisci le stanze"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Gestisci membri"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Messaggi e contenuti"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Moderatore"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Cambia il nome della stanza"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Cambiare l\'argomento della stanza"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Inviare messaggi"</string>
|
||||
<string name="screen_room_change_permissions_title">"Autorizzazioni"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Modifica amministratori"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"Non potrai annullare questa azione. Stai promuovendo l\'utente al tuo stesso livello di potere."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Aggiungi amministratore?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Administradores"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Banir pessoas"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Alterar configurações"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Remover mensagens"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Membro"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Convidar pessoas"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Gerenciar espaço"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Gerenciar salas"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Gerenciar membros"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Mensagens e conteúdo"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Moderador"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Alterar nome da sala"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Alterar tópico da sala"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Enviar mensagens"</string>
|
||||
<string name="screen_room_change_permissions_title">"Permissões"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Editar administradores"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"Você não poderá desfazer essa ação. Você está promovendo o usuário a ter o mesmo nível de poder que você."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Adicionar administrador?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Только администраторы"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Блокировать людей могут"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Изменить настройки"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Удалить сообщения"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Участник"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Пригласить людей"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Управление пространством"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Управление комнатами"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Список участников"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Сообщения и содержание"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Модератор"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Менять название комнаты могут"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Менять тему комнаты могут"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Отправлять сообщения могут"</string>
|
||||
<string name="screen_room_change_permissions_title">"Разрешения"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Редактировать роль администраторов"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"Вы не сможете отменить это действие. Вы устанавливаете уровень пользователю соответствующий вашему."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Добавить администратора?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"管理員"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"管理黑名單"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"變更設定"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"移除訊息"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"成員"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"邀請夥伴"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"管理空間"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"管理聊天室"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"管理成員"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"訊息與內容"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"版主"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"變更聊天室名稱"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"變更聊天室主題"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"傳送訊息"</string>
|
||||
<string name="screen_room_change_permissions_title">"權限"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"編輯管理員"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"您將無法復原此動作。您正將使用者提昇至與您相同的權力等級。"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"要新增管理員嗎?"</string>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_room_change_permissions_administrators">"Admin"</string>
|
||||
<string name="screen_room_change_permissions_ban_people">"Ban people"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Change settings"</string>
|
||||
<string name="screen_room_change_permissions_delete_messages">"Remove messages"</string>
|
||||
<string name="screen_room_change_permissions_everyone">"Member"</string>
|
||||
<string name="screen_room_change_permissions_invite_people">"Invite people"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Manage space"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Manage rooms"</string>
|
||||
<string name="screen_room_change_permissions_member_moderation">"Manage members"</string>
|
||||
<string name="screen_room_change_permissions_messages_and_content">"Messages and content"</string>
|
||||
<string name="screen_room_change_permissions_moderators">"Moderator"</string>
|
||||
|
|
@ -14,6 +17,7 @@
|
|||
<string name="screen_room_change_permissions_room_name">"Change name"</string>
|
||||
<string name="screen_room_change_permissions_room_topic">"Change topic"</string>
|
||||
<string name="screen_room_change_permissions_send_messages">"Send messages"</string>
|
||||
<string name="screen_room_change_permissions_title">"Permissions"</string>
|
||||
<string name="screen_room_change_role_administrators_title">"Edit Admins"</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_description">"You will not be able to undo this action. You are promoting the user to have the same power level as you."</string>
|
||||
<string name="screen_room_change_role_confirm_add_admin_title">"Add Admin?"</string>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
val itemsBySection = awaitUpdatedItem().itemsBySection
|
||||
assertThat(itemsBySection[RoomPermissionsSection.RoomDetails]).containsExactly(
|
||||
assertThat(itemsBySection[RoomPermissionsSection.EditDetails]).containsExactly(
|
||||
RoomPermissionType.ROOM_NAME,
|
||||
RoomPermissionType.ROOM_AVATAR,
|
||||
RoomPermissionType.ROOM_TOPIC,
|
||||
|
|
@ -62,7 +62,7 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
RoomPermissionType.SEND_EVENTS,
|
||||
RoomPermissionType.REDACT_EVENTS,
|
||||
)
|
||||
assertThat(itemsBySection[RoomPermissionsSection.MembershipModeration]).containsExactly(
|
||||
assertThat(itemsBySection[RoomPermissionsSection.ManageMembers]).containsExactly(
|
||||
RoomPermissionType.INVITE,
|
||||
RoomPermissionType.KICK,
|
||||
RoomPermissionType.BAN,
|
||||
|
|
@ -77,13 +77,13 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
val state = awaitUpdatedItem()
|
||||
assertThat(state.currentPermissions?.roomName).isEqualTo(Admin.powerLevel)
|
||||
assertThat(state.currentPermissions?.roomName).isEqualTo(Moderator.powerLevel)
|
||||
assertThat(state.hasChanges).isFalse()
|
||||
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Moderator))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Admin))
|
||||
|
||||
awaitItem().run {
|
||||
assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel)
|
||||
assertThat(currentPermissions?.roomName).isEqualTo(Admin.powerLevel)
|
||||
assertThat(hasChanges).isTrue()
|
||||
}
|
||||
}
|
||||
|
|
@ -115,8 +115,9 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
invite = Moderator.powerLevel,
|
||||
kick = Moderator.powerLevel,
|
||||
ban = Moderator.powerLevel,
|
||||
stateDefault = Moderator.powerLevel,
|
||||
redactEvents = Moderator.powerLevel,
|
||||
sendEvents = Moderator.powerLevel,
|
||||
eventsDefault = Moderator.powerLevel,
|
||||
roomName = Moderator.powerLevel,
|
||||
roomAvatar = Moderator.powerLevel,
|
||||
roomTopic = Moderator.powerLevel,
|
||||
|
|
@ -141,14 +142,14 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
val state = awaitUpdatedItem()
|
||||
assertThat(state.currentPermissions?.roomName).isEqualTo(Admin.powerLevel)
|
||||
assertThat(state.currentPermissions?.roomName).isEqualTo(Moderator.powerLevel)
|
||||
assertThat(state.hasChanges).isFalse()
|
||||
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Moderator))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_AVATAR, SelectableRole.Moderator))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_TOPIC, SelectableRole.Moderator))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.SEND_EVENTS, SelectableRole.Moderator))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.REDACT_EVENTS, SelectableRole.Everyone))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Admin))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_AVATAR, SelectableRole.Admin))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_TOPIC, SelectableRole.Admin))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.SEND_EVENTS, SelectableRole.Admin))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.REDACT_EVENTS, SelectableRole.Admin))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.KICK, SelectableRole.Admin))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.BAN, SelectableRole.Admin))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.INVITE, SelectableRole.Admin))
|
||||
|
|
@ -160,16 +161,16 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Loading)
|
||||
assertThat(awaitItem().hasChanges).isFalse()
|
||||
awaitItem().run {
|
||||
assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel)
|
||||
assertThat(currentPermissions?.roomName).isEqualTo(Admin.powerLevel)
|
||||
assertThat(saveAction).isEqualTo(AsyncAction.Success(true))
|
||||
}
|
||||
assertThat(analyticsService.capturedEvents).containsExactlyElementsIn(
|
||||
listOf(
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsRoomName, RoomModeration.Role.Moderator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsRoomAvatar, RoomModeration.Role.Moderator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsRoomTopic, RoomModeration.Role.Moderator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, RoomModeration.Role.Moderator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsRedactMessages, RoomModeration.Role.User),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsRoomName, RoomModeration.Role.Administrator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsRoomAvatar, RoomModeration.Role.Administrator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsRoomTopic, RoomModeration.Role.Administrator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, RoomModeration.Role.Administrator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsRedactMessages, RoomModeration.Role.Administrator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsKickMembers, RoomModeration.Role.Administrator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsBanMembers, RoomModeration.Role.Administrator),
|
||||
RoomModeration(RoomModeration.Action.ChangePermissionsInviteUsers, RoomModeration.Role.Administrator),
|
||||
|
|
@ -206,17 +207,17 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
val state = awaitUpdatedItem()
|
||||
assertThat(state.currentPermissions?.roomName).isEqualTo(Admin.powerLevel)
|
||||
assertThat(state.currentPermissions?.roomName).isEqualTo(Moderator.powerLevel)
|
||||
assertThat(state.hasChanges).isFalse()
|
||||
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Moderator))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Admin))
|
||||
assertThat(awaitItem().hasChanges).isTrue()
|
||||
|
||||
state.eventSink(ChangeRoomPermissionsEvent.Save)
|
||||
|
||||
assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Loading)
|
||||
awaitItem().run {
|
||||
assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel)
|
||||
assertThat(currentPermissions?.roomName).isEqualTo(Admin.powerLevel)
|
||||
// Couldn't save the changes, so they're still pending
|
||||
assertThat(hasChanges).isTrue()
|
||||
assertThat(saveAction).isInstanceOf(AsyncAction.Failure::class.java)
|
||||
|
|
@ -224,7 +225,7 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions)
|
||||
awaitItem().run {
|
||||
assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel)
|
||||
assertThat(currentPermissions?.roomName).isEqualTo(Admin.powerLevel)
|
||||
assertThat(saveAction).isEqualTo(AsyncAction.Uninitialized)
|
||||
assertThat(hasChanges).isTrue()
|
||||
}
|
||||
|
|
@ -238,7 +239,7 @@ class ChangeRoomPermissionsPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
val state = awaitUpdatedItem()
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Moderator))
|
||||
state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Admin))
|
||||
assertThat(awaitItem().hasChanges).isTrue()
|
||||
|
||||
state.eventSink(ChangeRoomPermissionsEvent.Exit)
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class ChangeRoomPermissionsViewTest {
|
|||
state = aChangeRoomPermissionsState(
|
||||
itemsBySection = persistentMapOf(
|
||||
// Makes sure there is only one item to click on
|
||||
RoomPermissionsSection.RoomDetails to persistentListOf(RoomPermissionType.ROOM_NAME)
|
||||
RoomPermissionsSection.EditDetails to persistentListOf(RoomPermissionType.ROOM_NAME)
|
||||
),
|
||||
eventSink = recorder,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEn
|
|||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
|
||||
class FakeRolesAndPermissionsEntryPoint : RolesAndPermissionsEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, callback: RolesAndPermissionsEntryPoint.Callback): Node {
|
||||
lambdaError()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -349,7 +349,16 @@ class RoomDetailsFlowNode(
|
|||
}
|
||||
|
||||
is NavTarget.AdminSettings -> {
|
||||
rolesAndPermissionsEntryPoint.createNode(this, buildContext)
|
||||
val callback = object : RolesAndPermissionsEntryPoint.Callback {
|
||||
override fun onDone() {
|
||||
backstack.pop()
|
||||
}
|
||||
}
|
||||
rolesAndPermissionsEntryPoint.createNode(
|
||||
parentNode = this,
|
||||
buildContext = buildContext,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
NavTarget.PinnedMessagesList -> {
|
||||
val params = MessagesEntryPoint.Params(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import dev.zacsweers.metro.Inject
|
||||
import im.vector.app.features.analytics.plan.Interaction
|
||||
import io.element.android.features.knockrequests.api.KnockRequestPermissions
|
||||
import io.element.android.features.knockrequests.api.knockRequestPermissions
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomEvent
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomState
|
||||
|
|
@ -26,6 +27,7 @@ import io.element.android.features.roomcall.api.RoomCallState
|
|||
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter
|
||||
import io.element.android.features.roomdetailsedit.api.RoomDetailsEditPermissions
|
||||
import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions
|
||||
import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions
|
||||
import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions
|
||||
import io.element.android.libraries.androidutils.clipboard.ClipboardHelper
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
|
|
@ -119,7 +121,10 @@ class RoomDetailsPresenter(
|
|||
room.knockRequestsFlow.collect { value = it.size }
|
||||
}
|
||||
val canShowKnockRequests by remember {
|
||||
derivedStateOf { isKnockRequestsEnabled && permissions.canManageKnockRequests && joinRule == JoinRule.Knock }
|
||||
derivedStateOf { isKnockRequestsEnabled && permissions.knockRequestsPermissions.hasAny && joinRule == JoinRule.Knock }
|
||||
}
|
||||
val canShowSecurityAndPrivacy by remember {
|
||||
derivedStateOf { !isDm && permissions.securityAndPrivacyPermissions.hasAny(isSpace = false, joinRule = joinRule) }
|
||||
}
|
||||
val isDeveloperModeEnabled by remember {
|
||||
appPreferencesStore.isDeveloperModeEnabledFlow()
|
||||
|
|
@ -186,7 +191,7 @@ class RoomDetailsPresenter(
|
|||
snackbarMessage = snackbarMessage,
|
||||
canShowKnockRequests = canShowKnockRequests,
|
||||
knockRequestsCount = knockRequestsCount,
|
||||
canShowSecurityAndPrivacy = !isDm && permissions.canEditSecurityAndPrivacy,
|
||||
canShowSecurityAndPrivacy = canShowSecurityAndPrivacy,
|
||||
hasMemberVerificationViolations = hasMemberVerificationViolations,
|
||||
canReportRoom = canReportRoom,
|
||||
isTombstoned = roomInfo.successorRoom != null,
|
||||
|
|
@ -221,9 +226,9 @@ class RoomDetailsPresenter(
|
|||
private data class Permissions(
|
||||
val canInvite: Boolean = false,
|
||||
val editDetailsPermissions: RoomDetailsEditPermissions = RoomDetailsEditPermissions.DEFAULT,
|
||||
val canManageKnockRequests: Boolean = false,
|
||||
val knockRequestsPermissions: KnockRequestPermissions = KnockRequestPermissions.DEFAULT,
|
||||
val securityAndPrivacyPermissions: SecurityAndPrivacyPermissions = SecurityAndPrivacyPermissions.DEFAULT,
|
||||
val canEditRolesAndPermissions: Boolean = false,
|
||||
val canEditSecurityAndPrivacy: Boolean = false,
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
@ -232,9 +237,9 @@ class RoomDetailsPresenter(
|
|||
Permissions(
|
||||
canInvite = perms.canOwnUserInvite(),
|
||||
editDetailsPermissions = perms.roomDetailsEditPermissions(),
|
||||
canManageKnockRequests = perms.knockRequestPermissions().hasAny,
|
||||
knockRequestsPermissions = perms.knockRequestPermissions(),
|
||||
canEditRolesAndPermissions = perms.canEditRolesAndPermissions(),
|
||||
canEditSecurityAndPrivacy = perms.securityAndPrivacyPermissions().hasAny,
|
||||
securityAndPrivacyPermissions = perms.securityAndPrivacyPermissions(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ fun RoomDetailsEditView(
|
|||
} else {
|
||||
AvatarType.Room()
|
||||
},
|
||||
enabled = state.canChangeAvatar,
|
||||
onAvatarClick = ::onAvatarClick,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
package io.element.android.features.securityandprivacy.api
|
||||
|
||||
import io.element.android.libraries.matrix.api.room.StateEventType
|
||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions
|
||||
|
||||
data class SecurityAndPrivacyPermissions(
|
||||
|
|
@ -17,10 +18,19 @@ data class SecurityAndPrivacyPermissions(
|
|||
val canChangeEncryption: Boolean,
|
||||
val canChangeRoomVisibility: Boolean,
|
||||
) {
|
||||
val hasAny = canChangeRoomAccess ||
|
||||
canChangeHistoryVisibility ||
|
||||
canChangeEncryption ||
|
||||
canChangeRoomVisibility
|
||||
fun hasAny(isSpace: Boolean, joinRule: JoinRule?): Boolean {
|
||||
val canChangeRoomVisibility = when (joinRule) {
|
||||
is JoinRule.Public,
|
||||
is JoinRule.Knock,
|
||||
is JoinRule.KnockRestricted -> canChangeRoomVisibility
|
||||
else -> false
|
||||
}
|
||||
return if (isSpace) {
|
||||
canChangeRoomAccess || canChangeRoomVisibility
|
||||
} else {
|
||||
canChangeRoomAccess || canChangeRoomVisibility || canChangeHistoryVisibility || canChangeEncryption
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DEFAULT = SecurityAndPrivacyPermissions(
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ package io.element.android.features.securityandprivacy.impl
|
|||
import android.os.Parcelable
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
|
|
@ -19,6 +22,7 @@ import dev.zacsweers.metro.Assisted
|
|||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint
|
||||
import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions
|
||||
import io.element.android.features.securityandprivacy.impl.editroomaddress.EditRoomAddressNode
|
||||
import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyNode
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
|
|
@ -26,6 +30,12 @@ import io.element.android.libraries.architecture.BaseFlowNode
|
|||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.use
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@ContributesNode(RoomScope::class)
|
||||
|
|
@ -33,6 +43,7 @@ import kotlinx.parcelize.Parcelize
|
|||
class SecurityAndPrivacyFlowNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val room: JoinedRoom,
|
||||
) : BaseFlowNode<SecurityAndPrivacyFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
initialElement = NavTarget.SecurityAndPrivacy,
|
||||
|
|
@ -52,6 +63,24 @@ class SecurityAndPrivacyFlowNode(
|
|||
private val callback: SecurityAndPrivacyEntryPoint.Callback = callback()
|
||||
private val navigator = BackstackSecurityAndPrivacyNavigator(callback, backstack)
|
||||
|
||||
override fun onBuilt() {
|
||||
super.onBuilt()
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||
room.roomInfoFlow
|
||||
.map { roomInfo ->
|
||||
room.roomPermissions().use(false) { perms ->
|
||||
perms.securityAndPrivacyPermissions().hasAny(roomInfo.isSpace, roomInfo.joinRule)
|
||||
}
|
||||
}
|
||||
.filter { canEdit -> !canEdit }
|
||||
.first()
|
||||
// If the user can no longer edit security and privacy, exit the flow
|
||||
callback.onDone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||
return when (navTarget) {
|
||||
NavTarget.SecurityAndPrivacy -> {
|
||||
|
|
|
|||
|
|
@ -182,9 +182,20 @@ class SecurityAndPrivacyPresenter(
|
|||
eventSink = ::handleEvent,
|
||||
)
|
||||
|
||||
// If the history visibility is not available for the current access, use the fallback.
|
||||
LaunchedEffect(state.availableHistoryVisibilities) {
|
||||
if (editedSettings.historyVisibility !in state.availableHistoryVisibilities) {
|
||||
// Revert changes that the user is not allowed to make anymore
|
||||
LaunchedEffect(permissions, state.editedSettings.roomAccess) {
|
||||
if (!state.showRoomAccessSection) {
|
||||
editedRoomAccess = savedSettings.roomAccess
|
||||
}
|
||||
if (!state.showEncryptionSection) {
|
||||
editedIsEncrypted = savedSettings.isEncrypted
|
||||
}
|
||||
if (!state.showRoomVisibilitySections) {
|
||||
editedVisibleInRoomDirectory = savedSettings.isVisibleInRoomDirectory
|
||||
}
|
||||
if (!state.showHistoryVisibilitySection) {
|
||||
editedHistoryVisibility = savedSettings.historyVisibility
|
||||
} else if (editedSettings.historyVisibility !in state.availableHistoryVisibilities) {
|
||||
editedHistoryVisibility = editedSettings.historyVisibility.fallback()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ class SecurityAndPrivacyPresenterTest {
|
|||
navigator = navigator,
|
||||
)
|
||||
presenter.test {
|
||||
skipItems(2)
|
||||
skipItems(1)
|
||||
with(awaitItem()) {
|
||||
assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly)
|
||||
eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone))
|
||||
|
|
@ -312,7 +312,7 @@ class SecurityAndPrivacyPresenterTest {
|
|||
)
|
||||
val presenter = createSecurityAndPrivacyPresenter(room = room)
|
||||
presenter.test {
|
||||
skipItems(2)
|
||||
skipItems(1)
|
||||
with(awaitItem()) {
|
||||
assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly)
|
||||
eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone))
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ dependencies {
|
|||
implementation(projects.libraries.previewutils)
|
||||
implementation(projects.features.securityandprivacy.api)
|
||||
implementation(projects.features.rolesandpermissions.api)
|
||||
implementation(projects.features.roomdetailsedit.api)
|
||||
api(projects.features.space.api)
|
||||
|
||||
testCommonDependencies(libs, true)
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class SpaceFlowNode(
|
|||
data object Root : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object Settings : NavTarget
|
||||
data class Settings(val initialTarget: SpaceSettingsFlowNode.NavTarget = SpaceSettingsFlowNode.NavTarget.Root) : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object Leave : NavTarget
|
||||
|
|
@ -89,7 +89,7 @@ class SpaceFlowNode(
|
|||
}
|
||||
|
||||
override fun navigateToRolesAndPermissions() {
|
||||
// TODO
|
||||
backstack.push(NavTarget.Settings(SpaceSettingsFlowNode.NavTarget.RolesAndPermissions))
|
||||
}
|
||||
}
|
||||
createNode<LeaveSpaceNode>(buildContext, listOf(callback))
|
||||
|
|
@ -101,7 +101,7 @@ class SpaceFlowNode(
|
|||
}
|
||||
|
||||
override fun navigateToSpaceSettings() {
|
||||
backstack.push(NavTarget.Settings)
|
||||
backstack.push(NavTarget.Settings())
|
||||
}
|
||||
|
||||
override fun navigateToRoomMemberList() {
|
||||
|
|
@ -114,8 +114,10 @@ class SpaceFlowNode(
|
|||
}
|
||||
createNode<SpaceNode>(buildContext, listOf(callback))
|
||||
}
|
||||
NavTarget.Settings -> {
|
||||
is NavTarget.Settings -> {
|
||||
val callback = object : SpaceSettingsFlowNode.Callback {
|
||||
override fun initialTarget() = navTarget.initialTarget
|
||||
|
||||
override fun navigateToSpaceMembers() {
|
||||
callback.navigateToRoomMemberList()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,8 +132,7 @@ fun LeaveSpaceView(
|
|||
state.eventSink(LeaveSpaceEvents.LeaveSpace)
|
||||
},
|
||||
onCancel = onCancel,
|
||||
// TODO enable when navigation is ready
|
||||
showRolesAndPermissionsButton = false, // state.isLastAdmin,
|
||||
showRolesAndPermissionsButton = state.isLastAdmin,
|
||||
onRolesAndPermissionsClick = onRolesAndPermissionsClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,17 +11,20 @@ package io.element.android.features.space.impl.root
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
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.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
|
||||
|
|
@ -31,8 +34,10 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
|
|||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
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.BaseRoom
|
||||
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 +55,7 @@ import kotlin.jvm.optionals.getOrNull
|
|||
@Inject
|
||||
class SpacePresenter(
|
||||
private val spaceRoomList: SpaceRoomList,
|
||||
private val room: BaseRoom,
|
||||
private val client: MatrixClient,
|
||||
private val seenInvitesStore: SeenInvitesStore,
|
||||
private val joinRoom: JoinRoom,
|
||||
|
|
@ -82,10 +88,17 @@ class SpacePresenter(
|
|||
}
|
||||
}.collectAsState()
|
||||
|
||||
val permissions by room.permissionsAsState(SpaceSettingsPermissions.DEFAULT) { perms ->
|
||||
perms.spaceSettingsPermissions()
|
||||
}
|
||||
val isSpaceSettingsEnabled by remember {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.SpaceSettings)
|
||||
}.collectAsState(false)
|
||||
|
||||
val roomInfo by room.roomInfoFlow.collectAsState()
|
||||
val canAccessSpaceSettings by remember {
|
||||
derivedStateOf { isSpaceSettingsEnabled && permissions.hasAny(roomInfo.joinRule) }
|
||||
}
|
||||
val currentSpace by spaceRoomList.currentSpaceFlow.collectAsState()
|
||||
val (joinActions, setJoinActions) = remember { mutableStateOf(emptyMap<RoomId, AsyncAction<Unit>>()) }
|
||||
|
||||
|
|
@ -136,7 +149,7 @@ class SpacePresenter(
|
|||
joinActions = joinActions.toImmutableMap(),
|
||||
acceptDeclineInviteState = acceptDeclineInviteState,
|
||||
topicViewerState = topicViewerState,
|
||||
canAccessSpaceSettings = isSpaceSettingsEnabled,
|
||||
canAccessSpaceSettings = canAccessSpaceSettings,
|
||||
eventSink = ::handleEvent,
|
||||
)
|
||||
}
|
||||
|
|
@ -150,7 +163,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)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import dev.zacsweers.metro.Assisted
|
|||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEntryPoint
|
||||
import io.element.android.features.roomdetailsedit.api.RoomDetailsEditEntryPoint
|
||||
import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint
|
||||
import io.element.android.features.space.impl.di.SpaceFlowScope
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
|
|
@ -35,15 +36,17 @@ class SpaceSettingsFlowNode(
|
|||
@Assisted plugins: List<Plugin>,
|
||||
private val securityAndPrivacyEntryPoint: SecurityAndPrivacyEntryPoint,
|
||||
private val rolesAndPermissionsEntryPoint: RolesAndPermissionsEntryPoint,
|
||||
private val roomDetailsEditEntryPoint: RoomDetailsEditEntryPoint
|
||||
) : BaseFlowNode<SpaceSettingsFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
initialElement = NavTarget.Root,
|
||||
initialElement = initialElement(plugins),
|
||||
savedStateMap = buildContext.savedStateMap,
|
||||
),
|
||||
buildContext = buildContext,
|
||||
plugins = plugins,
|
||||
) {
|
||||
interface Callback : Plugin {
|
||||
fun initialTarget(): NavTarget = NavTarget.Root
|
||||
fun navigateToSpaceMembers()
|
||||
fun startLeaveSpaceFlow()
|
||||
fun closeSettings()
|
||||
|
|
@ -53,6 +56,9 @@ class SpaceSettingsFlowNode(
|
|||
@Parcelize
|
||||
data object Root : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object EditDetails : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object SecurityAndPrivacy : NavTarget
|
||||
|
||||
|
|
@ -71,7 +77,7 @@ class SpaceSettingsFlowNode(
|
|||
}
|
||||
|
||||
override fun navigateToEditDetails() {
|
||||
// TODO
|
||||
backstack.push(NavTarget.EditDetails)
|
||||
}
|
||||
|
||||
override fun navigateToSpaceMembers() {
|
||||
|
|
@ -108,9 +114,21 @@ class SpaceSettingsFlowNode(
|
|||
)
|
||||
}
|
||||
is NavTarget.RolesAndPermissions -> {
|
||||
val callback = object : RolesAndPermissionsEntryPoint.Callback {
|
||||
override fun onDone() {
|
||||
backstack.pop()
|
||||
}
|
||||
}
|
||||
rolesAndPermissionsEntryPoint.createNode(
|
||||
parentNode = this,
|
||||
buildContext = buildContext,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
NavTarget.EditDetails -> {
|
||||
roomDetailsEditEntryPoint.createNode(
|
||||
parentNode = this,
|
||||
buildContext = buildContext,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -121,3 +139,7 @@ class SpaceSettingsFlowNode(
|
|||
BackstackView(modifier)
|
||||
}
|
||||
}
|
||||
|
||||
fun initialElement(plugins: List<Plugin>): SpaceSettingsFlowNode.NavTarget {
|
||||
return plugins.callback<SpaceSettingsFlowNode.Callback>().initialTarget()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.roomdetailsedit.api.roomDetailsEditPermissions
|
||||
import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions
|
||||
import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions
|
||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.canEditRolesAndPermissions
|
||||
|
||||
data class SpaceSettingsPermissions(
|
||||
val editDetailsPermissions: RoomDetailsEditPermissions,
|
||||
val canEditRolesAndPermissions: Boolean,
|
||||
val securityAndPrivacyPermissions: SecurityAndPrivacyPermissions,
|
||||
) {
|
||||
fun hasAny(joinRule: JoinRule?): Boolean {
|
||||
return editDetailsPermissions.hasAny ||
|
||||
canEditRolesAndPermissions ||
|
||||
securityAndPrivacyPermissions.hasAny(isSpace = true, joinRule = joinRule)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DEFAULT = SpaceSettingsPermissions(
|
||||
editDetailsPermissions = RoomDetailsEditPermissions.DEFAULT,
|
||||
canEditRolesAndPermissions = false,
|
||||
securityAndPrivacyPermissions = SecurityAndPrivacyPermissions.DEFAULT,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun RoomPermissions.spaceSettingsPermissions(): SpaceSettingsPermissions {
|
||||
return SpaceSettingsPermissions(
|
||||
editDetailsPermissions = roomDetailsEditPermissions(),
|
||||
canEditRolesAndPermissions = canEditRolesAndPermissions(),
|
||||
securityAndPrivacyPermissions = securityAndPrivacyPermissions(),
|
||||
)
|
||||
}
|
||||
|
|
@ -10,11 +10,13 @@ package io.element.android.features.space.impl.settings
|
|||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
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 +25,22 @@ 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()
|
||||
}
|
||||
val showSecurityAndPrivacy by remember {
|
||||
derivedStateOf { permissions.securityAndPrivacyPermissions.hasAny(isSpace = false, joinRule = roomInfo.joinRule) }
|
||||
}
|
||||
|
||||
return SpaceSettingsState(
|
||||
roomId = room.roomId,
|
||||
name = roomInfo.name.orEmpty(),
|
||||
canonicalAlias = roomInfo.canonicalAlias,
|
||||
avatarUrl = roomInfo.avatarUrl,
|
||||
memberCount = roomInfo.activeMembersCount,
|
||||
showRolesAndPermissions = isUserAdmin,
|
||||
showSecurityAndPrivacy = isUserAdmin,
|
||||
canEditDetails = permissions.editDetailsPermissions.hasAny,
|
||||
showRolesAndPermissions = permissions.canEditRolesAndPermissions,
|
||||
showSecurityAndPrivacy = showSecurityAndPrivacy,
|
||||
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,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
|||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
|
||||
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
|
||||
import io.element.android.libraries.matrix.api.room.BaseRoom
|
||||
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.spaces.SpaceRoomList
|
||||
|
|
@ -31,7 +32,9 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
|||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
|
||||
import io.element.android.libraries.matrix.test.room.join.FakeJoinRoom
|
||||
import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions
|
||||
import io.element.android.libraries.matrix.test.spaces.FakeSpaceRoomList
|
||||
import io.element.android.libraries.previewutils.room.aSpaceRoom
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
|
|
@ -71,8 +74,25 @@ class SpacePresenterTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `present - canAccessSpaceSettings when space settings ff is enabled`() = runTest {
|
||||
fun `present - canAccessSpaceSettings false when space settings ff is enabled but no permissions`() = runTest {
|
||||
val presenter = createSpacePresenter(spaceSettingsEnabled = true)
|
||||
presenter.test {
|
||||
val state = awaitItem()
|
||||
assertThat(state.canAccessSpaceSettings).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - canAccessSpaceSettings true when space settings ff is enabled and has permissions`() = runTest {
|
||||
val room = FakeBaseRoom(
|
||||
roomPermissions = FakeRoomPermissions(
|
||||
canSendState = { true }
|
||||
)
|
||||
)
|
||||
val presenter = createSpacePresenter(
|
||||
room = room,
|
||||
spaceSettingsEnabled = true,
|
||||
)
|
||||
presenter.test {
|
||||
skipItems(1)
|
||||
val state = awaitItem()
|
||||
|
|
@ -335,7 +355,10 @@ class SpacePresenterTest {
|
|||
|
||||
private fun TestScope.createSpacePresenter(
|
||||
client: MatrixClient = FakeMatrixClient(),
|
||||
spaceRoomList: SpaceRoomList = FakeSpaceRoomList(),
|
||||
room: BaseRoom = FakeBaseRoom(),
|
||||
spaceRoomList: SpaceRoomList = FakeSpaceRoomList(
|
||||
paginateResult = { Result.success(Unit) }
|
||||
),
|
||||
seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(),
|
||||
joinRoom: JoinRoom = FakeJoinRoom(
|
||||
lambda = { _, _, _ -> Result.success(Unit) },
|
||||
|
|
@ -345,6 +368,7 @@ class SpacePresenterTest {
|
|||
): SpacePresenter {
|
||||
return SpacePresenter(
|
||||
client = client,
|
||||
room = room,
|
||||
spaceRoomList = spaceRoomList,
|
||||
seenInvitesStore = seenInvitesStore,
|
||||
joinRoom = joinRoom,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue