Change a room's permissions power levels (#2525)
* Change a room's permissions power levels * Make `currentPermissions` use a `MatrixRoomPowerLevels?` instance instead. * Update strings * Update screenshots --------- Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
parent
3453738344
commit
59a682b407
71 changed files with 1556 additions and 58 deletions
|
|
@ -170,7 +170,7 @@ class StateContentFormatter @Inject constructor(
|
|||
"RoomPinnedEvents"
|
||||
}
|
||||
}
|
||||
is OtherState.RoomPowerLevels -> when (renderingMode) {
|
||||
is OtherState.RoomUserPowerLevels -> when (renderingMode) {
|
||||
RenderingMode.RoomList -> {
|
||||
Timber.v("Filtering timeline item for room state change: $content")
|
||||
null
|
||||
|
|
|
|||
|
|
@ -3,12 +3,16 @@
|
|||
<string name="state_event_avatar_changed_too">"(avatar was changed too)"</string>
|
||||
<string name="state_event_avatar_url_changed">"%1$s changed their avatar"</string>
|
||||
<string name="state_event_avatar_url_changed_by_you">"You changed your avatar"</string>
|
||||
<string name="state_event_demoted_to_member">"%1$s was demoted to member"</string>
|
||||
<string name="state_event_demoted_to_moderator">"%1$s was demoted to moderator"</string>
|
||||
<string name="state_event_display_name_changed_from">"%1$s changed their display name from %2$s to %3$s"</string>
|
||||
<string name="state_event_display_name_changed_from_by_you">"You changed your display name from %1$s to %2$s"</string>
|
||||
<string name="state_event_display_name_removed">"%1$s removed their display name (it was %2$s)"</string>
|
||||
<string name="state_event_display_name_removed_by_you">"You removed your display name (it was %1$s)"</string>
|
||||
<string name="state_event_display_name_set">"%1$s set their display name to %2$s"</string>
|
||||
<string name="state_event_display_name_set_by_you">"You set your display name to %1$s"</string>
|
||||
<string name="state_event_promoted_to_administrator">"%1$s was promoted to admin"</string>
|
||||
<string name="state_event_promoted_to_moderator">"%1$s was promoted to moderator"</string>
|
||||
<string name="state_event_room_avatar_changed">"%1$s changed the room avatar"</string>
|
||||
<string name="state_event_room_avatar_changed_by_you">"You changed the room avatar"</string>
|
||||
<string name="state_event_room_avatar_removed">"%1$s removed the room avatar"</string>
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ class DefaultRoomLastMessageFormatterTest {
|
|||
OtherState.RoomHistoryVisibility,
|
||||
OtherState.RoomJoinRules,
|
||||
OtherState.RoomPinnedEvents,
|
||||
OtherState.RoomPowerLevels(emptyMap()),
|
||||
OtherState.RoomUserPowerLevels(emptyMap()),
|
||||
OtherState.RoomServerAcl,
|
||||
OtherState.RoomTombstone,
|
||||
OtherState.SpaceChild,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import io.element.android.libraries.matrix.api.media.MediaUploadHandler
|
|||
import io.element.android.libraries.matrix.api.media.VideoInfo
|
||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
|
||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||
|
|
@ -97,6 +98,12 @@ interface MatrixRoom : Closeable {
|
|||
|
||||
suspend fun unsubscribeFromSync()
|
||||
|
||||
suspend fun powerLevels(): Result<MatrixRoomPowerLevels>
|
||||
|
||||
suspend fun updatePowerLevels(matrixRoomPowerLevels: MatrixRoomPowerLevels): Result<Unit>
|
||||
|
||||
suspend fun resetPowerLevels(): Result<MatrixRoomPowerLevels>
|
||||
|
||||
suspend fun userRole(userId: UserId): Result<RoomMember.Role>
|
||||
|
||||
suspend fun updateUsersRoles(changes: List<UserRoleChange>): Result<Unit>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,17 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
|
|||
import io.element.android.libraries.matrix.api.room.MessageEventType
|
||||
import io.element.android.libraries.matrix.api.room.StateEventType
|
||||
|
||||
data class MatrixRoomPowerLevels(
|
||||
val ban: Long,
|
||||
val invite: Long,
|
||||
val kick: Long,
|
||||
val sendEvents: Long,
|
||||
val redactEvents: Long,
|
||||
val roomName: Long,
|
||||
val roomAvatar: Long,
|
||||
val roomTopic: Long,
|
||||
)
|
||||
|
||||
/**
|
||||
* Shortcut for calling [MatrixRoom.canUserInvite] with our own user.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ sealed interface OtherState {
|
|||
data object RoomJoinRules : OtherState
|
||||
data class RoomName(val name: String?) : OtherState
|
||||
data object RoomPinnedEvents : OtherState
|
||||
data class RoomPowerLevels(val users: Map<String, Long>) : OtherState
|
||||
data class RoomUserPowerLevels(val users: Map<String, Long>) : OtherState
|
||||
data object RoomServerAcl : OtherState
|
||||
data class RoomThirdPartyInvite(val displayName: String?) : OtherState
|
||||
data object RoomTombstone : OtherState
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import io.element.android.libraries.matrix.api.room.MessageEventType
|
|||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.StateEventType
|
||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||
import io.element.android.libraries.matrix.api.room.roomNotificationSettings
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
|
||||
|
|
@ -54,6 +55,7 @@ import io.element.android.libraries.matrix.impl.poll.toInner
|
|||
import io.element.android.libraries.matrix.impl.room.location.toInner
|
||||
import io.element.android.libraries.matrix.impl.room.member.RoomMemberListFetcher
|
||||
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
|
||||
import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsMapper
|
||||
import io.element.android.libraries.matrix.impl.timeline.RustMatrixTimeline
|
||||
import io.element.android.libraries.matrix.impl.timeline.toRustReceiptType
|
||||
import io.element.android.libraries.matrix.impl.util.mxCallbackFlow
|
||||
|
|
@ -86,6 +88,7 @@ import org.matrix.rustcomponents.sdk.messageEventContentFromHtml
|
|||
import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
|
||||
import org.matrix.rustcomponents.sdk.use
|
||||
import timber.log.Timber
|
||||
import uniffi.matrix_sdk.RoomPowerLevelChanges
|
||||
import java.io.File
|
||||
import org.matrix.rustcomponents.sdk.Room as InnerRoom
|
||||
import org.matrix.rustcomponents.sdk.Timeline as InnerTimeline
|
||||
|
|
@ -253,6 +256,34 @@ class RustMatrixRoom(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun powerLevels(): Result<MatrixRoomPowerLevels> = withContext(roomDispatcher) {
|
||||
runCatching {
|
||||
RoomPowerLevelsMapper.map(innerRoom.getPowerLevels())
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun updatePowerLevels(matrixRoomPowerLevels: MatrixRoomPowerLevels): Result<Unit> = withContext(roomDispatcher) {
|
||||
runCatching {
|
||||
val changes = RoomPowerLevelChanges(
|
||||
ban = matrixRoomPowerLevels.ban,
|
||||
invite = matrixRoomPowerLevels.invite,
|
||||
kick = matrixRoomPowerLevels.kick,
|
||||
redact = matrixRoomPowerLevels.redactEvents,
|
||||
eventsDefault = matrixRoomPowerLevels.sendEvents,
|
||||
roomName = matrixRoomPowerLevels.roomName,
|
||||
roomAvatar = matrixRoomPowerLevels.roomAvatar,
|
||||
roomTopic = matrixRoomPowerLevels.roomTopic,
|
||||
)
|
||||
innerRoom.applyPowerLevelChanges(changes)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun resetPowerLevels(): Result<MatrixRoomPowerLevels> = withContext(roomDispatcher) {
|
||||
runCatching {
|
||||
RoomPowerLevelsMapper.map(innerRoom.resetPowerLevels())
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun userAvatarUrl(userId: UserId): Result<String?> = withContext(roomDispatcher) {
|
||||
runCatching {
|
||||
innerRoom.memberAvatarUrl(userId.value)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2024 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.impl.room.powerlevels
|
||||
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
|
||||
import org.matrix.rustcomponents.sdk.RoomPowerLevels as RustRoomPowerLevels
|
||||
|
||||
object RoomPowerLevelsMapper {
|
||||
fun map(roomPowerLevels: RustRoomPowerLevels): MatrixRoomPowerLevels {
|
||||
return MatrixRoomPowerLevels(
|
||||
ban = roomPowerLevels.ban,
|
||||
invite = roomPowerLevels.invite,
|
||||
kick = roomPowerLevels.kick,
|
||||
sendEvents = roomPowerLevels.eventsDefault,
|
||||
redactEvents = roomPowerLevels.redact,
|
||||
roomName = roomPowerLevels.roomName,
|
||||
roomAvatar = roomPowerLevels.roomAvatar,
|
||||
roomTopic = roomPowerLevels.roomTopic
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -163,7 +163,7 @@ private fun RustOtherState.map(): OtherState {
|
|||
RustOtherState.RoomJoinRules -> OtherState.RoomJoinRules
|
||||
is RustOtherState.RoomName -> OtherState.RoomName(name)
|
||||
RustOtherState.RoomPinnedEvents -> OtherState.RoomPinnedEvents
|
||||
is RustOtherState.RoomPowerLevels -> OtherState.RoomPowerLevels(users)
|
||||
is RustOtherState.RoomPowerLevels -> OtherState.RoomUserPowerLevels(users)
|
||||
RustOtherState.RoomServerAcl -> OtherState.RoomServerAcl
|
||||
is RustOtherState.RoomThirdPartyInvite -> OtherState.RoomThirdPartyInvite(displayName)
|
||||
RustOtherState.RoomTombstone -> OtherState.RoomTombstone
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import io.element.android.libraries.matrix.api.room.RoomMember
|
|||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.matrix.api.room.StateEventType
|
||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
|
||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||
|
|
@ -125,6 +126,9 @@ class FakeMatrixRoom(
|
|||
private var canUserTriggerRoomNotificationResult: Result<Boolean> = Result.success(true)
|
||||
private var canUserJoinCallResult: Result<Boolean> = Result.success(true)
|
||||
private var setIsFavoriteResult = Result.success(Unit)
|
||||
private var powerLevelsResult = Result.success(defaultRoomPowerLevels())
|
||||
private var updatePowerLevelsResult = Result.success(Unit)
|
||||
private var resetPowerLevelsResult = Result.success(defaultRoomPowerLevels())
|
||||
var sendMessageMentions = emptyList<Mention>()
|
||||
val editMessageCalls = mutableListOf<Pair<String, String?>>()
|
||||
private val _typingRecord = mutableListOf<Boolean>()
|
||||
|
|
@ -204,6 +208,17 @@ class FakeMatrixRoom(
|
|||
override suspend fun subscribeToSync() = Unit
|
||||
|
||||
override suspend fun unsubscribeFromSync() = Unit
|
||||
override suspend fun powerLevels(): Result<MatrixRoomPowerLevels> {
|
||||
return powerLevelsResult
|
||||
}
|
||||
|
||||
override suspend fun updatePowerLevels(matrixRoomPowerLevels: MatrixRoomPowerLevels): Result<Unit> = simulateLongTask {
|
||||
updatePowerLevelsResult
|
||||
}
|
||||
|
||||
override suspend fun resetPowerLevels(): Result<MatrixRoomPowerLevels> = simulateLongTask {
|
||||
resetPowerLevelsResult
|
||||
}
|
||||
|
||||
override fun destroy() = Unit
|
||||
|
||||
|
|
@ -676,6 +691,18 @@ class FakeMatrixRoom(
|
|||
fun givenRoomTypingMembers(typingMembers: List<UserId>) {
|
||||
_roomTypingMembersFlow.tryEmit(typingMembers)
|
||||
}
|
||||
|
||||
fun givenPowerLevelsResult(result: Result<MatrixRoomPowerLevels>) {
|
||||
powerLevelsResult = result
|
||||
}
|
||||
|
||||
fun givenUpdatePowerLevelsResult(result: Result<Unit>) {
|
||||
updatePowerLevelsResult = result
|
||||
}
|
||||
|
||||
fun givenResetPowerLevelsResult(result: Result<MatrixRoomPowerLevels>) {
|
||||
resetPowerLevelsResult = result
|
||||
}
|
||||
}
|
||||
|
||||
data class SendLocationInvocation(
|
||||
|
|
@ -752,3 +779,14 @@ fun aRoomInfo(
|
|||
userPowerLevels = userPowerLevels,
|
||||
activeRoomCallParticipants = activeRoomCallParticipants.toImmutableList(),
|
||||
)
|
||||
|
||||
fun defaultRoomPowerLevels() = MatrixRoomPowerLevels(
|
||||
ban = 50,
|
||||
invite = 0,
|
||||
kick = 50,
|
||||
sendEvents = 0,
|
||||
redactEvents = 50,
|
||||
roomName = 100,
|
||||
roomAvatar = 100,
|
||||
roomTopic = 100
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
<string name="action_decline">"Decline"</string>
|
||||
<string name="action_delete_poll">"Delete Poll"</string>
|
||||
<string name="action_disable">"Disable"</string>
|
||||
<string name="action_discard">"Discard"</string>
|
||||
<string name="action_done">"Done"</string>
|
||||
<string name="action_edit">"Edit"</string>
|
||||
<string name="action_edit_poll">"Edit poll"</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue