added aliases to commands

This commit is contained in:
fedrunov 2022-01-11 12:23:26 +01:00
parent 9ec662ccdc
commit 2aabbf0aa6
5 changed files with 147 additions and 159 deletions

View File

@ -50,7 +50,7 @@ class AutocompleteCommandPresenter @Inject constructor(context: Context,
if (query.isNullOrEmpty()) { if (query.isNullOrEmpty()) {
true true
} else { } else {
it.command.startsWith(query, 1, true) it.startsWith(query)
} }
} }
controller.setData(data) controller.setData(data)

View File

@ -24,42 +24,46 @@ import im.vector.app.R
* the user can write theses messages to perform some actions * the user can write theses messages to perform some actions
* the list will be displayed in this order * the list will be displayed in this order
*/ */
enum class Command(val command: String, val parameters: String, @StringRes val description: Int, val isDevCommand: Boolean) { enum class Command(val command: String, val aliases: Array<CharSequence>?, val parameters: String, @StringRes val description: Int, val isDevCommand: Boolean) {
EMOTE("/me", "<message>", R.string.command_description_emote, false), EMOTE("/me", null, "<message>", R.string.command_description_emote, false),
BAN_USER("/ban", "<user-id> [reason]", R.string.command_description_ban_user, false), BAN_USER("/ban", null, "<user-id> [reason]", R.string.command_description_ban_user, false),
UNBAN_USER("/unban", "<user-id> [reason]", R.string.command_description_unban_user, false), UNBAN_USER("/unban", null, "<user-id> [reason]", R.string.command_description_unban_user, false),
IGNORE_USER("/ignore", "<user-id> [reason]", R.string.command_description_ignore_user, false), IGNORE_USER("/ignore", null, "<user-id> [reason]", R.string.command_description_ignore_user, false),
UNIGNORE_USER("/unignore", "<user-id>", R.string.command_description_unignore_user, false), UNIGNORE_USER("/unignore", null, "<user-id>", R.string.command_description_unignore_user, false),
SET_USER_POWER_LEVEL("/op", "<user-id> [<power-level>]", R.string.command_description_op_user, false), SET_USER_POWER_LEVEL("/op", null, "<user-id> [<power-level>]", R.string.command_description_op_user, false),
RESET_USER_POWER_LEVEL("/deop", "<user-id>", R.string.command_description_deop_user, false), RESET_USER_POWER_LEVEL("/deop", null, "<user-id>", R.string.command_description_deop_user, false),
ROOM_NAME("/roomname", "<name>", R.string.command_description_room_name, false), ROOM_NAME("/roomname", null, "<name>", R.string.command_description_room_name, false),
INVITE("/invite", "<user-id> [reason]", R.string.command_description_invite_user, false), INVITE("/invite", null, "<user-id> [reason]", R.string.command_description_invite_user, false),
JOIN_ROOM("/join", "<room-address> [reason]", R.string.command_description_join_room, false), JOIN_ROOM("/join", null, "<room-address> [reason]", R.string.command_description_join_room, false),
PART("/part", "[<room-address>]", R.string.command_description_part_room, false), PART("/part", null, "[<room-address>]", R.string.command_description_part_room, false),
TOPIC("/topic", "<topic>", R.string.command_description_topic, false), TOPIC("/topic", null, "<topic>", R.string.command_description_topic, false),
REMOVE_USER("/remove", "<user-id> [reason]", R.string.command_description_kick_user, false), REMOVE_USER("/remove", arrayOf("/kick"), "<user-id> [reason]", R.string.command_description_kick_user, false),
CHANGE_DISPLAY_NAME("/nick", "<display-name>", R.string.command_description_nick, false), CHANGE_DISPLAY_NAME("/nick", null, "<display-name>", R.string.command_description_nick, false),
CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "<display-name>", R.string.command_description_nick_for_room, false), CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", null, "<display-name>", R.string.command_description_nick_for_room, false),
ROOM_AVATAR("/roomavatar", "<mxc_url>", R.string.command_description_room_avatar, true /* Since user has to know the mxc url */), ROOM_AVATAR("/roomavatar", null, "<mxc_url>", R.string.command_description_room_avatar, true /* Since user has to know the mxc url */),
CHANGE_AVATAR_FOR_ROOM("/myroomavatar", "<mxc_url>", R.string.command_description_avatar_for_room, true /* Since user has to know the mxc url */), CHANGE_AVATAR_FOR_ROOM("/myroomavatar", null, "<mxc_url>", R.string.command_description_avatar_for_room, true /* Since user has to know the mxc url */),
MARKDOWN("/markdown", "<on|off>", R.string.command_description_markdown, false), MARKDOWN("/markdown", null, "<on|off>", R.string.command_description_markdown, false),
RAINBOW("/rainbow", "<message>", R.string.command_description_rainbow, false), RAINBOW("/rainbow", null, "<message>", R.string.command_description_rainbow, false),
RAINBOW_EMOTE("/rainbowme", "<message>", R.string.command_description_rainbow_emote, false), RAINBOW_EMOTE("/rainbowme", null, "<message>", R.string.command_description_rainbow_emote, false),
CLEAR_SCALAR_TOKEN("/clear_scalar_token", "", R.string.command_description_clear_scalar_token, false), CLEAR_SCALAR_TOKEN("/clear_scalar_token", null, "", R.string.command_description_clear_scalar_token, false),
SPOILER("/spoiler", "<message>", R.string.command_description_spoiler, false), SPOILER("/spoiler", null, "<message>", R.string.command_description_spoiler, false),
SHRUG("/shrug", "<message>", R.string.command_description_shrug, false), SHRUG("/shrug", null, "<message>", R.string.command_description_shrug, false),
LENNY("/lenny", "<message>", R.string.command_description_lenny, false), LENNY("/lenny", null, "<message>", R.string.command_description_lenny, false),
PLAIN("/plain", "<message>", R.string.command_description_plain, false), PLAIN("/plain", null, "<message>", R.string.command_description_plain, false),
WHOIS("/whois", "<user-id>", R.string.command_description_whois, false), WHOIS("/whois", null, "<user-id>", R.string.command_description_whois, false),
DISCARD_SESSION("/discardsession", "", R.string.command_description_discard_session, false), DISCARD_SESSION("/discardsession", null, "", R.string.command_description_discard_session, false),
CONFETTI("/confetti", "<message>", R.string.command_confetti, false), CONFETTI("/confetti", null, "<message>", R.string.command_confetti, false),
SNOWFALL("/snowfall", "<message>", R.string.command_snow, false), SNOWFALL("/snowfall", null, "<message>", R.string.command_snow, false),
CREATE_SPACE("/createspace", "<name> <invitee>*", R.string.command_description_create_space, true), CREATE_SPACE("/createspace", null, "<name> <invitee>*", R.string.command_description_create_space, true),
ADD_TO_SPACE("/addToSpace", "spaceId", R.string.command_description_add_to_space, true), ADD_TO_SPACE("/addToSpace", null, "spaceId", R.string.command_description_add_to_space, true),
JOIN_SPACE("/joinSpace", "spaceId", R.string.command_description_join_space, true), JOIN_SPACE("/joinSpace", null, "spaceId", R.string.command_description_join_space, true),
LEAVE_ROOM("/leave", "<roomId?>", R.string.command_description_leave_room, true), LEAVE_ROOM("/leave", null, "<roomId?>", R.string.command_description_leave_room, true),
UPGRADE_ROOM("/upgraderoom", "newVersion", R.string.command_description_upgrade_room, true); UPGRADE_ROOM("/upgraderoom", null, "newVersion", R.string.command_description_upgrade_room, true);
val length val allAliases = arrayOf(command, *aliases.orEmpty())
get() = command.length + 1
fun matches(inputCommand: CharSequence) = allAliases.any { it.contentEquals(inputCommand, true) }
fun startsWith(input: CharSequence) =
allAliases.any { it.startsWith(input, 1, true) }
} }

