Merge pull request #5908 from element-hq/feature/fga/space_settings_iteration
Change : space settings iteration
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -10,8 +10,11 @@ package io.element.android.libraries.architecture
|
||||
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.bumble.appyx.core.plugin.plugins
|
||||
|
||||
inline fun <reified I : Plugin> Node.callback(): I {
|
||||
return requireNotNull(plugins<I>().singleOrNull()) { "Make sure to actually pass a Callback plugin to your node" }
|
||||
return plugins.callback()
|
||||
}
|
||||
|
||||
inline fun <reified I : Plugin> List<Plugin>.callback(): I {
|
||||
return requireNotNull(filterIsInstance<I>().singleOrNull()) { "Make sure to actually pass a Callback plugin to your node" }
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ import kotlinx.coroutines.flow.map
|
||||
* Provides information about the permissions of users in a room.
|
||||
*/
|
||||
interface RoomPermissions : AutoCloseable {
|
||||
/**
|
||||
* Returns true if the current user is able to ban from the room.
|
||||
*/
|
||||
fun canOwnUserBan(): Boolean
|
||||
|
||||
/**
|
||||
@@ -31,7 +34,7 @@ interface RoomPermissions : AutoCloseable {
|
||||
fun canOwnUserInvite(): Boolean
|
||||
|
||||
/**
|
||||
* Returns true if the current user is able to kick in the room.
|
||||
* Returns true if the current user is able to kick from the room.
|
||||
*/
|
||||
fun canOwnUserKick(): Boolean
|
||||
|
||||
@@ -128,10 +131,18 @@ interface RoomPermissions : AutoCloseable {
|
||||
fun canUserTriggerRoomNotification(userId: UserId): Boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current user can edit roles and permissions in the room ie. can send
|
||||
* a power levels state event.
|
||||
*/
|
||||
fun RoomPermissions.canEditRolesAndPermissions(): Boolean {
|
||||
return canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current user can start a call in the room ie. can send
|
||||
* a call member state event.
|
||||
*/
|
||||
fun RoomPermissions.canCall(): Boolean {
|
||||
return canOwnUserSendState(StateEventType.CALL_MEMBER)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ data class RoomPowerLevelsValues(
|
||||
val ban: Long,
|
||||
val invite: Long,
|
||||
val kick: Long,
|
||||
val sendEvents: Long,
|
||||
val eventsDefault: Long,
|
||||
val stateDefault: Long,
|
||||
val redactEvents: Long,
|
||||
val roomName: Long,
|
||||
val roomAvatar: Long,
|
||||
|
||||
@@ -397,10 +397,12 @@ class JoinedRustRoom(
|
||||
invite = roomPowerLevelsValues.invite,
|
||||
kick = roomPowerLevelsValues.kick,
|
||||
redact = roomPowerLevelsValues.redactEvents,
|
||||
eventsDefault = roomPowerLevelsValues.sendEvents,
|
||||
stateDefault = roomPowerLevelsValues.stateDefault,
|
||||
eventsDefault = roomPowerLevelsValues.eventsDefault,
|
||||
roomName = roomPowerLevelsValues.roomName,
|
||||
roomAvatar = roomPowerLevelsValues.roomAvatar,
|
||||
roomTopic = roomPowerLevelsValues.roomTopic,
|
||||
spaceChild = roomPowerLevelsValues.spaceChild,
|
||||
)
|
||||
innerRoom.applyPowerLevelChanges(changes)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ object RoomPowerLevelsValuesMapper {
|
||||
ban = values.ban,
|
||||
invite = values.invite,
|
||||
kick = values.kick,
|
||||
sendEvents = values.eventsDefault,
|
||||
eventsDefault = values.eventsDefault,
|
||||
stateDefault = values.stateDefault,
|
||||
redactEvents = values.redact,
|
||||
roomName = values.roomName,
|
||||
roomAvatar = values.roomAvatar,
|
||||
|
||||
@@ -25,11 +25,11 @@ fun defaultFfiRoomPowerLevelValues() = RoomPowerLevelsValues(
|
||||
invite = 0,
|
||||
kick = 50,
|
||||
eventsDefault = 0,
|
||||
stateDefault = 50,
|
||||
redact = 50,
|
||||
roomName = 100,
|
||||
roomAvatar = 100,
|
||||
roomTopic = 100,
|
||||
stateDefault = 0,
|
||||
roomName = 50,
|
||||
roomAvatar = 50,
|
||||
roomTopic = 50,
|
||||
spaceChild = 50,
|
||||
usersDefault = 0,
|
||||
spaceChild = 100,
|
||||
)
|
||||
|
||||
@@ -37,8 +37,9 @@ class RoomPowerLevelsValuesMapperTest {
|
||||
ban = 1,
|
||||
invite = 2,
|
||||
kick = 3,
|
||||
sendEvents = 5,
|
||||
redactEvents = 4,
|
||||
eventsDefault = 5,
|
||||
stateDefault = 6,
|
||||
roomName = 8,
|
||||
roomAvatar = 9,
|
||||
roomTopic = 10,
|
||||
|
||||
@@ -211,10 +211,11 @@ fun defaultRoomPowerLevelValues() = RoomPowerLevelsValues(
|
||||
ban = 50,
|
||||
invite = 0,
|
||||
kick = 50,
|
||||
sendEvents = 0,
|
||||
eventsDefault = 0,
|
||||
stateDefault = 50,
|
||||
redactEvents = 50,
|
||||
roomName = 100,
|
||||
roomAvatar = 100,
|
||||
roomTopic = 100,
|
||||
spaceChild = 100,
|
||||
roomName = 50,
|
||||
roomAvatar = 50,
|
||||
roomTopic = 50,
|
||||
spaceChild = 50,
|
||||
)
|
||||
|
||||
@@ -56,6 +56,7 @@ fun EditableAvatarView(
|
||||
avatarType: AvatarType,
|
||||
onAvatarClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
) {
|
||||
val a11yAvatar = stringResource(CommonStrings.a11y_avatar)
|
||||
val editIconRadius = 15.dp
|
||||
@@ -66,6 +67,7 @@ fun EditableAvatarView(
|
||||
.wrapContentSize()
|
||||
.size(height = parentHeight, width = parentWidth)
|
||||
.clickable(
|
||||
enabled = enabled,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
onClickLabel = stringResource(CommonStrings.a11y_edit_avatar),
|
||||
onClick = onAvatarClick,
|
||||
|
||||
@@ -453,10 +453,6 @@ Opravdu chcete pokračovat?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Vaše zpráva nebyla odeslána, protože%1$s neověřil(a) všechna zařízení"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Jedno nebo více vašich zařízení není ověřeno. Zprávu můžete přesto odeslat, nebo ji můžete prozatím zrušit a zkusit to znovu později, až ověříte všechna svá zařízení."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Vaše zpráva nebyla odeslána, protože jste neověřili jedno nebo více zařízení"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Změnit nastavení"</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_title">"Oprávnění"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Upravit správce nebo vlastníky"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Nahrání média se nezdařilo, zkuste to prosím znovu."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Nepodařilo se načíst údaje o uživateli"</string>
|
||||
|
||||
@@ -445,10 +445,6 @@ Er du sikker på, at du vil fortsætte?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Din besked blev ikke sendt, fordi %1$s ikke har bekræftet alle enheder"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"En eller flere af dine enheder er ikke verificeret. Du kan sende beskeden alligevel, eller du kan annullere for nu og prøve igen senere, når du har verificeret alle dine enheder."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Din besked blev ikke sendt, fordi du ikke har verificeret en eller flere af dine enheder"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Skift indstillinger"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Administrér gruppe"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Administrer rum"</string>
|
||||
<string name="screen_room_change_permissions_title">"Tilladelser"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Rediger administratorer eller ejere"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Det lykkedes ikke at behandle medier til upload. Prøv venligst igen."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Kunne ikke hente brugeroplysninger"</string>
|
||||
|
||||
@@ -483,10 +483,6 @@ Kas sa oled kindel, et soovid jätkata?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Sinu sõnum on saatmata, kuna %1$s pole verifitseerinud kõiki oma seadmeid"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Üks või enam sinu seadet on verifitseerimata. Sa võid sõnumi ikkagi ära saata või katkestad saatmise ning proovid uuesti, kui oled kõik oma seadmed verifitseerinud."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Kuna sul on üks või enam verifitseerimata seadet, siis sinu sõnum jäi saatmata"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Muuda seadistusi"</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_title">"Õigused"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Muuda peakasutajaid või omanikke"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Meediafaili töötlemine enne üleslaadimist ei õnnestunud. Palun proovi uuesti."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Kasutaja andmete laadimine ei õnnestunud"</string>
|
||||
|
||||
@@ -446,10 +446,6 @@ Haluatko varmasti jatkaa?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Viestiäsi ei lähetetty, koska %1$s ei ole vahvistanut kaikkia laitteitaan."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Yksi tai useampi laitteistasi on vahvistamaton. Voit lähettää viestin silti tai peruuttaa sen toistaiseksi ja yrittää uudelleen myöhemmin, kun olet vahvistanut kaikki laitteesi."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Viestiäsi ei lähetetty, koska et ole vahvistanut yhtä tai useampaa laitettasi."</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Asetusten muuttaminen"</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_title">"Oikeudet"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Muokkaa ylläpitäjiä tai omistajia"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Median käsittely epäonnistui, yritä uudelleen."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Käyttäjän tietojen hakeminen epäonnistui"</string>
|
||||
|
||||
@@ -453,10 +453,6 @@ Raison : %1$s."</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Votre message n’a pas été envoyé car %1$s n’a pas vérifié tous ses appareils"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Un ou plusieurs de vos appareils ne sont pas vérifiés. Vous pouvez quand même envoyer le message, ou vous pouvez annuler et réessayer plus tard après avoir vérifié tous vos appareils."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Votre message n’a pas été envoyé car vous n’avez pas vérifié tous vos appareils"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Changer les paramètres"</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_title">"Autorisations"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Modifier les administrateurs ou les propriétaires"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Échec du traitement des médias à télécharger, veuillez réessayer."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Impossible de récupérer les détails de l’utilisateur"</string>
|
||||
|
||||
@@ -492,10 +492,6 @@ Jeste li sigurni da želite nastaviti?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Vaša poruka nije poslana jer %1$s nije potvrdio sve uređaje"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Jedan vaš uređaj ili više njih nije potvrđeno. Možete svejedno poslati poruku ili za sada otkazati i pokušati ponovno poslije nakon što potvrdite sve svoje uređaje."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Vaša poruka nije poslana jer niste potvrdili jedan svoj uređaj ili više njih"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Promijeni postavke"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Upravljaj prostorom"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Upravljaj sobama"</string>
|
||||
<string name="screen_room_change_permissions_title">"Dopuštenja"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Uredi administratore ili vlasnike"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Prijenos medija za obradu nije uspio, pokušajte ponovno."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Nije moguće dohvatiti korisničke podatke"</string>
|
||||
|
||||
@@ -445,10 +445,6 @@ Biztos, hogy folytatja?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Az üzenet nem lett elküldve, mert %1$s nem ellenőrizte az összes eszközét"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Egy vagy több eszköze nincs ellenőrizve. Így is elküldheti az üzenetet, vagy egyelőre megszakíthatja, és később, az összes eszköz ellenőrzése után újrapróbálkozhat."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Az üzenet nem lett elküldve, mert egy vagy több eszközét nem ellenőrizte"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Beállítások módosítá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_title">"Jogosultságok"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Adminisztrátorok vagy tulajdonosok szerkesztése"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Nem sikerült feldolgozni a feltöltendő médiát, próbálja újra."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Nem sikerült letölteni a felhasználói adatokat"</string>
|
||||
|
||||
@@ -446,10 +446,6 @@ Sei sicuro di voler continuare?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Il tuo messaggio non è stato inviato perché %1$s non ha verificato tutti i dispositivi."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Uno o più dispositivi non sono verificati. Puoi inviare il messaggio comunque, oppure annullarlo e riprovare più tardi dopo aver verificato tutti i tuoi dispositivi."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Il tuo messaggio non è stato inviato perché non hai verificato uno o più dispositivi."</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Modifica impostazioni"</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_title">"Autorizzazioni"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Modifica amministratori o proprietari"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Elaborazione del file multimediale da caricare fallita, riprova."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Impossibile recuperare i dettagli dell\'utente"</string>
|
||||
|
||||
@@ -446,10 +446,6 @@ Você tem certeza de que deseja continuar?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Sua mensagem não foi enviada porque %1$s não verificou todos os dispositivos"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Um ou mais de seus dispositivos não foram verificados. Você pode enviar a mensagem mesmo assim ou pode cancelar por enquanto e tentar novamente mais tarde, depois de ter verificado todos os seus dispositivos."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Sua mensagem não foi enviada porque você não verificou um ou mais de seus dispositivos"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Alterar configurações"</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_title">"Permissões"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Editar administradores ou proprietários"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Falha ao processar a mídia para o envio. Tente novamente."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Não foi possível buscar os detalhes do usuário"</string>
|
||||
|
||||
@@ -492,10 +492,6 @@ Sunteți sigur că doriți să continuați?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Mesajul dvs. nu a fost trimis deoarece %1$s nu si-a verificat toate dispozitivele"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Unul sau mai multe dispozitive nu sunt verificate. Puteți trimite mesajul oricum sau puteți anula deocamdată și încercați din nou mai târziu după ce ați verificat toate dispozitivele."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Mesajul dumneavoastră nu a fost trimis deoarece nu ați verificat unul sau mai multe dispozitive"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Modificați setările"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Gestionați spațiul"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Gestionați camerele"</string>
|
||||
<string name="screen_room_change_permissions_title">"Permisiuni"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Editați administratorii sau proprietarii"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Procesarea datelor media a eșuat, vă rugăm să încercați din nou."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Nu am putut găsi detaliile utilizatorului"</string>
|
||||
|
||||
@@ -455,10 +455,6 @@
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Ваше сообщение не было отправлено, потому что %1$s не проверил одно или несколько устройств"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Одно или несколько ваших устройств не проверены. Вы можете отправить сообщение в любом случае или отменить его пока и повторить попытку позже, проверив все свои устройства."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Ваше сообщение не было отправлено, поскольку вы не подтвердили одно или несколько своих устройств."</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Изменить настройки"</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_title">"Разрешения"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Редактировать роль владельца и администратора"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Не удалось обработать медиафайл для загрузки, попробуйте еще раз."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Не удалось получить данные о пользователе"</string>
|
||||
|
||||
@@ -462,10 +462,6 @@ Naozaj chcete pokračovať?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Vaša správa nebola odoslaná, pretože %1$s neoveril/a všetky zariadenia."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"Jedno alebo viac vašich zariadení nie je overených. Správu môžete odoslať aj tak, alebo môžete zatiaľ zrušiť a skúsiť to znova neskôr po overení všetkých svojich zariadení."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Vaša správa nebola odoslaná, pretože ste neoverili jedno alebo viac svojich zariadení"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Zmeniť nastavenia"</string>
|
||||
<string name="screen_room_change_permissions_manage_space">"Spravovať priestor"</string>
|
||||
<string name="screen_room_change_permissions_manage_space_rooms">"Spravovať miestnosti"</string>
|
||||
<string name="screen_room_change_permissions_title">"Povolenia"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Upraviť správcov alebo vlastníkov"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Nepodarilo sa spracovať médiá na odoslanie, skúste to prosím znova."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Nepodarilo sa získať údaje o používateľovi"</string>
|
||||
|
||||
@@ -437,10 +437,6 @@
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"未傳送您的訊息,因為 %1$s 尚未驗證所有裝置。"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"您的一個或多個裝置未經驗證。您仍可傳送訊息,也可以取消並在您驗證您的所有裝置後再試一次。"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"因為您尚未驗證一個或多個裝置,因為未傳送您的訊息"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"變更設定"</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_title">"權限"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"編輯管理員或擁有者"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"無法處理要上傳的媒體,請再試一次。"</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"無法擷取使用者詳細資訊"</string>
|
||||
|
||||
@@ -483,10 +483,6 @@ Are you sure you want to continue?"</string>
|
||||
<string name="screen_resolve_send_failure_unsigned_device_title">"Your message was not sent because %1$s has not verified all devices"</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"One or more of your devices are unverified. You can send the message anyway, or you can cancel for now and try again later after you have verified all of your devices."</string>
|
||||
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Your message was not sent because you have not verified one or more of your devices"</string>
|
||||
<string name="screen_room_change_permissions_change_settings">"Change settings"</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_title">"Permissions"</string>
|
||||
<string name="screen_room_change_role_administrators_or_owners_title">"Edit Admins or Owners"</string>
|
||||
<string name="screen_room_error_failed_processing_media">"Failed processing media to upload, please try again."</string>
|
||||
<string name="screen_room_error_failed_retrieving_user_details">"Could not retrieve user details"</string>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -381,6 +381,7 @@
|
||||
"name" : ":features:rolesandpermissions:impl",
|
||||
"includeRegex" : [
|
||||
"screen_room_change_.*",
|
||||
"screen\\.room_change_permissions\\..*",
|
||||
"screen_room_roles_.*",
|
||||
"screen\\.room_roles_and_permissions\\..*",
|
||||
"screen_room_member_list.*",
|
||||
|
||||
Reference in New Issue
Block a user