From 9ec662ccdc9be0768bf4403252df5d961b46a8b0 Mon Sep 17 00:00:00 2001 From: fedrunov Date: Tue, 11 Jan 2022 10:17:29 +0100 Subject: [PATCH 1/4] replace "kick" with "remove" --- changelog.d/4865.misc | 1 + .../session/room/members/MembershipService.kt | 2 +- .../membership/DefaultMembershipService.kt | 2 +- .../im/vector/app/features/command/Command.kt | 2 +- .../app/features/command/CommandParser.kt | 10 +++--- .../app/features/command/ParsedCommand.kt | 2 +- .../composer/MessageComposerViewModel.kt | 8 ++--- .../RoomMemberProfileViewModel.kt | 2 +- vector/src/main/res/values/strings.xml | 32 +++++++++---------- 9 files changed, 31 insertions(+), 30 deletions(-) create mode 100644 changelog.d/4865.misc diff --git a/changelog.d/4865.misc b/changelog.d/4865.misc new file mode 100644 index 0000000000..a253ab24c7 --- /dev/null +++ b/changelog.d/4865.misc @@ -0,0 +1 @@ +"/kick" command is replaced with "/remove" \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt index 198d6677a0..6dacd9cfd1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt @@ -77,7 +77,7 @@ interface MembershipService { /** * Kick a user from the room */ - suspend fun kick(userId: String, reason: String? = null) + suspend fun remove(userId: String, reason: String? = null) /** * Join the room, or accept an invitation. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt index 6cf82dde44..49b58aa765 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt @@ -125,7 +125,7 @@ internal class DefaultMembershipService @AssistedInject constructor( membershipAdminTask.execute(params) } - override suspend fun kick(userId: String, reason: String?) { + override suspend fun remove(userId: String, reason: String?) { val params = MembershipAdminTask.Params(MembershipAdminTask.Type.KICK, roomId, userId, reason) membershipAdminTask.execute(params) } diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index 1950038691..c90d06a7b0 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -37,7 +37,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room, false), PART("/part", "[]", R.string.command_description_part_room, false), TOPIC("/topic", "", R.string.command_description_topic, false), - KICK_USER("/kick", " [reason]", R.string.command_description_kick_user, false), + REMOVE_USER("/remove", " [reason]", R.string.command_description_kick_user, false), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick, false), CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "", R.string.command_description_nick_for_room, false), ROOM_AVATAR("/roomavatar", "", R.string.command_description_room_avatar, true /* Since user has to know the mxc url */), diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index 4b2a4aa28c..22e1091c24 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -200,22 +200,22 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.INVITE) } } - Command.KICK_USER.command -> { + Command.REMOVE_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { - ParsedCommand.KickUser( + ParsedCommand.RemoveUser( userId, - textMessage.substring(Command.KICK_USER.length + userId.length) + textMessage.substring(Command.REMOVE_USER.length + userId.length) .trim() .takeIf { it.isNotBlank() } ) } else { - ParsedCommand.ErrorSyntax(Command.KICK_USER) + ParsedCommand.ErrorSyntax(Command.REMOVE_USER) } } else { - ParsedCommand.ErrorSyntax(Command.KICK_USER) + ParsedCommand.ErrorSyntax(Command.REMOVE_USER) } } Command.BAN_USER.command -> { diff --git a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt index 4f8d19abb6..584272f3f4 100644 --- a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt @@ -51,7 +51,7 @@ sealed class ParsedCommand { class JoinRoom(val roomAlias: String, val reason: String?) : ParsedCommand() class PartRoom(val roomAlias: String?) : ParsedCommand() class ChangeTopic(val topic: String) : ParsedCommand() - class KickUser(val userId: String, val reason: String?) : ParsedCommand() + class RemoveUser(val userId: String, val reason: String?) : ParsedCommand() class ChangeDisplayName(val displayName: String) : ParsedCommand() class ChangeDisplayNameForRoom(val displayName: String) : ParsedCommand() class ChangeRoomAvatar(val url: String) : ParsedCommand() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt index a63a06928a..d787978aa9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt @@ -217,8 +217,8 @@ class MessageComposerViewModel @AssistedInject constructor( is ParsedCommand.UnignoreUser -> { handleUnignoreSlashCommand(slashCommandResult) } - is ParsedCommand.KickUser -> { - handleKickSlashCommand(slashCommandResult) + is ParsedCommand.RemoveUser -> { + handleRemoveSlashCommand(slashCommandResult) } is ParsedCommand.JoinRoom -> { handleJoinToAnotherRoomSlashCommand(slashCommandResult) @@ -576,9 +576,9 @@ class MessageComposerViewModel @AssistedInject constructor( } } - private fun handleKickSlashCommand(kick: ParsedCommand.KickUser) { + private fun handleRemoveSlashCommand(removeUser: ParsedCommand.RemoveUser) { launchSlashCommandFlowSuspendable { - room.kick(kick.userId, kick.reason) + room.remove(removeUser.userId, removeUser.reason) } } 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 4f3d9d0776..d6ba11d929 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 @@ -254,7 +254,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor( viewModelScope.launch { try { _viewEvents.post(RoomMemberProfileViewEvents.Loading()) - room.kick(initialState.userId, action.reason) + room.remove(initialState.userId, action.reason) _viewEvents.post(RoomMemberProfileViewEvents.OnKickActionSuccess) } catch (failure: Throwable) { _viewEvents.post(RoomMemberProfileViewEvents.Failure(failure)) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index dbdf104dff..11a3eb0a0d 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -25,8 +25,8 @@ You left the room %1$s rejected the invitation You rejected the invitation - %1$s kicked %2$s - You kicked %1$s + %1$s removed %2$s + You removed %1$s %1$s unbanned %2$s You unbanned %1$s %1$s banned %2$s @@ -229,8 +229,8 @@ You left. Reason: %1$s %1$s rejected the invitation. Reason: %2$s You rejected the invitation. Reason: %1$s - %1$s kicked %2$s. Reason: %3$s - You kicked %1$s. Reason: %2$s + %1$s removed %2$s. Reason: %3$s + You removed %1$s. Reason: %2$s %1$s unbanned %2$s. Reason: %3$s You unbanned %1$s. Reason: %2$s %1$s banned %2$s. Reason: %3$s @@ -884,7 +884,7 @@ Remove from this room Ban Unban - Kick + Remove from chat Reset to normal user Make moderator Make admin @@ -908,15 +908,15 @@ Cancel invite Are you sure you want to cancel the invite for this user? - Kick user - Reason to kick - kicking user will remove them from this room.\n\nTo prevent them from joining again, you should ban them instead. - kicking user will remove them from this space.\n\nTo prevent them from joining again, you should ban them instead. + Remove user + Reason to remove + The user will be removed from this room.\n\nTo prevent them from joining again, you should ban them instead. + The user will be removed from this space.\n\nTo prevent them from joining again, you should ban them instead. Ban user Reason to ban Unban user - Banning user will kick them from this room and prevent them from joining again. - Banning user will kick them from this space and prevent them from joining again. + Banning user will remove them from this room and prevent them from joining again. + Banning user will remove them from this space and prevent them from joining again. Unbanning user will allow them to join the room again. Unbanning user will allow them to join the space again. @@ -996,7 +996,7 @@ Send messages Invite users Change settings - Kick users + Remove users Ban users Remove messages sent by others Notify everyone @@ -1323,9 +1323,9 @@ Show room member state events Show chat effects Use /confetti command or send a message containing ❄️ or 🎉 - Includes invite/join/left/kick/ban events and avatar/display name changes. + Includes invite/join/left/remove/ban events and avatar/display name changes. Show join and leave events - Invites, kicks, and bans are unaffected. + Invites, removes, and bans are unaffected. Show account events Includes avatar and display name changes. Vibrate when mentioning a user @@ -1853,7 +1853,7 @@ Joins room with given address Leave room Set the room topic - Kicks user with given id + Removes user with given id from this room Changes your display nickname Changes your display nickname in the current room only Changes the avatar of the current room @@ -1903,7 +1903,7 @@ The community admin has not provided a long description for this community. - You have been kicked from %1$s by %2$s + You have been removed from %1$s by %2$s You have been banned from %1$s by %2$s Reason: %1$s Rejoin From 2aabbf0aa6ded0d97a08c13aece00d6019395de5 Mon Sep 17 00:00:00 2001 From: fedrunov Date: Tue, 11 Jan 2022 12:23:26 +0100 Subject: [PATCH 2/4] added aliases to commands --- .../command/AutocompleteCommandPresenter.kt | 2 +- .../im/vector/app/features/command/Command.kt | 78 +++--- .../app/features/command/CommandParser.kt | 222 ++++++++---------- .../home/room/detail/RoomDetailFragment.kt | 2 +- .../composer/MessageComposerViewModel.kt | 2 +- 5 files changed, 147 insertions(+), 159 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandPresenter.kt index 5ad31aeaa6..9888f1e35e 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandPresenter.kt @@ -50,7 +50,7 @@ class AutocompleteCommandPresenter @Inject constructor(context: Context, if (query.isNullOrEmpty()) { true } else { - it.command.startsWith(query, 1, true) + it.startsWith(query) } } controller.setData(data) diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index c90d06a7b0..4edd62a488 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -24,42 +24,46 @@ import im.vector.app.R * the user can write theses messages to perform some actions * the list will be displayed in this order */ -enum class Command(val command: String, val parameters: String, @StringRes val description: Int, val isDevCommand: Boolean) { - EMOTE("/me", "", R.string.command_description_emote, false), - BAN_USER("/ban", " [reason]", R.string.command_description_ban_user, false), - UNBAN_USER("/unban", " [reason]", R.string.command_description_unban_user, false), - IGNORE_USER("/ignore", " [reason]", R.string.command_description_ignore_user, false), - UNIGNORE_USER("/unignore", "", R.string.command_description_unignore_user, false), - SET_USER_POWER_LEVEL("/op", " []", R.string.command_description_op_user, false), - RESET_USER_POWER_LEVEL("/deop", "", R.string.command_description_deop_user, false), - ROOM_NAME("/roomname", "", R.string.command_description_room_name, false), - INVITE("/invite", " [reason]", R.string.command_description_invite_user, false), - JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room, false), - PART("/part", "[]", R.string.command_description_part_room, false), - TOPIC("/topic", "", R.string.command_description_topic, false), - REMOVE_USER("/remove", " [reason]", R.string.command_description_kick_user, false), - CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick, false), - CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "", R.string.command_description_nick_for_room, false), - ROOM_AVATAR("/roomavatar", "", R.string.command_description_room_avatar, true /* Since user has to know the mxc url */), - CHANGE_AVATAR_FOR_ROOM("/myroomavatar", "", R.string.command_description_avatar_for_room, true /* Since user has to know the mxc url */), - MARKDOWN("/markdown", "", R.string.command_description_markdown, false), - RAINBOW("/rainbow", "", R.string.command_description_rainbow, false), - RAINBOW_EMOTE("/rainbowme", "", R.string.command_description_rainbow_emote, false), - CLEAR_SCALAR_TOKEN("/clear_scalar_token", "", R.string.command_description_clear_scalar_token, false), - SPOILER("/spoiler", "", R.string.command_description_spoiler, false), - SHRUG("/shrug", "", R.string.command_description_shrug, false), - LENNY("/lenny", "", R.string.command_description_lenny, false), - PLAIN("/plain", "", R.string.command_description_plain, false), - WHOIS("/whois", "", R.string.command_description_whois, false), - DISCARD_SESSION("/discardsession", "", R.string.command_description_discard_session, false), - CONFETTI("/confetti", "", R.string.command_confetti, false), - SNOWFALL("/snowfall", "", R.string.command_snow, false), - CREATE_SPACE("/createspace", " *", R.string.command_description_create_space, true), - ADD_TO_SPACE("/addToSpace", "spaceId", R.string.command_description_add_to_space, true), - JOIN_SPACE("/joinSpace", "spaceId", R.string.command_description_join_space, true), - LEAVE_ROOM("/leave", "", R.string.command_description_leave_room, true), - UPGRADE_ROOM("/upgraderoom", "newVersion", R.string.command_description_upgrade_room, true); +enum class Command(val command: String, val aliases: Array?, val parameters: String, @StringRes val description: Int, val isDevCommand: Boolean) { + EMOTE("/me", null, "", R.string.command_description_emote, false), + BAN_USER("/ban", null, " [reason]", R.string.command_description_ban_user, false), + UNBAN_USER("/unban", null, " [reason]", R.string.command_description_unban_user, false), + IGNORE_USER("/ignore", null, " [reason]", R.string.command_description_ignore_user, false), + UNIGNORE_USER("/unignore", null, "", R.string.command_description_unignore_user, false), + SET_USER_POWER_LEVEL("/op", null, " []", R.string.command_description_op_user, false), + RESET_USER_POWER_LEVEL("/deop", null, "", R.string.command_description_deop_user, false), + ROOM_NAME("/roomname", null, "", R.string.command_description_room_name, false), + INVITE("/invite", null, " [reason]", R.string.command_description_invite_user, false), + JOIN_ROOM("/join", null, " [reason]", R.string.command_description_join_room, false), + PART("/part", null, "[]", R.string.command_description_part_room, false), + TOPIC("/topic", null, "", R.string.command_description_topic, false), + REMOVE_USER("/remove", arrayOf("/kick"), " [reason]", R.string.command_description_kick_user, false), + CHANGE_DISPLAY_NAME("/nick", null, "", R.string.command_description_nick, false), + CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", null, "", R.string.command_description_nick_for_room, false), + ROOM_AVATAR("/roomavatar", null, "", R.string.command_description_room_avatar, true /* Since user has to know the mxc url */), + CHANGE_AVATAR_FOR_ROOM("/myroomavatar", null, "", R.string.command_description_avatar_for_room, true /* Since user has to know the mxc url */), + MARKDOWN("/markdown", null, "", R.string.command_description_markdown, false), + RAINBOW("/rainbow", null, "", R.string.command_description_rainbow, false), + RAINBOW_EMOTE("/rainbowme", null, "", R.string.command_description_rainbow_emote, false), + CLEAR_SCALAR_TOKEN("/clear_scalar_token", null, "", R.string.command_description_clear_scalar_token, false), + SPOILER("/spoiler", null, "", R.string.command_description_spoiler, false), + SHRUG("/shrug", null, "", R.string.command_description_shrug, false), + LENNY("/lenny", null, "", R.string.command_description_lenny, false), + PLAIN("/plain", null, "", R.string.command_description_plain, false), + WHOIS("/whois", null, "", R.string.command_description_whois, false), + DISCARD_SESSION("/discardsession", null, "", R.string.command_description_discard_session, false), + CONFETTI("/confetti", null, "", R.string.command_confetti, false), + SNOWFALL("/snowfall", null, "", R.string.command_snow, false), + CREATE_SPACE("/createspace", null, " *", R.string.command_description_create_space, true), + ADD_TO_SPACE("/addToSpace", null, "spaceId", R.string.command_description_add_to_space, true), + JOIN_SPACE("/joinSpace", null, "spaceId", R.string.command_description_join_space, true), + LEAVE_ROOM("/leave", null, "", R.string.command_description_leave_room, true), + UPGRADE_ROOM("/upgraderoom", null, "newVersion", R.string.command_description_upgrade_room, true); - val length - get() = command.length + 1 + val allAliases = arrayOf(command, *aliases.orEmpty()) + + fun matches(inputCommand: CharSequence) = allAliases.any { it.contentEquals(inputCommand, true) } + + fun startsWith(input: CharSequence) = + allAliases.any { it.startsWith(input, 1, true) } } diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index 22e1091c24..c6de96859a 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -32,12 +32,12 @@ object CommandParser { * @param textMessage the text message * @return a parsed slash command (ok or error) */ - fun parseSplashCommand(textMessage: CharSequence): ParsedCommand { + fun parseSlashCommand(textMessage: CharSequence): ParsedCommand { // check if it has the Slash marker if (!textMessage.startsWith("/")) { return ParsedCommand.ErrorNotACommand } else { - Timber.v("parseSplashCommand") + Timber.v("parseSlashCommand") // "/" only if (textMessage.length == 1) { @@ -52,7 +52,7 @@ object CommandParser { val messageParts = try { textMessage.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() } } catch (e: Exception) { - Timber.e(e, "## manageSplashCommand() : split failed") + Timber.e(e, "## manageSlashCommand() : split failed") null } @@ -61,35 +61,32 @@ object CommandParser { return ParsedCommand.ErrorEmptySlashCommand } - return when (val slashCommand = messageParts.first()) { - Command.PLAIN.command -> { - val text = textMessage.substring(Command.PLAIN.command.length).trim() + val slashCommand = messageParts.first() + val message = textMessage.substring(slashCommand.length).trim() - if (text.isNotEmpty()) { - ParsedCommand.SendPlainText(text) + return when { + Command.PLAIN.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.SendPlainText(message = message) } else { ParsedCommand.ErrorSyntax(Command.PLAIN) } } - Command.CHANGE_DISPLAY_NAME.command -> { - val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() - - if (newDisplayName.isNotEmpty()) { - ParsedCommand.ChangeDisplayName(newDisplayName) + Command.CHANGE_DISPLAY_NAME.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.ChangeDisplayName(displayName = message) } else { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME) } } - Command.CHANGE_DISPLAY_NAME_FOR_ROOM.command -> { - val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME_FOR_ROOM.command.length).trim() - - if (newDisplayName.isNotEmpty()) { - ParsedCommand.ChangeDisplayNameForRoom(newDisplayName) + Command.CHANGE_DISPLAY_NAME_FOR_ROOM.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.ChangeDisplayNameForRoom(displayName = message) } else { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME_FOR_ROOM) } } - Command.ROOM_AVATAR.command -> { + Command.ROOM_AVATAR.matches(slashCommand) -> { if (messageParts.size == 2) { val url = messageParts[1] @@ -102,7 +99,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) } } - Command.CHANGE_AVATAR_FOR_ROOM.command -> { + Command.CHANGE_AVATAR_FOR_ROOM.matches(slashCommand) -> { if (messageParts.size == 2) { val url = messageParts[1] @@ -115,40 +112,42 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) } } - Command.TOPIC.command -> { - val newTopic = textMessage.substring(Command.TOPIC.command.length).trim() - - if (newTopic.isNotEmpty()) { - ParsedCommand.ChangeTopic(newTopic) + Command.TOPIC.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.ChangeTopic(topic = message) } else { ParsedCommand.ErrorSyntax(Command.TOPIC) } } - Command.EMOTE.command -> { - val message = textMessage.subSequence(Command.EMOTE.command.length, textMessage.length).trim() - - ParsedCommand.SendEmote(message) + Command.EMOTE.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.SendEmote(message) + } else { + ParsedCommand.ErrorSyntax(Command.EMOTE) + } } - Command.RAINBOW.command -> { - val message = textMessage.subSequence(Command.RAINBOW.command.length, textMessage.length).trim() - - ParsedCommand.SendRainbow(message) + Command.RAINBOW.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.SendRainbow(message) + } else { + ParsedCommand.ErrorSyntax(Command.RAINBOW) + } } - Command.RAINBOW_EMOTE.command -> { - val message = textMessage.subSequence(Command.RAINBOW_EMOTE.command.length, textMessage.length).trim() - - ParsedCommand.SendRainbowEmote(message) + Command.RAINBOW_EMOTE.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.SendRainbowEmote(message) + } else { + ParsedCommand.ErrorSyntax(Command.RAINBOW_EMOTE) + } } - Command.JOIN_ROOM.command -> { + Command.JOIN_ROOM.matches(slashCommand) -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] if (roomAlias.isNotEmpty()) { ParsedCommand.JoinRoom( roomAlias, - textMessage.substring(Command.JOIN_ROOM.length + roomAlias.length) - .trim() - .takeIf { it.isNotBlank() } + trimParts(textMessage, messageParts.take(2)) ) } else { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) @@ -157,23 +156,21 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) } } - Command.PART.command -> { + Command.PART.matches(slashCommand) -> { when (messageParts.size) { 1 -> ParsedCommand.PartRoom(null) 2 -> ParsedCommand.PartRoom(messageParts[1]) else -> ParsedCommand.ErrorSyntax(Command.PART) } } - Command.ROOM_NAME.command -> { - val newRoomName = textMessage.substring(Command.ROOM_NAME.command.length).trim() - - if (newRoomName.isNotEmpty()) { - ParsedCommand.ChangeRoomName(newRoomName) + Command.ROOM_NAME.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.ChangeRoomName(name = message) } else { ParsedCommand.ErrorSyntax(Command.ROOM_NAME) } } - Command.INVITE.command -> { + Command.INVITE.matches(slashCommand) -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -181,9 +178,7 @@ object CommandParser { MatrixPatterns.isUserId(userId) -> { ParsedCommand.Invite( userId, - textMessage.substring(Command.INVITE.length + userId.length) - .trim() - .takeIf { it.isNotBlank() } + trimParts(textMessage, messageParts.take(2)) ) } userId.isEmail() -> { @@ -200,16 +195,14 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.INVITE) } } - Command.REMOVE_USER.command -> { + Command.REMOVE_USER.matches(slashCommand) -> { if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { ParsedCommand.RemoveUser( userId, - textMessage.substring(Command.REMOVE_USER.length + userId.length) - .trim() - .takeIf { it.isNotBlank() } + trimParts(textMessage, messageParts.take(2)) ) } else { ParsedCommand.ErrorSyntax(Command.REMOVE_USER) @@ -218,16 +211,14 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.REMOVE_USER) } } - Command.BAN_USER.command -> { + Command.BAN_USER.matches(slashCommand) -> { if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { ParsedCommand.BanUser( userId, - textMessage.substring(Command.BAN_USER.length + userId.length) - .trim() - .takeIf { it.isNotBlank() } + trimParts(textMessage, messageParts.take(2)) ) } else { ParsedCommand.ErrorSyntax(Command.BAN_USER) @@ -236,16 +227,14 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.BAN_USER) } } - Command.UNBAN_USER.command -> { + Command.UNBAN_USER.matches(slashCommand) -> { if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { ParsedCommand.UnbanUser( userId, - textMessage.substring(Command.UNBAN_USER.length + userId.length) - .trim() - .takeIf { it.isNotBlank() } + trimParts(textMessage, messageParts.take(2)) ) } else { ParsedCommand.ErrorSyntax(Command.UNBAN_USER) @@ -254,7 +243,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.UNBAN_USER) } } - Command.IGNORE_USER.command -> { + Command.IGNORE_USER.matches(slashCommand) -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -267,7 +256,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.IGNORE_USER) } } - Command.UNIGNORE_USER.command -> { + Command.UNIGNORE_USER.matches(slashCommand) -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -280,7 +269,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) } } - Command.SET_USER_POWER_LEVEL.command -> { + Command.SET_USER_POWER_LEVEL.matches(slashCommand) -> { if (messageParts.size == 3) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -300,7 +289,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.RESET_USER_POWER_LEVEL.command -> { + Command.RESET_USER_POWER_LEVEL.matches(slashCommand) -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -313,7 +302,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.MARKDOWN.command -> { + Command.MARKDOWN.matches(slashCommand) -> { if (messageParts.size == 2) { when { "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) @@ -324,31 +313,34 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.MARKDOWN) } } - Command.CLEAR_SCALAR_TOKEN.command -> { + Command.CLEAR_SCALAR_TOKEN.matches(slashCommand) -> { if (messageParts.size == 1) { ParsedCommand.ClearScalarToken } else { ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) } } - Command.SPOILER.command -> { - val message = textMessage.substring(Command.SPOILER.command.length).trim() - ParsedCommand.SendSpoiler(message) + Command.SPOILER.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.SendSpoiler(message) + } else { + ParsedCommand.ErrorSyntax(Command.SPOILER) + } } - Command.SHRUG.command -> { - val message = textMessage.substring(Command.SHRUG.command.length).trim() - + Command.SHRUG.matches(slashCommand) -> { ParsedCommand.SendShrug(message) } - Command.LENNY.command -> { - val message = textMessage.substring(Command.LENNY.command.length).trim() - + Command.LENNY.matches(slashCommand) -> { ParsedCommand.SendLenny(message) } - Command.DISCARD_SESSION.command -> { - ParsedCommand.DiscardSession + Command.DISCARD_SESSION.matches(slashCommand) -> { + if (messageParts.size == 1) { + ParsedCommand.DiscardSession + } else { + ParsedCommand.ErrorSyntax(Command.DISCARD_SESSION) + } } - Command.WHOIS.command -> { + Command.WHOIS.matches(slashCommand) -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -361,57 +353,49 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.WHOIS) } } - Command.CONFETTI.command -> { - val message = textMessage.substring(Command.CONFETTI.command.length).trim() + Command.CONFETTI.matches(slashCommand) -> { ParsedCommand.SendChatEffect(ChatEffect.CONFETTI, message) } - Command.SNOWFALL.command -> { - val message = textMessage.substring(Command.SNOWFALL.command.length).trim() + Command.SNOWFALL.matches(slashCommand) -> { ParsedCommand.SendChatEffect(ChatEffect.SNOWFALL, message) } - Command.CREATE_SPACE.command -> { - val rawCommand = textMessage.substring(Command.CREATE_SPACE.command.length).trim() - val split = rawCommand.split(" ").map { it.trim() } - if (split.isEmpty()) { - ParsedCommand.ErrorSyntax(Command.CREATE_SPACE) - } else { + Command.CREATE_SPACE.matches(slashCommand) -> { + if (messageParts.size >= 2) { ParsedCommand.CreateSpace( - split[0], - split.subList(1, split.size) + messageParts[1], + messageParts.drop(2) ) - } - } - Command.ADD_TO_SPACE.command -> { - val rawCommand = textMessage.substring(Command.ADD_TO_SPACE.command.length).trim() - ParsedCommand.AddToSpace( - rawCommand - ) - } - Command.JOIN_SPACE.command -> { - val spaceIdOrAlias = textMessage.substring(Command.JOIN_SPACE.command.length).trim() - ParsedCommand.JoinSpace( - spaceIdOrAlias - ) - } - Command.LEAVE_ROOM.command -> { - val spaceIdOrAlias = textMessage.substring(Command.LEAVE_ROOM.command.length).trim() - ParsedCommand.LeaveRoom( - spaceIdOrAlias - ) - } - Command.UPGRADE_ROOM.command -> { - val newVersion = textMessage.substring(Command.UPGRADE_ROOM.command.length).trim() - if (newVersion.isEmpty()) { - ParsedCommand.ErrorSyntax(Command.UPGRADE_ROOM) } else { - ParsedCommand.UpgradeRoom(newVersion) + ParsedCommand.ErrorSyntax(Command.CREATE_SPACE) } } - else -> { + Command.ADD_TO_SPACE.matches(slashCommand) -> { + ParsedCommand.AddToSpace(spaceId = message) + } + Command.JOIN_SPACE.matches(slashCommand) -> { + ParsedCommand.JoinSpace(spaceIdOrAlias = message) + } + Command.LEAVE_ROOM.matches(slashCommand) -> { + ParsedCommand.LeaveRoom(roomId = message) + } + Command.UPGRADE_ROOM.matches(slashCommand) -> { + if (message.isNotEmpty()) { + ParsedCommand.UpgradeRoom(newVersion = message) + } else { + ParsedCommand.ErrorSyntax(Command.UPGRADE_ROOM) + } + } + else -> { // Unknown command ParsedCommand.ErrorUnknownSlashCommand(slashCommand) } } } } + + private fun trimParts(message: CharSequence, messageParts: List): String? { + val partsSize = messageParts.sumOf { it.length } + val gapsNumber = messageParts.size - 1 + return message.substring(partsSize + gapsNumber).trim().takeIf { it.isNotEmpty() } + } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 566cb2d2de..eaa684dea1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -2098,7 +2098,7 @@ class RoomDetailFragment @Inject constructor( userId == session.myUserId) { // Empty composer, current user: start an emote views.composerLayout.views.composerEditText.setText(Command.EMOTE.command + " ") - views.composerLayout.views.composerEditText.setSelection(Command.EMOTE.length) + views.composerLayout.views.composerEditText.setSelection(Command.EMOTE.command.length + 1) } else { val roomMember = roomDetailViewModel.getMember(userId) // TODO move logic outside of fragment diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt index d787978aa9..e907db0328 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt @@ -161,7 +161,7 @@ class MessageComposerViewModel @AssistedInject constructor( withState { state -> when (state.sendMode) { is SendMode.Regular -> { - when (val slashCommandResult = CommandParser.parseSplashCommand(action.text)) { + when (val slashCommandResult = CommandParser.parseSlashCommand(action.text)) { is ParsedCommand.ErrorNotACommand -> { // Send the text message to the room room.sendTextMessage(action.text, autoMarkdown = action.autoMarkdown) From 9fa38c5cc5d27d00c1e9faf74356f214e50d4ee3 Mon Sep 17 00:00:00 2001 From: fedrunov Date: Tue, 11 Jan 2022 15:50:51 +0100 Subject: [PATCH 3/4] web version aliases --- .../src/main/java/im/vector/app/features/command/Command.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index 4edd62a488..385cf1f3db 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -34,12 +34,12 @@ enum class Command(val command: String, val aliases: Array?, val p RESET_USER_POWER_LEVEL("/deop", null, "", R.string.command_description_deop_user, false), ROOM_NAME("/roomname", null, "", R.string.command_description_room_name, false), INVITE("/invite", null, " [reason]", R.string.command_description_invite_user, false), - JOIN_ROOM("/join", null, " [reason]", R.string.command_description_join_room, false), + JOIN_ROOM("/join", arrayOf("/j", "/goto"), " [reason]", R.string.command_description_join_room, false), PART("/part", null, "[]", R.string.command_description_part_room, false), TOPIC("/topic", null, "", R.string.command_description_topic, false), REMOVE_USER("/remove", arrayOf("/kick"), " [reason]", R.string.command_description_kick_user, false), CHANGE_DISPLAY_NAME("/nick", null, "", R.string.command_description_nick, false), - CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", null, "", R.string.command_description_nick_for_room, false), + CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", arrayOf("/roomnick"), "", R.string.command_description_nick_for_room, false), ROOM_AVATAR("/roomavatar", null, "", R.string.command_description_room_avatar, true /* Since user has to know the mxc url */), CHANGE_AVATAR_FOR_ROOM("/myroomavatar", null, "", R.string.command_description_avatar_for_room, true /* Since user has to know the mxc url */), MARKDOWN("/markdown", null, "", R.string.command_description_markdown, false), From d92e0e48f68d3c4b7b4d50e219701146106e9a68 Mon Sep 17 00:00:00 2001 From: fedrunov Date: Thu, 13 Jan 2022 17:50:38 +0100 Subject: [PATCH 4/4] code review changes --- changelog.d/4865.misc | 2 +- .../api/session/room/members/MembershipService.kt | 5 ++++- .../java/im/vector/app/features/command/Command.kt | 6 +++++- .../im/vector/app/features/command/CommandParser.kt | 12 ++++++++++-- vector/src/main/res/values/strings.xml | 1 + 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/changelog.d/4865.misc b/changelog.d/4865.misc index a253ab24c7..291c4a099f 100644 --- a/changelog.d/4865.misc +++ b/changelog.d/4865.misc @@ -1 +1 @@ -"/kick" command is replaced with "/remove" \ No newline at end of file +"/kick" command is replaced with "/remove". Also replaced all occurrences in string resources diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt index 6dacd9cfd1..d5bc65c142 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt @@ -75,10 +75,13 @@ interface MembershipService { suspend fun unban(userId: String, reason: String? = null) /** - * Kick a user from the room + * Remove a user from the room */ suspend fun remove(userId: String, reason: String? = null) + @Deprecated("Use remove instead", ReplaceWith("remove(userId, reason)")) + suspend fun kick(userId: String, reason: String? = null) = remove(userId, reason) + /** * Join the room, or accept an invitation. */ diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index 385cf1f3db..f7390282f2 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -24,7 +24,11 @@ import im.vector.app.R * the user can write theses messages to perform some actions * the list will be displayed in this order */ -enum class Command(val command: String, val aliases: Array?, val parameters: String, @StringRes val description: Int, val isDevCommand: Boolean) { +enum class Command(val command: String, + val aliases: Array?, + val parameters: String, + @StringRes val description: Int, + val isDevCommand: Boolean) { EMOTE("/me", null, "", R.string.command_description_emote, false), BAN_USER("/ban", null, " [reason]", R.string.command_description_ban_user, false), UNBAN_USER("/unban", null, " [reason]", R.string.command_description_unban_user, false), diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index c6de96859a..f5861c7c53 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -370,10 +370,18 @@ object CommandParser { } } Command.ADD_TO_SPACE.matches(slashCommand) -> { - ParsedCommand.AddToSpace(spaceId = message) + if (messageParts.size == 1) { + ParsedCommand.AddToSpace(spaceId = message) + } else { + ParsedCommand.ErrorSyntax(Command.ADD_TO_SPACE) + } } Command.JOIN_SPACE.matches(slashCommand) -> { - ParsedCommand.JoinSpace(spaceIdOrAlias = message) + if (messageParts.size == 1) { + ParsedCommand.JoinSpace(spaceIdOrAlias = message) + } else { + ParsedCommand.ErrorSyntax(Command.JOIN_SPACE) + } } Command.LEAVE_ROOM.matches(slashCommand) -> { ParsedCommand.LeaveRoom(roomId = message) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 11a3eb0a0d..265758c673 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -25,6 +25,7 @@ You left the room %1$s rejected the invitation You rejected the invitation + %1$s removed %2$s You removed %1$s %1$s unbanned %2$s