View File

@ -32,12 +32,12 @@ object CommandParser {
* @param textMessage the text message * @param textMessage the text message
* @return a parsed slash command (ok or error) * @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 // check if it has the Slash marker
if (!textMessage.startsWith("/")) { if (!textMessage.startsWith("/")) {
return ParsedCommand.ErrorNotACommand return ParsedCommand.ErrorNotACommand
} else { } else {
Timber.v("parseSplashCommand") Timber.v("parseSlashCommand")
// "/" only // "/" only
if (textMessage.length == 1) { if (textMessage.length == 1) {
@ -52,7 +52,7 @@ object CommandParser {
val messageParts = try { val messageParts = try {
textMessage.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() } textMessage.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## manageSplashCommand() : split failed") Timber.e(e, "## manageSlashCommand() : split failed")
null null
} }
@ -61,35 +61,32 @@ object CommandParser {
return ParsedCommand.ErrorEmptySlashCommand return ParsedCommand.ErrorEmptySlashCommand
} }
return when (val slashCommand = messageParts.first()) { val slashCommand = messageParts.first()
Command.PLAIN.command -> { val message = textMessage.substring(slashCommand.length).trim()
val text = textMessage.substring(Command.PLAIN.command.length).trim()
if (text.isNotEmpty()) { return when {
ParsedCommand.SendPlainText(text) Command.PLAIN.matches(slashCommand) -> {
if (message.isNotEmpty()) {
ParsedCommand.SendPlainText(message = message)
} else { } else {
ParsedCommand.ErrorSyntax(Command.PLAIN) ParsedCommand.ErrorSyntax(Command.PLAIN)
} }
} }
Command.CHANGE_DISPLAY_NAME.command -> { Command.CHANGE_DISPLAY_NAME.matches(slashCommand) -> {
val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() if (message.isNotEmpty()) {
ParsedCommand.ChangeDisplayName(displayName = message)
if (newDisplayName.isNotEmpty()) {
ParsedCommand.ChangeDisplayName(newDisplayName)
} else { } else {
ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME) ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME)
} }
} }
Command.CHANGE_DISPLAY_NAME_FOR_ROOM.command -> { Command.CHANGE_DISPLAY_NAME_FOR_ROOM.matches(slashCommand) -> {
val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME_FOR_ROOM.command.length).trim() if (message.isNotEmpty()) {
ParsedCommand.ChangeDisplayNameForRoom(displayName = message)
if (newDisplayName.isNotEmpty()) {
ParsedCommand.ChangeDisplayNameForRoom(newDisplayName)
} else { } else {
ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME_FOR_ROOM) ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME_FOR_ROOM)
} }
} }
Command.ROOM_AVATAR.command -> { Command.ROOM_AVATAR.matches(slashCommand) -> {
if (messageParts.size == 2) { if (messageParts.size == 2) {
val url = messageParts[1] val url = messageParts[1]
@ -102,7 +99,7 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR)
} }
} }
Command.CHANGE_AVATAR_FOR_ROOM.command -> { Command.CHANGE_AVATAR_FOR_ROOM.matches(slashCommand) -> {
if (messageParts.size == 2) { if (messageParts.size == 2) {
val url = messageParts[1] val url = messageParts[1]
@ -115,40 +112,42 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM)
} }
} }
Command.TOPIC.command -> { Command.TOPIC.matches(slashCommand) -> {
val newTopic = textMessage.substring(Command.TOPIC.command.length).trim() if (message.isNotEmpty()) {
ParsedCommand.ChangeTopic(topic = message)
if (newTopic.isNotEmpty()) {
ParsedCommand.ChangeTopic(newTopic)
} else { } else {
ParsedCommand.ErrorSyntax(Command.TOPIC) ParsedCommand.ErrorSyntax(Command.TOPIC)
} }
} }
Command.EMOTE.command -> { Command.EMOTE.matches(slashCommand) -> {
val message = textMessage.subSequence(Command.EMOTE.command.length, textMessage.length).trim() if (message.isNotEmpty()) {
ParsedCommand.SendEmote(message) ParsedCommand.SendEmote(message)
} else {
ParsedCommand.ErrorSyntax(Command.EMOTE)
} }
Command.RAINBOW.command -> { }
val message = textMessage.subSequence(Command.RAINBOW.command.length, textMessage.length).trim() Command.RAINBOW.matches(slashCommand) -> {
if (message.isNotEmpty()) {
ParsedCommand.SendRainbow(message) ParsedCommand.SendRainbow(message)
} else {
ParsedCommand.ErrorSyntax(Command.RAINBOW)
} }
Command.RAINBOW_EMOTE.command -> { }
val message = textMessage.subSequence(Command.RAINBOW_EMOTE.command.length, textMessage.length).trim() Command.RAINBOW_EMOTE.matches(slashCommand) -> {
if (message.isNotEmpty()) {
ParsedCommand.SendRainbowEmote(message) ParsedCommand.SendRainbowEmote(message)
} else {
ParsedCommand.ErrorSyntax(Command.RAINBOW_EMOTE)
} }
Command.JOIN_ROOM.command -> { }
Command.JOIN_ROOM.matches(slashCommand) -> {
if (messageParts.size >= 2) { if (messageParts.size >= 2) {
val roomAlias = messageParts[1] val roomAlias = messageParts[1]
if (roomAlias.isNotEmpty()) { if (roomAlias.isNotEmpty()) {
ParsedCommand.JoinRoom( ParsedCommand.JoinRoom(
roomAlias, roomAlias,
textMessage.substring(Command.JOIN_ROOM.length + roomAlias.length) trimParts(textMessage, messageParts.take(2))
.trim()
.takeIf { it.isNotBlank() }
) )
} else { } else {
ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) ParsedCommand.ErrorSyntax(Command.JOIN_ROOM)
@ -157,23 +156,21 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) ParsedCommand.ErrorSyntax(Command.JOIN_ROOM)
} }
} }
Command.PART.command -> { Command.PART.matches(slashCommand) -> {
when (messageParts.size) { when (messageParts.size) {
1 -> ParsedCommand.PartRoom(null) 1 -> ParsedCommand.PartRoom(null)
2 -> ParsedCommand.PartRoom(messageParts[1]) 2 -> ParsedCommand.PartRoom(messageParts[1])
else -> ParsedCommand.ErrorSyntax(Command.PART) else -> ParsedCommand.ErrorSyntax(Command.PART)
} }
} }
Command.ROOM_NAME.command -> { Command.ROOM_NAME.matches(slashCommand) -> {
val newRoomName = textMessage.substring(Command.ROOM_NAME.command.length).trim() if (message.isNotEmpty()) {
ParsedCommand.ChangeRoomName(name = message)
if (newRoomName.isNotEmpty()) {
ParsedCommand.ChangeRoomName(newRoomName)
} else { } else {
ParsedCommand.ErrorSyntax(Command.ROOM_NAME) ParsedCommand.ErrorSyntax(Command.ROOM_NAME)
} }
} }
Command.INVITE.command -> { Command.INVITE.matches(slashCommand) -> {
if (messageParts.size >= 2) { if (messageParts.size >= 2) {
val userId = messageParts[1] val userId = messageParts[1]
@ -181,9 +178,7 @@ object CommandParser {
MatrixPatterns.isUserId(userId) -> { MatrixPatterns.isUserId(userId) -> {
ParsedCommand.Invite( ParsedCommand.Invite(
userId, userId,
textMessage.substring(Command.INVITE.length + userId.length) trimParts(textMessage, messageParts.take(2))
.trim()
.takeIf { it.isNotBlank() }
) )
} }
userId.isEmail() -> { userId.isEmail() -> {
@ -200,16 +195,14 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.INVITE) ParsedCommand.ErrorSyntax(Command.INVITE)
} }
} }
Command.REMOVE_USER.command -> { Command.REMOVE_USER.matches(slashCommand) -> {
if (messageParts.size >= 2) { if (messageParts.size >= 2) {
val userId = messageParts[1] val userId = messageParts[1]
if (MatrixPatterns.isUserId(userId)) { if (MatrixPatterns.isUserId(userId)) {
ParsedCommand.RemoveUser( ParsedCommand.RemoveUser(
userId, userId,
textMessage.substring(Command.REMOVE_USER.length + userId.length) trimParts(textMessage, messageParts.take(2))
.trim()
.takeIf { it.isNotBlank() }
) )
} else { } else {
ParsedCommand.ErrorSyntax(Command.REMOVE_USER) ParsedCommand.ErrorSyntax(Command.REMOVE_USER)
@ -218,16 +211,14 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.REMOVE_USER) ParsedCommand.ErrorSyntax(Command.REMOVE_USER)
} }
} }
Command.BAN_USER.command -> { Command.BAN_USER.matches(slashCommand) -> {
if (messageParts.size >= 2) { if (messageParts.size >= 2) {
val userId = messageParts[1] val userId = messageParts[1]
if (MatrixPatterns.isUserId(userId)) { if (MatrixPatterns.isUserId(userId)) {
ParsedCommand.BanUser( ParsedCommand.BanUser(
userId, userId,
textMessage.substring(Command.BAN_USER.length + userId.length) trimParts(textMessage, messageParts.take(2))
.trim()
.takeIf { it.isNotBlank() }
) )
} else { } else {
ParsedCommand.ErrorSyntax(Command.BAN_USER) ParsedCommand.ErrorSyntax(Command.BAN_USER)
@ -236,16 +227,14 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.BAN_USER) ParsedCommand.ErrorSyntax(Command.BAN_USER)
} }
} }
Command.UNBAN_USER.command -> { Command.UNBAN_USER.matches(slashCommand) -> {
if (messageParts.size >= 2) { if (messageParts.size >= 2) {
val userId = messageParts[1] val userId = messageParts[1]
if (MatrixPatterns.isUserId(userId)) { if (MatrixPatterns.isUserId(userId)) {
ParsedCommand.UnbanUser( ParsedCommand.UnbanUser(
userId, userId,
textMessage.substring(Command.UNBAN_USER.length + userId.length) trimParts(textMessage, messageParts.take(2))
.trim()
.takeIf { it.isNotBlank() }
) )
} else { } else {
ParsedCommand.ErrorSyntax(Command.UNBAN_USER) ParsedCommand.ErrorSyntax(Command.UNBAN_USER)
@ -254,7 +243,7 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.UNBAN_USER) ParsedCommand.ErrorSyntax(Command.UNBAN_USER)
} }
} }
Command.IGNORE_USER.command -> { Command.IGNORE_USER.matches(slashCommand) -> {
if (messageParts.size == 2) { if (messageParts.size == 2) {
val userId = messageParts[1] val userId = messageParts[1]
@ -267,7 +256,7 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.IGNORE_USER) ParsedCommand.ErrorSyntax(Command.IGNORE_USER)
} }
} }
Command.UNIGNORE_USER.command -> { Command.UNIGNORE_USER.matches(slashCommand) -> {
if (messageParts.size == 2) { if (messageParts.size == 2) {
val userId = messageParts[1] val userId = messageParts[1]
@ -280,7 +269,7 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER)
} }
} }
Command.SET_USER_POWER_LEVEL.command -> { Command.SET_USER_POWER_LEVEL.matches(slashCommand) -> {
if (messageParts.size == 3) { if (messageParts.size == 3) {
val userId = messageParts[1] val userId = messageParts[1]
if (MatrixPatterns.isUserId(userId)) { if (MatrixPatterns.isUserId(userId)) {
@ -300,7 +289,7 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL)
} }
} }
Command.RESET_USER_POWER_LEVEL.command -> { Command.RESET_USER_POWER_LEVEL.matches(slashCommand) -> {
if (messageParts.size == 2) { if (messageParts.size == 2) {
val userId = messageParts[1] val userId = messageParts[1]
@ -313,7 +302,7 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL)
} }
} }
Command.MARKDOWN.command -> { Command.MARKDOWN.matches(slashCommand) -> {
if (messageParts.size == 2) { if (messageParts.size == 2) {
when { when {
"on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true)
@ -324,31 +313,34 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.MARKDOWN) ParsedCommand.ErrorSyntax(Command.MARKDOWN)
} }
} }
Command.CLEAR_SCALAR_TOKEN.command -> { Command.CLEAR_SCALAR_TOKEN.matches(slashCommand) -> {
if (messageParts.size == 1) { if (messageParts.size == 1) {
ParsedCommand.ClearScalarToken ParsedCommand.ClearScalarToken
} else { } else {
ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN)
} }
} }
Command.SPOILER.command -> { Command.SPOILER.matches(slashCommand) -> {
val message = textMessage.substring(Command.SPOILER.command.length).trim() if (message.isNotEmpty()) {
ParsedCommand.SendSpoiler(message) 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) ParsedCommand.SendShrug(message)
} }
Command.LENNY.command -> { Command.LENNY.matches(slashCommand) -> {
val message = textMessage.substring(Command.LENNY.command.length).trim()
ParsedCommand.SendLenny(message) ParsedCommand.SendLenny(message)
} }
Command.DISCARD_SESSION.command -> { Command.DISCARD_SESSION.matches(slashCommand) -> {
if (messageParts.size == 1) {
ParsedCommand.DiscardSession ParsedCommand.DiscardSession
} else {
ParsedCommand.ErrorSyntax(Command.DISCARD_SESSION)
} }
Command.WHOIS.command -> { }
Command.WHOIS.matches(slashCommand) -> {
if (messageParts.size == 2) { if (messageParts.size == 2) {
val userId = messageParts[1] val userId = messageParts[1]
@ -361,50 +353,36 @@ object CommandParser {
ParsedCommand.ErrorSyntax(Command.WHOIS) ParsedCommand.ErrorSyntax(Command.WHOIS)
} }
} }
Command.CONFETTI.command -> { Command.CONFETTI.matches(slashCommand) -> {
val message = textMessage.substring(Command.CONFETTI.command.length).trim()
ParsedCommand.SendChatEffect(ChatEffect.CONFETTI, message) ParsedCommand.SendChatEffect(ChatEffect.CONFETTI, message)
} }
Command.SNOWFALL.command -> { Command.SNOWFALL.matches(slashCommand) -> {
val message = textMessage.substring(Command.SNOWFALL.command.length).trim()
ParsedCommand.SendChatEffect(ChatEffect.SNOWFALL, message) ParsedCommand.SendChatEffect(ChatEffect.SNOWFALL, message)
} }
Command.CREATE_SPACE.command -> { Command.CREATE_SPACE.matches(slashCommand) -> {
val rawCommand = textMessage.substring(Command.CREATE_SPACE.command.length).trim() if (messageParts.size >= 2) {
val split = rawCommand.split(" ").map { it.trim() }
if (split.isEmpty()) {
ParsedCommand.ErrorSyntax(Command.CREATE_SPACE)
} else {
ParsedCommand.CreateSpace( ParsedCommand.CreateSpace(
split[0], messageParts[1],
split.subList(1, split.size) 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 { } else {
ParsedCommand.UpgradeRoom(newVersion) ParsedCommand.ErrorSyntax(Command.CREATE_SPACE)
}
}
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 -> { else -> {
@ -414,4 +392,10 @@ object CommandParser {
} }
} }
} }
private fun trimParts(message: CharSequence, messageParts: List<String>): String? {
val partsSize = messageParts.sumOf { it.length }
val gapsNumber = messageParts.size - 1
return message.substring(partsSize + gapsNumber).trim().takeIf { it.isNotEmpty() }
}
} }

View File

@ -2098,7 +2098,7 @@ class RoomDetailFragment @Inject constructor(
userId == session.myUserId) { userId == session.myUserId) {
// Empty composer, current user: start an emote // Empty composer, current user: start an emote
views.composerLayout.views.composerEditText.setText(Command.EMOTE.command + " ") 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 { } else {
val roomMember = roomDetailViewModel.getMember(userId) val roomMember = roomDetailViewModel.getMember(userId)
// TODO move logic outside of fragment // TODO move logic outside of fragment

View File

@ -161,7 +161,7 @@ class MessageComposerViewModel @AssistedInject constructor(
withState { state -> withState { state ->
when (state.sendMode) { when (state.sendMode) {
is SendMode.Regular -> { is SendMode.Regular -> {
when (val slashCommandResult = CommandParser.parseSplashCommand(action.text)) { when (val slashCommandResult = CommandParser.parseSlashCommand(action.text)) {
is ParsedCommand.ErrorNotACommand -> { is ParsedCommand.ErrorNotACommand -> {
// Send the text message to the room // Send the text message to the room
room.sendTextMessage(action.text, autoMarkdown = action.autoMarkdown) room.sendTextMessage(action.text, autoMarkdown = action.autoMarkdown)