Render enhanced mentions in incoming messages - #6501
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
SDK Size Comparison 📏
|
d728b33 to
fcfa4c9
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
WalkthroughExtends the mention system to support ChangesMulti-type Mention System
Sequence Diagram(s)sequenceDiagram
participant User as User Tap
participant TextViewLinkHandler
participant LongClickFriendlyLinkMovementMethod
participant dispatchMentionClick as MessageListListeners.dispatchMentionClick
participant OnMentionTokenClickListener
participant OnMentionClickListener as OnMentionClickListener (deprecated)
User->>TextViewLinkHandler: ACTION_UP on MentionSpan
TextViewLinkHandler->>LongClickFriendlyLinkMovementMethod: onMentionClick(mention: Mention)
LongClickFriendlyLinkMovementMethod->>dispatchMentionClick: dispatchMentionClick(mention)
dispatchMentionClick->>OnMentionTokenClickListener: onMentionClick(mention)
alt mention is Mention.User
dispatchMentionClick->>OnMentionClickListener: onMentionClick(user)
end
sequenceDiagram
participant MessageList
participant DefaultMessageItem
participant MessageItem
participant MessageContainer
participant MessageContent
participant MessageText
participant handleAnnotationClick
MessageList->>DefaultMessageItem: onMentionClick=(Mention)->Unit
DefaultMessageItem->>MessageItem: onMentionClick
MessageItem->>MessageContainer: onMentionClick
MessageContainer->>MessageContent: onMentionClick via MessageContentParams
MessageContent->>MessageText: onMentionClick
MessageText->>handleAnnotationClick: tag + value
handleAnnotationClick->>handleAnnotationClick: map tag → Mention subtype
handleAnnotationClick-->>MessageText: onMentionClick(mention)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/MentionRegexTest.kt (1)
41-41: ⚡ Quick winDocument or remove this suppression.
Line 41 adds
@Suppress("LongMethod")without rationale. Please either splitprovideMatchCasesor add a short justification comment above the suppression to keep it guideline-compliant.
As per coding guidelines:**/*.kt: “Use@OptInannotations explicitly in Kotlin code; avoid suppressions unless documented.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/MentionRegexTest.kt` at line 41, The `@Suppress`("LongMethod") annotation on the provideMatchCases method lacks documentation or rationale, violating coding guidelines that require suppressions to be explicitly justified. Either add a concise comment above the suppression explaining why the long method is necessary in this test context, or refactor the provideMatchCases method by splitting it into smaller focused helper methods to eliminate the need for the suppression entirely.Source: Coding guidelines
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/MessageTextHelpersTest.kt (1)
247-276: ⚡ Quick winAdd a user-mention row to
mentionDispatchCasesto lock the generic callback contract.
mentionDispatchCasesvalidates non-user mention kinds, but it skipsAnnotationTagUserMention. Adding one user case here would protect the newonMentionClick(Mention.User)path and complement the legacyonUserMentionClickassertion.Also applies to: 371-385
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/MessageTextHelpersTest.kt` around lines 247 - 276, The parameterized test `handleAnnotationClick fires onMentionClick with the right Mention for each kind` is missing a test case for user mentions in its `mentionDispatchCases` method source. Add a new test case row to the `mentionDispatchCases` method source (around lines 371-385) that includes a user mention scenario with `AnnotationTagUserMention` as the annotationTag and an appropriate `Mention.User` as the expectedMention. This will ensure the new `onMentionClick(Mention.User)` path is properly validated and tested alongside the legacy `onUserMentionClick` behavior.stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt (1)
989-997: ⚡ Quick winAlign
onMentionSelectedKDoc with its declared replacement contract.Line 996 documents
onMentionSelectedas non-user only, but Line 1012 saysonUserSelectedshould be replaced byonMentionSelectedfor every mention type. Please make these public docs consistent.✏️ Suggested doc fix
- * `@param` onMentionSelected Action invoked when a non-user [Mention] is selected. + * `@param` onMentionSelected Action invoked when any [Mention] is selected.Also applies to: 1011-1016
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt` around lines 989 - 997, The KDoc for the `onMentionSelected` parameter at line 996 states it is invoked only for non-user mentions, but the replacement contract documented around lines 1011-1016 indicates that `onMentionSelected` should replace `onUserSelected` and handle all mention types including user mentions. Update the KDoc comment for `onMentionSelected` to accurately reflect that it handles all mention types (both user and non-user mentions) to align with the declared replacement contract and make the documentation consistent across the parameter documentation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt`:
- Around line 989-997: The KDoc for the `onMentionSelected` parameter at line
996 states it is invoked only for non-user mentions, but the replacement
contract documented around lines 1011-1016 indicates that `onMentionSelected`
should replace `onUserSelected` and handle all mention types including user
mentions. Update the KDoc comment for `onMentionSelected` to accurately reflect
that it handles all mention types (both user and non-user mentions) to align
with the declared replacement contract and make the documentation consistent
across the parameter documentation.
In
`@stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/MessageTextHelpersTest.kt`:
- Around line 247-276: The parameterized test `handleAnnotationClick fires
onMentionClick with the right Mention for each kind` is missing a test case for
user mentions in its `mentionDispatchCases` method source. Add a new test case
row to the `mentionDispatchCases` method source (around lines 371-385) that
includes a user mention scenario with `AnnotationTagUserMention` as the
annotationTag and an appropriate `Mention.User` as the expectedMention. This
will ensure the new `onMentionClick(Mention.User)` path is properly validated
and tested alongside the legacy `onUserMentionClick` behavior.
In
`@stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/MentionRegexTest.kt`:
- Line 41: The `@Suppress`("LongMethod") annotation on the provideMatchCases
method lacks documentation or rationale, violating coding guidelines that
require suppressions to be explicitly justified. Either add a concise comment
above the suppression explaining why the long method is necessary in this test
context, or refactor the provideMatchCases method by splitting it into smaller
focused helper methods to eliminate the need for the suppression entirely.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 0fe352d1-10c1-49b0-85f7-4df6b9bccfe3
⛔ Files ignored due to path filters (1)
stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.messages_MessageTextTest_text_with_all_mention_types.pngis excluded by!**/*.png
📒 Files selected for processing (32)
stream-chat-android-compose/api/stream-chat-android-compose.apistream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageContent.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageText.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageContainer.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageList.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamDesign.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/util/MessageTextFormatter.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/util/TextUtils.ktstream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/MessageTextHelpersTest.ktstream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/MessageTextTest.ktstream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/util/TextUtilsKtTest.ktstream-chat-android-markdown-transformer/src/main/kotlin/io/getstream/chat/android/markdown/MarkdownTextTransformer.ktstream-chat-android-ui-common/api/stream-chat-android-ui-common.apistream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/Mention.ktstream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/MentionRegex.ktstream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/MentionRegexTest.ktstream-chat-android-ui-components/api/stream-chat-android-ui-components.apistream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/MessageListView.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/MessageListListeners.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/MessageListListenersImpl.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/viewholder/impl/CustomAttachmentsViewHolder.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/viewholder/impl/FileAttachmentsViewHolder.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/viewholder/impl/LinkAttachmentsViewHolder.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/viewholder/impl/MediaAttachmentsViewHolder.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/viewholder/impl/MessagePlainTextViewHolder.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/LongClickFriendlyLinkMovementMethod.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/helper/transformer/AutoLinkableTextTransformer.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/utils/Linkify.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/utils/MentionSpan.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/utils/TextViewLinkHandler.kt
fcfa4c9 to
76ee596
Compare
76ee596 to
2dbd745
Compare
2dbd745 to
52000bb
Compare
|
Just made a draft to prevent accidental merging right now. We're going to do a release today and I prefer not to include this PR. |
|
|
🚀 Available in v7.5.0 |



