From 8a1a772ab741fc33a4d240c9aa06e43a0ec5387a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 26 Jun 2020 23:31:19 +0200 Subject: [PATCH 1/3] Handle `/op` and `/deop` commands (#12) Also when resetting power level, remove from list of user instead of setting the default value. --- CHANGES.md | 1 + .../riotx/features/command/CommandParser.kt | 2 +- .../riotx/features/command/ParsedCommand.kt | 2 +- .../home/room/detail/RoomDetailViewModel.kt | 21 +++++++++++++++++-- .../RoomMemberProfileViewModel.kt | 6 +++++- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index df550511e2..2c9387b456 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Features ✨: Improvements 🙌: - "Add Matrix app" menu is now always visible (#1495) + - Handle `/op` and `/deop` commands (#12) Bugfix 🐛: - Fix dark theme issue on login screen (#1097) diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index e7d2e9a62b..7c32a34aff 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -232,7 +232,7 @@ object CommandParser { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { - ParsedCommand.SetUserPowerLevel(userId, 0) + ParsedCommand.SetUserPowerLevel(userId, null) } else { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } diff --git a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt index 63e016b0b6..44ad2265e1 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt @@ -39,7 +39,7 @@ sealed class ParsedCommand { class SendRainbowEmote(val message: CharSequence) : ParsedCommand() class BanUser(val userId: String, val reason: String?) : ParsedCommand() class UnbanUser(val userId: String, val reason: String?) : ParsedCommand() - class SetUserPowerLevel(val userId: String, val powerLevel: Int) : ParsedCommand() + class SetUserPowerLevel(val userId: String, val powerLevel: Int?) : ParsedCommand() class Invite(val userId: String, val reason: String?) : ParsedCommand() class JoinRoom(val roomAlias: String, val reason: String?) : ParsedCommand() class PartRoom(val roomAlias: String, val reason: String?) : ParsedCommand() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index 3e8949e94c..a0c7447569 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -41,6 +41,7 @@ import im.vector.matrix.android.api.session.file.FileService import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilities import im.vector.matrix.android.api.session.room.members.roomMemberQueryParams import im.vector.matrix.android.api.session.room.model.Membership +import im.vector.matrix.android.api.session.room.model.PowerLevelsContent import im.vector.matrix.android.api.session.room.model.RoomMemberSummary import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.message.MessageContent @@ -448,8 +449,8 @@ class RoomDetailViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.SetUserPowerLevel -> { - // TODO - _viewEvents.post(RoomDetailViewEvents.SlashCommandNotImplemented) + handleSetUserPowerLevel(slashCommandResult) + popDraft() } is ParsedCommand.ClearScalarToken -> { // TODO @@ -668,6 +669,22 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun handleSetUserPowerLevel(setUserPowerLevel: ParsedCommand.SetUserPowerLevel) { + val currentPowerLevelsContent = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS) + ?.content + ?.toModel() ?: return + + launchSlashCommandFlow { + if (setUserPowerLevel.powerLevel == null) { + currentPowerLevelsContent.users.remove(setUserPowerLevel.userId) + } else { + currentPowerLevelsContent.users[setUserPowerLevel.userId] = setUserPowerLevel.powerLevel + } + + room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, currentPowerLevelsContent.toContent(), it) + } + } + private fun handleKickSlashCommand(kick: ParsedCommand.KickUser) { launchSlashCommandFlow { room.kick(kick.userId, kick.reason, it) diff --git a/vector/src/main/java/im/vector/riotx/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roommemberprofile/RoomMemberProfileViewModel.kt index aca584a663..62f77e98c9 100644 --- a/vector/src/main/java/im/vector/riotx/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -162,7 +162,11 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v } else if (action.askForValidation && state.isMine) { _viewEvents.post(RoomMemberProfileViewEvents.ShowPowerLevelDemoteWarning(action.previousValue, action.newValue)) } else { - currentPowerLevelsContent.users[state.userId] = action.newValue + if (action.newValue == currentPowerLevelsContent.usersDefault) { + currentPowerLevelsContent.users.remove(state.userId) + } else { + currentPowerLevelsContent.users[state.userId] = action.newValue + } viewModelScope.launch { _viewEvents.post(RoomMemberProfileViewEvents.Loading()) try { From 30774957ba8a282e99ecdb31286a7cc493980739 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 26 Jun 2020 23:40:23 +0200 Subject: [PATCH 2/3] Handle `/nick` command (#12) --- CHANGES.md | 2 +- .../features/home/room/detail/RoomDetailViewModel.kt | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2c9387b456..df0ddb6e64 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,7 @@ Features ✨: Improvements 🙌: - "Add Matrix app" menu is now always visible (#1495) - - Handle `/op` and `/deop` commands (#12) + - Handle `/op`, `/deop`, and `/nick` commands (#12) Bugfix 🐛: - Fix dark theme issue on login screen (#1097) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index a0c7447569..a4ed9d3ee9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -539,8 +539,8 @@ class RoomDetailViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.ChangeDisplayName -> { - // TODO - _viewEvents.post(RoomDetailViewEvents.SlashCommandNotImplemented) + handleChangeDisplayNameSlashCommand(slashCommandResult) + popDraft() } is ParsedCommand.DiscardSession -> { if (room.isEncrypted()) { @@ -685,6 +685,12 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun handleChangeDisplayNameSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayName) { + launchSlashCommandFlow { + session.setDisplayName(session.myUserId, changeDisplayName.displayName, it) + } + } + private fun handleKickSlashCommand(kick: ParsedCommand.KickUser) { launchSlashCommandFlow { room.kick(kick.userId, kick.reason, it) From cec79fed442ae7e3d9894e3c1c9d753694eba2a2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Sat, 27 Jun 2020 11:43:13 +0200 Subject: [PATCH 3/3] Mutualize code --- .../api/session/room/model/PowerLevelsContent.kt | 16 +++++++++++++++- .../room/powerlevels/PowerLevelsHelper.kt | 1 + .../home/room/detail/RoomDetailViewModel.kt | 7 +------ .../RoomMemberProfileViewModel.kt | 6 +----- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/PowerLevelsContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/PowerLevelsContent.kt index b52f7b09bf..a14190eb47 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/PowerLevelsContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/PowerLevelsContent.kt @@ -35,4 +35,18 @@ data class PowerLevelsContent( @Json(name = "users") val users: MutableMap = HashMap(), @Json(name = "state_default") val stateDefault: Int = Role.Moderator.value, @Json(name = "notifications") val notifications: Map = HashMap() -) +) { + /** + * Alter this content with a new power level for the specified user + * + * @param userId the userId to alter the power level of + * @param powerLevel the new power level, or null to set the default value. + */ + fun setUserPowerLevel(userId: String, powerLevel: Int?) { + if (powerLevel == null || powerLevel == usersDefault) { + users.remove(userId) + } else { + users[userId] = powerLevel + } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/powerlevels/PowerLevelsHelper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/powerlevels/PowerLevelsHelper.kt index 49141e3e86..f434859f6e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/powerlevels/PowerLevelsHelper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/powerlevels/PowerLevelsHelper.kt @@ -44,6 +44,7 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) { */ fun getUserRole(userId: String): Role { val value = getUserPowerLevelValue(userId) + // I think we should use powerLevelsContent.usersDefault, but Ganfra told me that it was like that on riot-Web return Role.fromValue(value, powerLevelsContent.eventsDefault) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index a4ed9d3ee9..b481c00be7 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -675,12 +675,7 @@ class RoomDetailViewModel @AssistedInject constructor( ?.toModel() ?: return launchSlashCommandFlow { - if (setUserPowerLevel.powerLevel == null) { - currentPowerLevelsContent.users.remove(setUserPowerLevel.userId) - } else { - currentPowerLevelsContent.users[setUserPowerLevel.userId] = setUserPowerLevel.powerLevel - } - + currentPowerLevelsContent.setUserPowerLevel(setUserPowerLevel.userId, setUserPowerLevel.powerLevel) room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, currentPowerLevelsContent.toContent(), it) } } diff --git a/vector/src/main/java/im/vector/riotx/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roommemberprofile/RoomMemberProfileViewModel.kt index 62f77e98c9..6fc1facbc3 100644 --- a/vector/src/main/java/im/vector/riotx/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -162,11 +162,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v } else if (action.askForValidation && state.isMine) { _viewEvents.post(RoomMemberProfileViewEvents.ShowPowerLevelDemoteWarning(action.previousValue, action.newValue)) } else { - if (action.newValue == currentPowerLevelsContent.usersDefault) { - currentPowerLevelsContent.users.remove(state.userId) - } else { - currentPowerLevelsContent.users[state.userId] = action.newValue - } + currentPowerLevelsContent.setUserPowerLevel(state.userId, action.newValue) viewModelScope.launch { _viewEvents.post(RoomMemberProfileViewEvents.Loading()) try {