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 206c5af17a..db1f9eaa83 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,38 @@ 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) { + +enum class Command(val command: String, val parameters: String, @StringRes val description: Int) { + EMOTE("/me", "<message>", R.string.command_description_emote), + BAN_USER("/ban", "<user-id> [reason]", R.string.command_description_ban_user), + UNBAN_USER("/unban", "<user-id> [reason]", R.string.command_description_unban_user), + IGNORE_USER("/ignore", "<user-id> [reason]", R.string.command_description_ignore_user), + UNIGNORE_USER("/unignore", "<user-id>", R.string.command_description_unignore_user), + SET_USER_POWER_LEVEL("/op", "<user-id> [<power-level>]", R.string.command_description_op_user), + RESET_USER_POWER_LEVEL("/deop", "<user-id>", R.string.command_description_deop_user), + ROOM_NAME("/roomname", "<name>", R.string.command_description_room_name), + INVITE("/invite", "<user-id> [reason]", R.string.command_description_invite_user), + JOIN_ROOM("/join", "<room-alias> [reason]", R.string.command_description_join_room), + PART("/part", "<room-alias> [reason]", R.string.command_description_part_room), + TOPIC("/topic", "<topic>", R.string.command_description_topic), + KICK_USER("/kick", "<user-id> [reason]", R.string.command_description_kick_user), + CHANGE_DISPLAY_NAME("/nick", "<display-name>", R.string.command_description_nick), + CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "<display-name>", R.string.command_description_nick_for_room), + ROOM_AVATAR("/roomavatar", "<mxc_url>", R.string.command_description_room_avatar), + CHANGE_AVATAR_FOR_ROOM("/myroomavatar", "<mxc_url>", R.string.command_description_avatar_for_room), + MARKDOWN("/markdown", "<on|off>", R.string.command_description_markdown), + RAINBOW("/rainbow", "<message>", R.string.command_description_rainbow), + RAINBOW_EMOTE("/rainbowme", "<message>", R.string.command_description_rainbow_emote), + CLEAR_SCALAR_TOKEN("/clear_scalar_token", "", R.string.command_description_clear_scalar_token), + SPOILER("/spoiler", "<message>", R.string.command_description_spoiler), + POLL("/poll", "Question | Option 1 | Option 2 ...", R.string.command_description_poll), + SHRUG("/shrug", "[<message>]", R.string.command_description_shrug), + LENNY("/lenny", "[<message>]", R.string.command_description_lenny), + PLAIN("/plain", "<message>", R.string.command_description_plain), + WHOIS("/whois", "<user-id>", R.string.command_description_whois), + DISCARD_SESSION("/discardsession", "", R.string.command_description_discard_session); + + enum class Command(val command: String, val parameters: String, @StringRes val description: Int, val isDevCommand: Boolean) { EMOTE("/me", "<message>", R.string.command_description_emote, false), BAN_USER("/ban", "<user-id> [reason]", R.string.command_description_ban_user, false), UNBAN_USER("/unban", "<user-id> [reason]", R.string.command_description_unban_user, false), @@ -53,6 +84,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d LEAVE_ROOM("/leave", "<roomId?>", R.string.command_description_leave_room, true), UPGRADE_ROOM("/upgraderoom", "newVersion", R.string.command_description_upgrade_room, true); + val length get() = command.length + 1 } 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 adba6e4a18..2a0553c005 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 @@ -61,7 +61,7 @@ object CommandParser { } return when (val slashCommand = messageParts.first()) { - Command.PLAIN.command -> { + Command.PLAIN.command -> { val text = textMessage.substring(Command.PLAIN.command.length).trim() if (text.isNotEmpty()) { @@ -70,7 +70,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.PLAIN) } } - Command.CHANGE_DISPLAY_NAME.command -> { + Command.CHANGE_DISPLAY_NAME.command -> { val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() if (newDisplayName.isNotEmpty()) { @@ -79,7 +79,42 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME) } } - Command.TOPIC.command -> { + 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) + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME_FOR_ROOM) + } + } + Command.ROOM_AVATAR.command -> { + if (messageParts.size == 2) { + val url = messageParts[1] + + if (url.startsWith("mxc://")) { + ParsedCommand.ChangeRoomAvatar(url) + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) + } + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) + } + } + Command.CHANGE_AVATAR_FOR_ROOM.command -> { + if (messageParts.size == 2) { + val url = messageParts[1] + + if (url.startsWith("mxc://")) { + ParsedCommand.ChangeAvatarForRoom(url) + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) + } + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) + } + } + Command.TOPIC.command -> { val newTopic = textMessage.substring(Command.TOPIC.command.length).trim() if (newTopic.isNotEmpty()) { @@ -88,22 +123,22 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.TOPIC) } } - Command.EMOTE.command -> { + Command.EMOTE.command -> { val message = textMessage.subSequence(Command.EMOTE.command.length, textMessage.length).trim() ParsedCommand.SendEmote(message) } - Command.RAINBOW.command -> { + Command.RAINBOW.command -> { val message = textMessage.subSequence(Command.RAINBOW.command.length, textMessage.length).trim() ParsedCommand.SendRainbow(message) } - Command.RAINBOW_EMOTE.command -> { + Command.RAINBOW_EMOTE.command -> { val message = textMessage.subSequence(Command.RAINBOW_EMOTE.command.length, textMessage.length).trim() ParsedCommand.SendRainbowEmote(message) } - Command.JOIN_ROOM.command -> { + Command.JOIN_ROOM.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] @@ -121,7 +156,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) } } - Command.PART.command -> { + Command.PART.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] @@ -139,7 +174,16 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.PART) } } - Command.INVITE.command -> { + Command.ROOM_NAME.command -> { + val newRoomName = textMessage.substring(Command.ROOM_NAME.command.length).trim() + + if (newRoomName.isNotEmpty()) { + ParsedCommand.ChangeRoomName(newRoomName) + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_NAME) + } + } + Command.INVITE.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -166,7 +210,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.INVITE) } } - Command.KICK_USER.command -> { + Command.KICK_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -184,7 +228,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.KICK_USER) } } - Command.BAN_USER.command -> { + Command.BAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -202,7 +246,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.BAN_USER) } } - Command.UNBAN_USER.command -> { + Command.UNBAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -220,7 +264,33 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.UNBAN_USER) } } - Command.SET_USER_POWER_LEVEL.command -> { + Command.IGNORE_USER.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.IgnoreUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.IGNORE_USER) + } + } else { + ParsedCommand.ErrorSyntax(Command.IGNORE_USER) + } + } + Command.UNIGNORE_USER.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.UnignoreUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) + } + } else { + ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) + } + } + Command.SET_USER_POWER_LEVEL.command -> { if (messageParts.size == 3) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -240,7 +310,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.RESET_USER_POWER_LEVEL.command -> { + Command.RESET_USER_POWER_LEVEL.command -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -253,7 +323,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.MARKDOWN.command -> { + Command.MARKDOWN.command -> { if (messageParts.size == 2) { when { "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) @@ -264,23 +334,28 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.MARKDOWN) } } - Command.CLEAR_SCALAR_TOKEN.command -> { + Command.CLEAR_SCALAR_TOKEN.command -> { if (messageParts.size == 1) { ParsedCommand.ClearScalarToken } else { ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) } } - Command.SPOILER.command -> { + Command.SPOILER.command -> { val message = textMessage.substring(Command.SPOILER.command.length).trim() ParsedCommand.SendSpoiler(message) } - Command.SHRUG.command -> { + Command.SHRUG.command -> { val message = textMessage.substring(Command.SHRUG.command.length).trim() ParsedCommand.SendShrug(message) } - Command.POLL.command -> { + Command.LENNY.command -> { + val message = textMessage.substring(Command.LENNY.command.length).trim() + + ParsedCommand.SendLenny(message) + } + Command.POLL.command -> { val rawCommand = textMessage.substring(Command.POLL.command.length).trim() val split = rawCommand.split("|").map { it.trim() } if (split.size > 2) { @@ -289,9 +364,22 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.POLL) } } - Command.DISCARD_SESSION.command -> { + Command.DISCARD_SESSION.command -> { ParsedCommand.DiscardSession } + Command.WHOIS.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.ShowUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.WHOIS) + } + } else { + ParsedCommand.ErrorSyntax(Command.WHOIS) + } + } Command.CONFETTI.command -> { val message = textMessage.substring(Command.CONFETTI.command.length).trim() ParsedCommand.SendChatEffect(ChatEffect.CONFETTI, message) 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 123f1d3a36..bafb9153e6 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 @@ -42,7 +42,10 @@ 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 IgnoreUser(val userId: String) : ParsedCommand() + class UnignoreUser(val userId: String) : ParsedCommand() class SetUserPowerLevel(val userId: String, val powerLevel: Int?) : ParsedCommand() + class ChangeRoomName(val name: String) : ParsedCommand() class Invite(val userId: String, val reason: String?) : ParsedCommand() class Invite3Pid(val threePid: ThreePid) : ParsedCommand() class JoinRoom(val roomAlias: String, val reason: String?) : ParsedCommand() @@ -50,12 +53,17 @@ sealed class ParsedCommand { class ChangeTopic(val topic: String) : ParsedCommand() class KickUser(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() + class ChangeAvatarForRoom(val url: String) : ParsedCommand() class SetMarkdown(val enable: Boolean) : ParsedCommand() object ClearScalarToken : ParsedCommand() class SendSpoiler(val message: String) : ParsedCommand() class SendShrug(val message: CharSequence) : ParsedCommand() + class SendLenny(val message: CharSequence) : ParsedCommand() class SendPoll(val question: String, val options: List<String>) : ParsedCommand() object DiscardSession : ParsedCommand() + class ShowUser(val userId: String) : ParsedCommand() class SendChatEffect(val chatEffect: ChatEffect, val message: String) : ParsedCommand() class CreateSpace(val name: String, val invitees: List<String>) : ParsedCommand() class AddToSpace(val spaceId: String) : ParsedCommand() 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 c6eda584ad..8014b4694b 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 @@ -422,6 +422,7 @@ class RoomDetailFragment @Inject constructor( is RoomDetailViewEvents.SendMessageResult -> renderSendMessageResult(it) is RoomDetailViewEvents.ShowE2EErrorMessage -> displayE2eError(it.withHeldCode) RoomDetailViewEvents.DisplayPromptForIntegrationManager -> displayPromptForIntegrationManager() + is RoomDetailViewEvents.OpenRoomMemberProfile -> openRoomMemberProfile(it.userId) is RoomDetailViewEvents.OpenStickerPicker -> openStickerPicker(it) is RoomDetailViewEvents.DisplayEnableIntegrationsWarning -> displayDisabledIntegrationDialog() is RoomDetailViewEvents.OpenIntegrationManager -> openIntegrationManager() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt index 2802ee2f83..94aff2ed83 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt @@ -68,7 +68,13 @@ sealed class RoomDetailViewEvents : VectorViewEvents { abstract class SendMessageResult : RoomDetailViewEvents() - data class DisplayAndAcceptCall(val call: WebRtcCall): RoomDetailViewEvents() + object DisplayPromptForIntegrationManager : RoomDetailViewEvents() + + object DisplayEnableIntegrationsWarning : RoomDetailViewEvents() + + data class OpenRoomMemberProfile(val userId: String) : RoomDetailViewEvents() + + data class DisplayAndAcceptCall(val call: WebRtcCall): RoomDetailViewEvents() object DisplayPromptForIntegrationManager : RoomDetailViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index cacf9b8902..45607613c7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -87,6 +87,8 @@ import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams 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.model.RoomAvatarContent +import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.message.MessageType @@ -794,6 +796,10 @@ class RoomDetailViewModel @AssistedInject constructor( _viewEvents.post(RoomDetailViewEvents.MessageSent) popDraft() } + is ParsedCommand.ChangeRoomName -> { + handleChangeRoomNameSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.Invite -> { handleInviteSlashCommand(slashCommandResult) popDraft() @@ -816,12 +822,20 @@ class RoomDetailViewModel @AssistedInject constructor( if (slashCommandResult.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) popDraft() } + is ParsedCommand.BanUser -> { + handleBanSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.UnbanUser -> { handleUnbanSlashCommand(slashCommandResult) popDraft() } - is ParsedCommand.BanUser -> { - handleBanSlashCommand(slashCommandResult) + is ParsedCommand.IgnoreUser -> { + handleIgnoreSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.UnignoreUser -> { + handleUnignoreSlashCommand(slashCommandResult) popDraft() } is ParsedCommand.KickUser -> { @@ -864,14 +878,12 @@ class RoomDetailViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.SendShrug -> { - val sequence = buildString { - append("¯\\_(ツ)_/¯") - if (slashCommandResult.message.isNotEmpty()) { - append(" ") - append(slashCommandResult.message) - } - } - room.sendTextMessage(sequence) + sendPrefixedMessage("¯\\_(ツ)_/¯", slashCommandResult.message) + _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendLenny -> { + sendPrefixedMessage("( ͡° ͜ʖ ͡°)", slashCommandResult.message) _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) popDraft() } @@ -893,6 +905,23 @@ class RoomDetailViewModel @AssistedInject constructor( handleChangeDisplayNameSlashCommand(slashCommandResult) popDraft() } + is ParsedCommand.ChangeDisplayNameForRoom -> { + handleChangeDisplayNameForRoomSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.ChangeRoomAvatar -> { + handleChangeRoomAvatarSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.ChangeAvatarForRoom -> { + handleChangeAvatarForRoomSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.ShowUser -> { + _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) + handleWhoisSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.DiscardSession -> { if (room.isEncrypted()) { session.cryptoService().discardOutboundSession(room.roomId) @@ -1102,6 +1131,12 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun handleChangeRoomNameSlashCommand(changeRoomName: ParsedCommand.ChangeRoomName) { + launchSlashCommandFlow { + room.updateName(changeRoomName.name, it) + } + } + private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) { launchSlashCommandFlowSuspendable { room.invite(invite.userId, invite.reason) @@ -1133,6 +1168,30 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun getLastMemberEvent(): RoomMemberContent { + return room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(session.myUserId)) + ?.content?.toModel<RoomMemberContent>() + ?: RoomMemberContent(membership = Membership.JOIN) + } + + private fun handleChangeDisplayNameForRoomSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) { + launchSlashCommandFlow { + room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, getLastMemberEvent().copy(displayName = changeDisplayName.displayName).toContent(), it) + } + } + + private fun handleChangeRoomAvatarSlashCommand(changeAvatar: ParsedCommand.ChangeRoomAvatar) { + launchSlashCommandFlow { + room.sendStateEvent(EventType.STATE_ROOM_AVATAR, null, RoomAvatarContent(changeAvatar.url).toContent(), it) + } + } + + private fun handleChangeAvatarForRoomSlashCommand(changeAvatar: ParsedCommand.ChangeAvatarForRoom) { + launchSlashCommandFlow { + room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, getLastMemberEvent().copy(avatarUrl = changeAvatar.url).toContent(), it) + } + } + private fun handleKickSlashCommand(kick: ParsedCommand.KickUser) { launchSlashCommandFlowSuspendable { room.kick(kick.userId, kick.reason) @@ -1151,6 +1210,33 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun handleIgnoreSlashCommand(ignore: ParsedCommand.IgnoreUser) { + launchSlashCommandFlow { + session.ignoreUserIds(listOf(ignore.userId), it) + } + } + + private fun handleUnignoreSlashCommand(unignore: ParsedCommand.UnignoreUser) { + launchSlashCommandFlow { + session.unIgnoreUserIds(listOf(unignore.userId), it) + } + } + + private fun handleWhoisSlashCommand(whois: ParsedCommand.ShowUser) { + _viewEvents.post(RoomDetailViewEvents.OpenRoomMemberProfile(whois.userId)) + } + + private fun sendPrefixedMessage(prefix: String, message: CharSequence) { + val sequence = buildString { + append(prefix) + if (message.isNotEmpty()) { + append(" ") + append(message) + } + } + room.sendTextMessage(sequence) + } + private fun launchSlashCommandFlow(lambda: (MatrixCallback<Unit>) -> Unit) { _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) val matrixCallback = object : MatrixCallback<Unit> { diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index f3fd04a478..b57372e4c0 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1831,16 +1831,23 @@ <string name="command_description_emote">Displays action</string> <string name="command_description_ban_user">Bans user with given id</string> <string name="command_description_unban_user">Unbans user with given id</string> + <string name="command_description_ignore_user">Ignores a user, hiding their messages from you</string> + <string name="command_description_unignore_user">Stops ignoring a user, showing their messages going forward</string> <string name="command_description_op_user">Define the power level of a user</string> <string name="command_description_deop_user">Deops user with given id</string> + <string name="command_description_room_name">Sets the room name</string> <string name="command_description_invite_user">Invites user with given id to current room</string> <string name="command_description_join_room">Joins room with given alias</string> <string name="command_description_part_room">Leave room</string> <string name="command_description_topic">Set the room topic</string> <string name="command_description_kick_user">Kicks user with given id</string> <string name="command_description_nick">Changes your display nickname</string> + <string name="command_description_nick_for_room">Changes your display nickname in the current room only</string> + <string name="command_description_room_avatar">Changes the avatar of the current room</string> + <string name="command_description_avatar_for_room">Changes your avatar in this current room only</string> <string name="command_description_markdown">On/Off markdown</string> <string name="command_description_clear_scalar_token">To fix Matrix Apps management</string> + <string name="command_description_whois">Displays information about a user</string> <string name="markdown_has_been_enabled">Markdown has been enabled.</string> <string name="markdown_has_been_disabled">Markdown has been disabled.</string> @@ -2671,6 +2678,7 @@ <string name="settings_developer_mode_show_info_on_screen_summary">Show some useful info to help debugging the application</string> <string name="command_description_shrug">Prepends ¯\\_(ツ)_/¯ to a plain-text message</string> + <string name="command_description_lenny">Prepends ( ͡° ͜ʖ ͡°) to a plain-text message</string> <string name="create_room_encryption_title">"Enable encryption"</string> <string name="create_room_encryption_description">"Once enabled, encryption cannot be disabled."</string>