Fix mention suggestion filter to align with Swift SDK#6358
Fix mention suggestion filter to align with Swift SDK#6358
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
WalkthroughThe PR refactors the mention/user query filtering system by moving Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/query/filter/DefaultUserQueryFilter.kt`:
- Around line 29-37: Update the public KDoc on DefaultUserQueryFilter to
explicitly state its thread expectations and whether it holds internal state:
indicate if instances are thread-safe / can be called from any thread or are
confined to a single thread, and clearly state whether the class is stateless
(no mutable instance fields) or is stateful (documents what state is retained
and how to safely reuse instances). Reference the class name
DefaultUserQueryFilter and its constructor/transliterator parameter in the KDoc
so callers know the thread-safety and reusability guarantees.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 213c439c-918a-4868-b1df-fb5ffcc06498
📒 Files selected for processing (12)
stream-chat-android-docs/src/main/java/io/getstream/chat/docs/java/ui/messages/MessageComposer.javastream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/ui/messages/MessageComposer.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/DefaultUserLookupHandler.ktstream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/DefaultUserQueryFilter.ktstream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/LocalUserLookupHandler.ktstream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/query/filter/DefaultQueryFilter.ktstream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/query/filter/DefaultUserQueryFilter.ktstream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/query/formatter/Combine.ktstream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/query/formatter/Transliterate.ktstream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/query/filter/DefaultUserQueryFilterTest.ktstream-chat-android-ui-components-sample/src/main/kotlin/io/getstream/chat/ui/sample/feature/chat/ChatFragment.kt
💤 Files with no reviewable changes (2)
- stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/mention/DefaultUserQueryFilter.kt
- stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/query/filter/DefaultQueryFilter.kt
| /** | ||
| * Default [QueryFilter] for [User] objects used in mention suggestions. | ||
| * | ||
| * Keeps only users whose normalized name (or id) contains the normalized query as a substring, | ||
| * then sorts results by Levenshtein distance so the closest matches appear first. Normalization | ||
| * applies lowercasing, diacritics removal, and optional transliteration. | ||
| * | ||
| * @param transliterator The transliterator to use for normalizing strings. | ||
| */ |
There was a problem hiding this comment.
Add thread/state notes to the public KDoc.
The class KDoc is good, but it should explicitly state thread expectations and statefulness for this public API.
Proposed KDoc update
/**
* Default [QueryFilter] for [User] objects used in mention suggestions.
*
* Keeps only users whose normalized name (or id) contains the normalized query as a substring,
* then sorts results by Levenshtein distance so the closest matches appear first. Normalization
* applies lowercasing, diacritics removal, and optional transliteration.
+ *
+ * Threading: Stateless and safe to call from any thread.
+ * State: This filter keeps no mutable internal state.
*
* `@param` transliterator The transliterator to use for normalizing strings.
*/As per coding guidelines **/*.kt: Document public APIs with KDoc, including thread expectations and state notes.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** | |
| * Default [QueryFilter] for [User] objects used in mention suggestions. | |
| * | |
| * Keeps only users whose normalized name (or id) contains the normalized query as a substring, | |
| * then sorts results by Levenshtein distance so the closest matches appear first. Normalization | |
| * applies lowercasing, diacritics removal, and optional transliteration. | |
| * | |
| * @param transliterator The transliterator to use for normalizing strings. | |
| */ | |
| /** | |
| * Default [QueryFilter] for [User] objects used in mention suggestions. | |
| * | |
| * Keeps only users whose normalized name (or id) contains the normalized query as a substring, | |
| * then sorts results by Levenshtein distance so the closest matches appear first. Normalization | |
| * applies lowercasing, diacritics removal, and optional transliteration. | |
| * | |
| * Threading: Stateless and safe to call from any thread. | |
| * State: This filter keeps no mutable internal state. | |
| * | |
| * `@param` transliterator The transliterator to use for normalizing strings. | |
| */ |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/query/filter/DefaultUserQueryFilter.kt`
around lines 29 - 37, Update the public KDoc on DefaultUserQueryFilter to
explicitly state its thread expectations and whether it holds internal state:
indicate if instances are thread-safe / can be called from any thread or are
confined to a single thread, and clearly state whether the class is stateless
(no mutable instance fields) or is stateful (documents what state is retained
and how to safely reuse instances). Reference the class name
DefaultUserQueryFilter and its constructor/transliterator parameter in the KDoc
so callers know the thread-safety and reusability guarantees.
SDK Size Comparison 📏
|
...ream/chat/android/ui/common/feature/messages/composer/query/filter/DefaultUserQueryFilter.kt
Outdated
Show resolved
Hide resolved
…zzy Levenshtein filtering. The previous implementation filtered by Levenshtein distance < threshold, causing short queries like @jc to match unrelated names (e.g. "Aleksandar") because the distance was below the cutoff. Now filters by substring containment and sorts by Levenshtein distance, aligning with the Swift SDK.
…ages.composer.query classes
…tor it to replace the generic `DefaultQueryFilter`. Update all references and tests to use the new `DefaultUserQueryFilter` implementation.
…ages.composer classes
af9c9ef to
0bd9efe
Compare
|



Goal
Fix the mention suggestion filter (
@mentions) which returned unrelated users for short queries. For example, typing@jcin a channel with "Aleksandar Apostolov" and "Jc Minarro" showed both users instead of only "Jc Minarro". Aligns the filtering behavior with the Swift SDK.Implementation
Replace fuzzy Levenshtein filtering with substring matching (
DefaultUserQueryFilter):DefaultQueryFilterfiltered by Levenshtein distance < threshold, which was too permissive for short queries (e.g. distance between "jc" and "al" is 2, below the threshold of 3).Merge
DefaultQueryFilterintoDefaultUserQueryFilter:DefaultQueryFilter<T>was a generic internal class only ever used withUser. Merged intoDefaultUserQueryFilter(the public class) to eliminate the unnecessary abstraction.DefaultUserQueryFilterfrommentionpackage toquery.filterpackage where it belongs alongsideQueryFilter.Reduce visibility of internal classes:
DefaultQueryFilter→ removed (merged intoDefaultUserQueryFilter)Combine,Transliterate→internal(only used byDefaultUserQueryFilter)LocalUserLookupHandler→internal(no external consumers)Fix handler defaults:
LocalUserLookupHandlerandDefaultUserLookupHandlernow useDefaultUserQueryFilter()as default instead of creatingDefaultQueryFilterdirectly, ensuring consistent behavior.Testing
@followed by a short query (e.g.@jc,@al,@ale) — verify only users whose name or id contains the typed substring are shown.@josematches "José")../gradlew :stream-chat-android-ui-common:testDebugUnitTest— all unit tests pass.Summary by CodeRabbit
Refactor
Tests