From 2d21c15e3b3937fc2e01821fdc4d9975f90599ad Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 28 Jul 2025 16:49:57 +0200 Subject: [PATCH] change (power level) : continue handling v12 room --- .../sdk/api/session/room/powerlevels/Role.kt | 1 - .../room/powerlevels/RoomPowerLevels.kt | 2 +- .../timeline/format/NoticeEventFormatter.kt | 4 +- .../im/vector/app/features/powerlevel/Role.kt | 12 ++++ .../RoomMemberProfileController.kt | 4 +- .../RoomMemberProfileFragment.kt | 2 +- .../RoomMemberProfileViewModel.kt | 4 +- .../powerlevel/EditPowerLevelDialogs.kt | 32 ++++----- .../members/RoomMemberListComparator.kt | 4 +- .../permissions/RoomPermissionsController.kt | 2 +- .../permissions/RoomPermissionsFragment.kt | 2 +- .../app/features/spaces/SpaceMenuViewModel.kt | 4 +- .../leave/SpaceLeaveAdvanceViewState.kt | 2 +- .../leave/SpaceLeaveAdvancedFragment.kt | 2 +- .../leave/SpaceLeaveAdvancedViewModel.kt | 20 ++---- .../res/layout/dialog_edit_power_level.xml | 72 +++++++------------ 16 files changed, 77 insertions(+), 92 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/powerlevel/Role.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt index 57cd75e70d..dce48c8069 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt @@ -24,7 +24,6 @@ enum class Role { Moderator, User; - companion object { fun getSuggestedRole(userPowerLevel: UserPowerLevel): Role { return when { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/RoomPowerLevels.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/RoomPowerLevels.kt index d7fbeb8769..0d66136730 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/RoomPowerLevels.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/RoomPowerLevels.kt @@ -59,7 +59,7 @@ class RoomPowerLevels( * @param userId the user id * @return the power level */ - fun getUserRole(userId: String): Role { + fun getSuggestedRole(userId: String): Role { val value = getUserPowerLevel(userId) return Role.getSuggestedRole(value) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index 5a8d3fc41a..0e328bdbba 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -122,8 +122,8 @@ class NoticeEventFormatter @Inject constructor( userIds.addAll(previousPowerLevelsContent.users.orEmpty().keys) val diffs = ArrayList() userIds.forEach { userId -> - val from = RoomPowerLevels(previousPowerLevelsContent,null).getUserRole(userId) - val to = RoomPowerLevels(powerLevelsContent, null).getUserRole(userId) + val from = RoomPowerLevels(previousPowerLevelsContent,null).getSuggestedRole(userId) + val to = RoomPowerLevels(powerLevelsContent, null).getSuggestedRole(userId) if (from != to) { val fromStr = roleFormatter.format(from) val toStr = roleFormatter.format(to) diff --git a/vector/src/main/java/im/vector/app/features/powerlevel/Role.kt b/vector/src/main/java/im/vector/app/features/powerlevel/Role.kt new file mode 100644 index 0000000000..d61bbef768 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/powerlevel/Role.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package im.vector.app.features.powerlevel + +import org.matrix.android.sdk.api.session.room.powerlevels.Role + +fun Role.isOwner() = this == Role.Creator || this == Role.SuperAdmin diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt index f4420d6a42..308fdc5bce 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt @@ -17,7 +17,6 @@ import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import im.vector.lib.strings.CommonStrings import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.powerlevels.Role import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel import javax.inject.Inject @@ -38,7 +37,7 @@ class RoomMemberProfileController @Inject constructor( fun onOverrideColorClicked() fun onJumpToReadReceiptClicked() fun onMentionClicked() - fun onEditPowerLevel(userPowerLevel: UserPowerLevel) + fun onEditPowerLevel(userPowerLevel: UserPowerLevel.Value) fun onKickClicked(isSpace: Boolean) fun onBanClicked(isSpace: Boolean, isUserBanned: Boolean) fun onCancelInviteClicked() @@ -250,6 +249,7 @@ class RoomMemberProfileController @Inject constructor( if ((!state.isMine && myPowerLevel <= userPowerLevel)) { return } + if(userPowerLevel !is UserPowerLevel.Value) return val membership = state.asyncMembership() ?: return val canKick = !state.isMine && state.actionPermissions.canKick val canBan = !state.isMine && state.actionPermissions.canBan diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index 836e3857cc..7f0ec9b57a 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -377,7 +377,7 @@ class RoomMemberProfileFragment : .show() } - override fun onEditPowerLevel(userPowerLevel: UserPowerLevel) { + override fun onEditPowerLevel(userPowerLevel: UserPowerLevel.Value) { EditPowerLevelDialogs.showChoice(requireActivity(), CommonStrings.power_level_edit_title, userPowerLevel) { newPowerLevel -> viewModel.handle(RoomMemberProfileAction.SetPowerLevel(userPowerLevel, newPowerLevel, true)) } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index 92ba7acfb5..14e286fd1d 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -388,9 +388,9 @@ class RoomMemberProfileViewModel @AssistedInject constructor( } roomSummaryLive.combine(powerLevelsFlow) { roomSummary, roomPowerLevels -> val roomName = roomSummary.toMatrixItem().getBestName() - when (roomPowerLevels.getUserRole(initialState.userId)) { + when (roomPowerLevels.getSuggestedRole(initialState.userId)) { Role.SuperAdmin, - Role.Creator, + Role.Creator -> stringProvider.getString(CommonStrings.room_member_power_level_owner_in, roomName) Role.Admin -> stringProvider.getString(CommonStrings.room_member_power_level_admin_in, roomName) Role.Moderator -> stringProvider.getString(CommonStrings.room_member_power_level_moderator_in, roomName) Role.User -> stringProvider.getString(CommonStrings.room_member_power_level_default_in, roomName) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt index 6d24f198f4..c750b91f8f 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt @@ -17,6 +17,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard import im.vector.app.databinding.DialogEditPowerLevelBinding +import im.vector.app.features.powerlevel.isOwner import im.vector.lib.strings.CommonStrings import org.matrix.android.sdk.api.session.room.powerlevels.Role import org.matrix.android.sdk.api.session.room.powerlevels.UserPowerLevel @@ -27,46 +28,45 @@ object EditPowerLevelDialogs { fun showChoice( activity: Activity, @StringRes titleRes: Int, - currentPowerLevel: UserPowerLevel, + currentPowerLevel: UserPowerLevel.Value, listener: (UserPowerLevel.Value) -> Unit ) { val dialogLayout = activity.layoutInflater.inflate(R.layout.dialog_edit_power_level, null) val views = DialogEditPowerLevelBinding.bind(dialogLayout) - views.powerLevelRadioGroup.setOnCheckedChangeListener { _, checkedId -> - views.powerLevelCustomEditLayout.isVisible = checkedId == R.id.powerLevelCustomRadio - } val currentRole = Role.getSuggestedRole(currentPowerLevel) when (currentRole) { - Role.Creator -> views.powerLevelAdminRadio.isChecked = true - Role.SuperAdmin -> views.powerLevelAdminRadio.isChecked = true + Role.Creator, + Role.SuperAdmin -> views.powerLevelOwnerRadio.isChecked = true Role.Admin -> views.powerLevelAdminRadio.isChecked = true Role.Moderator -> views.powerLevelModeratorRadio.isChecked = true Role.User -> views.powerLevelDefaultRadio.isChecked = true } - + views.powerLevelOwnerRadio.isVisible = currentRole.isOwner() MaterialAlertDialogBuilder(activity) .setTitle(titleRes) .setView(dialogLayout) .setPositiveButton(CommonStrings.edit) { _, _ -> val newValue = when (views.powerLevelRadioGroup.checkedRadioButtonId) { + R.id.powerLevelOwnerRadio -> UserPowerLevel.SuperAdmin R.id.powerLevelAdminRadio -> UserPowerLevel.Admin R.id.powerLevelModeratorRadio -> UserPowerLevel.Moderator R.id.powerLevelDefaultRadio -> UserPowerLevel.User else -> null } - if(newValue != null) { + if (newValue != null) { listener(newValue) } } .setNegativeButton(CommonStrings.action_cancel, null) - .setOnKeyListener(DialogInterface.OnKeyListener - { dialog, keyCode, event -> - if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) { - dialog.cancel() - return@OnKeyListener true - } - false - }) + .setOnKeyListener( + DialogInterface.OnKeyListener + { dialog, keyCode, event -> + if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) { + dialog.cancel() + return@OnKeyListener true + } + false + }) .setOnDismissListener { dialogLayout.hideKeyboard() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListComparator.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListComparator.kt index a4ce99f63d..ffb4eaf522 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListComparator.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListComparator.kt @@ -23,8 +23,8 @@ class RoomMemberListComparator @Inject constructor() : Comparator -1 else -> when { - leftRoomMember.powerLevel > rightRoomMember.powerLevel -> 1 - leftRoomMember.powerLevel < rightRoomMember.powerLevel -> -1 + leftRoomMember.powerLevel > rightRoomMember.powerLevel -> -1 + leftRoomMember.powerLevel < rightRoomMember.powerLevel -> 1 leftRoomMember.summary.displayName.isNullOrBlank() -> when { rightRoomMember.summary.displayName.isNullOrBlank() -> { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt index e5255eb435..78a405db49 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt @@ -35,7 +35,7 @@ class RoomPermissionsController @Inject constructor( ) : TypedEpoxyController() { interface Callback { - fun onEditPermission(editablePermission: EditablePermission, currentPowerLevel: UserPowerLevel) + fun onEditPermission(editablePermission: EditablePermission, currentPowerLevel: UserPowerLevel.Value) fun toggleShowAllPermissions() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt index ea1afbcfc5..d2e94bf504 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt @@ -93,7 +93,7 @@ class RoomPermissionsFragment : } } - override fun onEditPermission(editablePermission: EditablePermission, currentPowerLevel: UserPowerLevel) { + override fun onEditPermission(editablePermission: EditablePermission, currentPowerLevel: UserPowerLevel.Value) { EditPowerLevelDialogs.showChoice(requireActivity(), editablePermission.labelResId, currentPowerLevel) { newPowerLevel -> viewModel.handle(RoomPermissionsAction.UpdatePermission(editablePermission, newPowerLevel)) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt index cebfb63f1f..c8ac7af8b8 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt @@ -82,9 +82,9 @@ class SpaceMenuViewModel @AssistedInject constructor( val canChangeName = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME) val canChangeTopic = roomPowerLevels.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC) - val isAdmin = roomPowerLevels.getUserRole(session.myUserId) == Role.Admin + val isAdmin = roomPowerLevels.getSuggestedRole(session.myUserId) == Role.Admin val otherAdminCount = roomSummary?.otherMemberIds - ?.map { roomPowerLevels.getUserRole(it) } + ?.map { roomPowerLevels.getSuggestedRole(it) } ?.count { it == Role.Admin } ?: 0 val isLastAdmin = isAdmin && otherAdminCount == 0 diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvanceViewState.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvanceViewState.kt index 48199cd2a2..0b1968b31e 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvanceViewState.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvanceViewState.kt @@ -21,7 +21,7 @@ data class SpaceLeaveAdvanceViewState( val currentFilter: String = "", val leaveState: Async = Uninitialized, val isFilteringEnabled: Boolean = false, - val isLastAdmin: Boolean = false + val isLastOwner: Boolean = false ) : MavericksState { constructor(args: SpaceBottomSheetSettingsArgs) : this( diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedFragment.kt index 1d9ff43a9d..1c1f33faa8 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedFragment.kt @@ -61,7 +61,7 @@ class SpaceLeaveAdvancedFragment : state.spaceSummary?.let { summary -> val warningMessage: CharSequence? = when { summary.otherMemberIds.isEmpty() -> getString(CommonStrings.space_leave_prompt_msg_only_you) - state.isLastAdmin -> getString(CommonStrings.space_leave_prompt_msg_as_admin) + state.isLastOwner -> getString(CommonStrings.space_leave_prompt_msg_as_admin) !summary.isPublic -> getString(CommonStrings.space_leave_prompt_msg_private) else -> null } diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt index b8a3bbd07d..3c06244888 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt @@ -20,23 +20,17 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel +import im.vector.app.features.powerlevel.isOwner import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import okhttp3.internal.toImmutableList -import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.query.SpaceFilter import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.room.getRoomPowerLevels -import org.matrix.android.sdk.api.session.room.getStateEvent import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent -import org.matrix.android.sdk.api.session.room.powerlevels.RoomPowerLevels -import org.matrix.android.sdk.api.session.room.powerlevels.Role import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.flow.unwrap @@ -53,14 +47,14 @@ class SpaceLeaveAdvancedViewModel @AssistedInject constructor( val spaceSummary = space?.roomSummary() val roomPowerLevels = space?.getRoomPowerLevels() roomPowerLevels?.let { - val isAdmin = roomPowerLevels.getUserRole(session.myUserId) == Role.Admin - val otherAdminCount = spaceSummary?.otherMemberIds - ?.map { roomPowerLevels.getUserRole(it) } - ?.count { it == Role.Admin } + val isOwner = roomPowerLevels.getSuggestedRole(session.myUserId).isOwner() + val otherOwnersCount = spaceSummary?.otherMemberIds + ?.map { roomPowerLevels.getSuggestedRole(it) } + ?.count { it.isOwner() } ?: 0 - val isLastAdmin = isAdmin && otherAdminCount == 0 + val isLastOwner = isOwner && otherOwnersCount == 0 setState { - copy(isLastAdmin = isLastAdmin) + copy(isLastOwner = isLastOwner) } } diff --git a/vector/src/main/res/layout/dialog_edit_power_level.xml b/vector/src/main/res/layout/dialog_edit_power_level.xml index bf91dc3367..00f6fbce56 100644 --- a/vector/src/main/res/layout/dialog_edit_power_level.xml +++ b/vector/src/main/res/layout/dialog_edit_power_level.xml @@ -1,5 +1,7 @@ - - + android:text="@string/power_level_owner" + android:textColor="?vctr_content_primary" /> - - - - - - - - - - - + android:text="@string/power_level_admin" + android:textColor="?vctr_content_primary" /> - + - + - +