This is beta documentation for Stream Chat Android SDK v7. For the latest stable version, see the latest version (v6) .

Selected Message Menu

The SelectedMessageMenu component allows you to show different message options to the user when they select a message in the MessageList. This is usually done by long tapping on a message item.

This is a stateless component that you can easily add to your UI if you're building a custom Messages screen. Internally, it sets up the following content:

  • Header content: Shows a list of reactions the user can use to react to the message. The visibility of reaction options is controlled by ChatTheme.reactionOptionsTheme.areReactionOptionsVisible and the user's SEND_REACTION capability.
  • Center content: Shows a list of actions the user can take with the selected message, such as delete, edit, reply to, flag, copy, pin and start a thread.

Let's see how to use it.

Usage

If you're using MessagesScreen, SelectedMessageMenu is already set up for you. To use SelectedMessageMenu in your custom screens, simply add it to your UI, like so:

// The rest of your UI
if (selectedMessageState is SelectedMessageOptionsState) {
    val selectedMessage = selectedMessageState.message
    SelectedMessageMenu(
        modifier = Modifier.align(Alignment.BottomCenter),
        // Define your message options
        messageOptions = defaultMessageOptionsState(
            selectedMessage = selectedMessage,
            currentUser = user,
            isInThread = listViewModel.isInThread,
            channel = channel,
        ),
        // The message you selected
        message = selectedMessage,
        // The capabilities the user has in a given channel
        ownCapabilities = selectedMessageState.ownCapabilities,
        onMessageAction = { action ->
            // Handle message action
        },
        onShowMoreReactionsSelected = {
            // Handle show more reactions button click
        },
        onDismiss = {
            // Handle dismiss
        }
    )
}

As you can see, showing the menu is very simple. If the selectedMessageState is an instance of SelectedMessageOptionsState, you pass in the message options you want to expose to the user, as well as the selected message. The reactions you show are taken from the ChatTheme component and everything else required to show the component is taken care of internally.

This produces the following UI:

Default SelectedMessageMenu component

The component shows reactions from the ChatTheme on the top, followed by the message actions you passed in.

The menu overlay has a darker background and tapping it will dismiss the component, as will pressing the system back button.

Handling Actions

SelectedMessageMenu exposes the following actions as parameters:

@Composable
fun SelectedMessageMenu(
    ..., // State and styling
    onMessageAction: (MessageAction) -> Unit,
    onShowMoreReactionsSelected: () -> Unit,
    onDismiss: () -> Unit = {},
)
  • onMessageAction: Handler used when the user triggers any message action, such as reply, edit, delete, react and others.
  • onShowMoreReactionsSelected: Handler used when the show more reactions button is clicked.
  • onDismiss: Handler used when the component is dismissed by clicking outside of the component UI or pressing the system back button.

To handle these actions, you can override them like so:

if (selectedMessageState is SelectedMessageOptionsState) {
    SelectedMessageMenu(
        ..., // State and options
        onMessageAction = { action ->
            composerViewModel.performMessageAction(action)
            listViewModel.performMessageAction(action)
        },
        onShowMoreReactionsSelected = {
            listViewModel.selectExtendedReactions(selectedMessage)
        },
        onDismiss = { listViewModel.removeOverlay() }
    )
}

In the snippet above, you propagate the action to the composerViewModel and listViewModel, for them to store the latest action. This will update the UI accordingly.

Alternatively, you call listViewModel.removeOverlay() to remove the overlay from the screen in onDismiss(). It's important to note that onMessageAction() calls removeOverlay() internally to hide the overlay.

Next, let's see how to customize the menu.

Customization

You can customize the SelectedMessageMenu component using the following parameters:

@Composable
fun SelectedMessageMenu(
    message: Message,
    messageOptions: List<MessageOptionItemState>,
    ownCapabilities: Set<String>,
    onMessageAction: (MessageAction) -> Unit,
    onShowMoreReactionsSelected: () -> Unit,
    modifier: Modifier = Modifier,
    currentUser: User? = null,
    onDismiss: () -> Unit = {},
)
  • message: The selected message.
  • messageOptions: The available message options within the menu. See below.
  • ownCapabilities: Set of capabilities the user is given for the current channel. For a full list see ChannelCapabilities.
  • onMessageAction: Handler for when the user selects a message option.
  • onShowMoreReactionsSelected: Handler for when the user taps the "show more reactions" button.
  • modifier: Modifier for styling the component.
  • currentUser: The currently logged-in user.
  • onDismiss: Handler for when the menu is dismissed.

The menu is rendered as a Dialog overlay, displaying the message with reactions above and options below.

Customizing the Menu Option List

You can pass defaultMessageOptionsState() to the messageOptions parameter to get the default actions that we expose in our SDK. This function uses the ChatTheme.messageOptionsTheme.optionVisibility property and own capabilities under the hood to control which action is visible to the user.

The values that defaultMessageOptionsState() gets from ChatTheme.messageOptionsTheme.optionVisibility take precedence over own capabilities, so you can pass your own implementation of MessageOptionTheme to ChatTheme.messageOptionsTheme to control which options to show. This is useful when you are using MessagesScreen, for example, which sets up SelectedMessageMenu automatically.

ChatTheme(
    // ...
    messageOptionsTheme = MessageOptionsTheme.defaultTheme(
        optionVisibility = MessageOptionItemVisibility(
            isMarkAsUnreadVisible = false,
            isCopyTextVisible = false,
        ),
    ),
    // ...
) {
    // Rest of the UI
}

Customizing Reactions

Reactions are resolved from ChatTheme.reactionResolver.

To customize reactions, override ChatTheme.reactionResolver with your own implementation of ReactionResolver so that all components wrapped inside ChatTheme draw from the same source.

You can also control the reaction list visibility by using your own implementation of ReactionOptionsTheme for the ChatTheme.reactionOptionsTheme parameter.

Customizing the Appearance

To customize the appearance of the SelectedMessageMenu, override the corresponding methods in ChatComponentFactory:

  • MessageMenu() — Controls the overall menu rendering.
  • MessageMenuHeaderContent() — Customizes the header (reaction options).
  • MessageMenuOptions() — Customizes the message options list.

See the Component Factory page for details on overriding these methods.