MessageComposerViewModelBinder.with(composerViewModel)
.onSuggestedMentionSelection { mention ->
composerViewModel.selectMention(mention)
}
.bindView(composerView, viewLifecycleOwner)Mentions
Stream Chat lets a sender notify more than one user at a time. Beyond direct user mentions (@<user>), a message can target everyone in a channel (@channel), only the members currently online (@here), everyone holding a given role (@<role>), or a named user group (@<group>).
The SDK exposes each of these as a Mention subtype, plumbs them through the message composer and the message list, and lets you control which kinds are available per channel via channel capabilities.
Mention kinds
Mention is an interface with five built-in implementations:
| Subtype | Token | Notifies |
|---|---|---|
Mention.User(user) | @<user name> | A single user |
Mention.Channel | @channel | Every member of the channel |
Mention.Here | @here | Online members only |
Mention.Role(role) | @<role> | Every user with that role (up to 10 roles per message) |
Mention.Group(group) | @<group name> | Every member of the named user group (up to 10 groups per message) |
Each kind maps to a server-side channel capability. For the four notify-* kinds, the composer skips that kind in its suggestions when the channel does not return the capability, and trying to send the mention is rejected by the server. User mentions behave differently: the composer always shows user suggestions regardless of create-mention, and the capability is only enforced on send under Permissions V2 (on Permissions V1, regular members lack create-mention yet user mentions still work).
| Capability | Constant | Required for |
|---|---|---|
create-mention | ChannelCapabilities.CREATE_MENTION | User mentions |
notify-channel | ChannelCapabilities.NOTIFY_CHANNEL | @channel |
notify-here | ChannelCapabilities.NOTIFY_HERE | @here |
notify-role | ChannelCapabilities.NOTIFY_ROLE | Role mentions |
notify-group | ChannelCapabilities.NOTIFY_GROUP | Group mentions |
Whether a message actually triggers a push for any given recipient depends on that user's push preferences. See Push Preferences for the full reference.
Sending mentions from the composer
MessageComposerView reads the active channel's capabilities and surfaces the matching kinds in the suggestion popup automatically. Typing @ shows users matching the query plus any of @channel, @here, matching roles, and matching groups that the channel allows. Picking an item inserts the token and remembers the selection; on send, the composer populates the right fields on the outgoing Message.
The only thing to wire up is the selection callback, which receives a Mention. Use the binder shortcut:
Or set the listener directly on the view:
composerView.suggestedMentionSelectionListener = { mention ->
composerViewModel.selectMention(mention)
}Building a message by hand
When sending a message without going through the built-in composer, set the mention fields directly on Message:
val message = Message(
cid = cid,
text = "Heads up @channel, the backup is failing",
mentionedChannel = true,
)
chatClient.channel(cid).sendMessage(message).enqueue()The full set of fields is:
| Field | Type | Meaning |
|---|---|---|
mentionedUsersIds | List<String> | User IDs to ping by name |
mentionedChannel | Boolean | @channel is set |
mentionedHere | Boolean | @here is set |
mentionedRoles | List<String> | Role names to ping |
mentionedGroups | List<UserGroup> | User groups to ping |
Server limits: 100 user IDs (25 on update), 10 roles, 10 groups.
Rendering and click handling
Incoming messages style and linkify every mention token automatically when the matching field on Message is set.
MessageListView exposes setOnMentionTokenClickListener, which takes any Mention:
messageListView.setOnMentionTokenClickListener { mention ->
when (mention) {
is Mention.User -> {
openProfile(mention.user.id)
true
}
is Mention.Group -> {
openGroupInfo(mention.group.id)
true
}
else -> false // fall back to the default handler
}
}Return true to mark the click as handled, false to let the default handler run.
Customizing the suggestion popup
The simplest path is to subclass DefaultMessageComposerMentionSuggestionsContent and pass it to setMentionSuggestionsContent. The subclass keeps the default rendering and lets you override just the parts you want to change:
class MyMentionSuggestionsContent(context: Context) :
DefaultMessageComposerMentionSuggestionsContent(context) {
// override what you want to customize
}
composerView.setMentionSuggestionsContent(
MyMentionSuggestionsContent(context).apply {
suggestedMentionSelectionListener = { mention ->
composerViewModel.selectMention(mention)
}
},
)For a fully custom view, implement MessageComposerContent, read the suggestions from state.suggestedMentions in renderState, and invoke composerViewModel.selectMention(mention) when the user taps an item. DefaultMessageComposerMentionSuggestionsContent is a working reference.
Styling mentions in rendered text
Mention spans in rendered messages pick up their color from the MessageListView text attributes. See MessageListView for the full set of style attributes.