Goal
Render
@channel,@here, role, and user-group tokens in incoming messages so users see them styled and clickable, like user mentions. No composer autocomplete yet.This is PR 3 in the enhanced-mentions series.
Part of AND-1175
Implementation
ui-common:Mentionsealed interface gainsChannel,Here,Role,Groupcases; newmentionRegex(display)helper uses Unicode-aware boundaries so non-ASCII display names match correctly.TextUtilsspans every mention type with a per-type annotation tag;StreamDesignexposeschatTextMention*/chatBgMention*color tokens;MessageText/MessageContent/MessageContainer/MessageItem/MessageListplumbonMentionClick: (Mention) -> Unit.Linkify,MentionSpan(renamed fromUserSpan),TextViewLinkHandler, andLongClickFriendlyLinkMovementMethodnow span every mention type and dispatch through a newMessageListView.OnMentionTokenClickListener. The legacy user-onlyOnMentionClickListenerstays in place and is deprecated.UI Changes
Testing
MentionRegexTestcovers Unicode boundaries, escape behavior, and the start/end-of-string cases.TextUtilsKtTestandMessageTextHelpersTestassert that each mention type produces the right annotation/span.stream-chat-android-compose,stream-chat-android-ui-common, andstream-chat-android-ui-components.Summary by CodeRabbit
Release Notes
New Features
Refactor