1
0
mirror of https://github.com/vector-im/riotX-android synced 2025-10-05 15:52:47 +02:00

change (power level) : continue handling v12 room

This commit is contained in:
ganfra
2025-07-28 16:49:57 +02:00
parent fd3f7e3a24
commit 2d21c15e3b
16 changed files with 77 additions and 92 deletions

View File

@@ -122,8 +122,8 @@ class NoticeEventFormatter @Inject constructor(
userIds.addAll(previousPowerLevelsContent.users.orEmpty().keys)
val diffs = ArrayList<String>()
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)

View File

@@ -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

View File

@@ -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

View File

@@ -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))
}

View File

@@ -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)

View File

@@ -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()
}

View File

@@ -23,8 +23,8 @@ class RoomMemberListComparator @Inject constructor() : Comparator<RoomMemberWith
null -> -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() -> {

View File

@@ -35,7 +35,7 @@ class RoomPermissionsController @Inject constructor(
) : TypedEpoxyController<RoomPermissionsViewState>() {
interface Callback {
fun onEditPermission(editablePermission: EditablePermission, currentPowerLevel: UserPowerLevel)
fun onEditPermission(editablePermission: EditablePermission, currentPowerLevel: UserPowerLevel.Value)
fun toggleShowAllPermissions()
}

View File

@@ -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))
}

View File

@@ -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

View File

@@ -21,7 +21,7 @@ data class SpaceLeaveAdvanceViewState(
val currentFilter: String = "",
val leaveState: Async<Unit> = Uninitialized,
val isFilteringEnabled: Boolean = false,
val isLastAdmin: Boolean = false
val isLastOwner: Boolean = false
) : MavericksState {
constructor(args: SpaceBottomSheetSettingsArgs) : this(

View File

@@ -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
}

View File

@@ -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)
}
}

View File

@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/powerLevelRadioGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -7,54 +9,32 @@
android:paddingTop="12dp"
android:paddingEnd="?dialogPreferredPadding">
<RadioGroup
android:id="@+id/powerLevelRadioGroup"
android:layout_width="match_parent"
<RadioButton
android:id="@+id/powerLevelOwnerRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
android:text="@string/power_level_owner"
android:textColor="?vctr_content_primary" />
<RadioButton
android:id="@+id/powerLevelAdminRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/power_level_admin"
android:textColor="?vctr_content_primary" />
<RadioButton
android:id="@+id/powerLevelModeratorRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/power_level_moderator"
android:textColor="?vctr_content_primary" />
<RadioButton
android:id="@+id/powerLevelDefaultRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/power_level_default"
android:textColor="?vctr_content_primary" />
<RadioButton
android:id="@+id/powerLevelCustomRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/power_level_custom_no_value"
android:textColor="?vctr_content_primary" />
</RadioGroup>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/powerLevelCustomEditLayout"
android:layout_width="match_parent"
<RadioButton
android:id="@+id/powerLevelAdminRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/power_level_custom_no_value">
android:text="@string/power_level_admin"
android:textColor="?vctr_content_primary" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/powerLevelCustomEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number|numberSigned" />
<RadioButton
android:id="@+id/powerLevelModeratorRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/power_level_moderator"
android:textColor="?vctr_content_primary" />
</com.google.android.material.textfield.TextInputLayout>
<RadioButton
android:id="@+id/powerLevelDefaultRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/power_level_default"
android:textColor="?vctr_content_primary" />
</LinearLayout>
</RadioGroup>