Add support for slash commands (under Feature Flag) (#6482)

* Add support for slash commands

* Update screenshots

* Rename module `slash` to `slashcommands`

* Rename `SlashCommand` to `SlashCommandService`

* Introduce MsgType in order to send text message with a different msgtype value.

* Format file and add parameter names, add default values and cleanup

* Add isSupported parameter to filter out unsupported yet commands.

* Slash commands: disable suggestions if the feature is disabled.

* Fix sending shrug command.

* Add missing test on SuggestionsProcessor

* Add tests on MessageComposerPresenter about slash command.

* Fix import ordering

* Add missing tests on CommandExecutor

* Add missing tests in MarkdownTextEditorStateTest

* Slash commands: Improve code when sending message with prefix.

* Slash commands: Add support for /unflip

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Benoit Marty 2026-04-02 16:15:32 +02:00 committed by GitHub
parent f08d1ed686
commit a77662421c
65 changed files with 3038 additions and 86 deletions

View file

@ -422,6 +422,10 @@ class LoggedInFlowNode(
override fun navigateToGlobalNotificationSettings() {
backstack.push(NavTarget.Settings(PreferencesEntryPoint.InitialTarget.NotificationSettings))
}
override fun navigateToDeveloperSettings() {
backstack.push(NavTarget.Settings(PreferencesEntryPoint.InitialTarget.DeveloperSettings))
}
}
val inputs = RoomFlowNode.Inputs(
roomIdOrAlias = navTarget.roomIdOrAlias,
@ -744,11 +748,11 @@ private class AttachRoomOperation(
}
} + // Always create a new element, otherwise we wouldn't be navigating to the target event id or child node
BackStackElement(
key = NavKey(roomTarget),
fromState = CREATED,
targetState = ACTIVE,
operation = this
)
key = NavKey(roomTarget),
fromState = CREATED,
targetState = ACTIVE,
operation = this
)
} else {
// Otherwise, just push the new node to the end of the backstack
Push<LoggedInFlowNode.NavTarget>(roomTarget).invoke(currentElements)

View file

@ -85,6 +85,7 @@ class JoinedRoomLoadedFlowNode(
fun navigateToRoom(roomId: RoomId, serverNames: List<String>)
fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean)
fun navigateToGlobalNotificationSettings()
fun navigateToDeveloperSettings()
}
data class Inputs(
@ -145,6 +146,10 @@ class JoinedRoomLoadedFlowNode(
callback.navigateToGlobalNotificationSettings()
}
override fun navigateToDeveloperSettings() {
callback.navigateToDeveloperSettings()
}
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>) {
callback.navigateToRoom(roomId, serverNames)
}
@ -252,6 +257,10 @@ class JoinedRoomLoadedFlowNode(
override fun navigateToRoom(roomId: RoomId) {
callback.navigateToRoom(roomId, emptyList())
}
override fun navigateToDeveloperSettings() {
callback.navigateToDeveloperSettings()
}
}
val params = MessagesEntryPoint.Params(
MessagesEntryPoint.InitialTarget.Messages(navTarget.focusedEventId)

View file

@ -16,4 +16,5 @@ class FakeJoinedRoomLoadedFlowNodeCallback : JoinedRoomLoadedFlowNode.Callback {
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>) = lambdaError()
override fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean) = lambdaError()
override fun navigateToGlobalNotificationSettings() = lambdaError()
override fun navigateToDeveloperSettings() = lambdaError()
}