compose: Introduce AvatarPresenceIndicator and hide offline avatar indicator by default#6518
Conversation
…ate showIndicator
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
|
@CodeRabbit review |
✅ Action performedReview finished.
|
SDK Size Comparison 📏
|
WalkthroughIntroduces an ChangesAvatarPresenceIndicator enum API migration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
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.
Actionable comments posted: 1
🤖 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.
Inline comments:
In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/avatar/UserAvatar.kt`:
- Around line 96-102: The deprecation quick-fix in UserAvatar’s `@Deprecated`
ReplaceWith mapping is incorrect because it does not preserve the showIndicator
= false path and may not import AvatarPresenceIndicator for the caller. Update
the ReplaceWith expression in UserAvatar so it maps false to
AvatarPresenceIndicator.None and true to the existing online/offline logic, and
add AvatarPresenceIndicator to the imports list so the IDE replacement resolves
correctly.
🪄 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: 923afc44-2557-4086-8804-f138effea796
⛔ Files ignored due to path filters (6)
stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.avatar_UserAvatarTest_user_avatar.pngis excluded by!**/*.pngstream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.mentions_MentionListTest_loaded_mention_list.pngis excluded by!**/*.pngstream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.mentions_MentionListTest_loading_more_mention_list.pngis excluded by!**/*.pngstream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loaded_threads.pngis excluded by!**/*.pngstream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loaded_threads_with_unread_banner.pngis excluded by!**/*.pngstream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loading_more_threads.pngis excluded by!**/*.png
📒 Files selected for processing (21)
stream-chat-android-compose/api/stream-chat-android-compose.apistream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/internal/MediaGalleryPhotosMenu.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/AddMembersScreen.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/ChannelInfoMemberInfoModalSheet.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/DirectChannelInfoScreen.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/GroupChannelInfoScreen.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/ChannelActionsSheet.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SearchResultItem.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/avatar/AvatarPresenceIndicator.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/avatar/ChannelAvatar.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/avatar/OnlineIndicator.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/avatar/UserAvatar.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelMembersItem.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollAnswers.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollVoteItem.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/suggestions/MentionSuggestionItem.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/pinned/internal/DefaultPinnedMessageItemContent.ktstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.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/threads/ThreadItem.ktstream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/avatar/AvatarPresenceIndicatorTest.kt
💤 Files with no reviewable changes (6)
- stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollVoteItem.kt
- stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/suggestions/MentionSuggestionItem.kt
- stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollAnswers.kt
- stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/internal/MediaGalleryPhotosMenu.kt
- stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/AddMembersScreen.kt
- stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/pinned/internal/DefaultPinnedMessageItemContent.kt
|
gpunto
left a comment
There was a problem hiding this comment.
LG, just left a doubt but probably it can be ignored


Goal
Today the Compose SDK always draws a presence dot on user avatars when the indicator is requested: green when the user is online and grey when offline. This does not match the design system ("Common / Avatar Behavior") or the other Stream SDKs, which show the indicator only when the user is online.
This change hides the indicator when the user is offline by default, and gives integrators per-call control over the presence state. It is aligned with the iOS SwiftUI
AvatarIndicator.Linear: https://linear.app/stream/issue/AND-1257
Implementation
AvatarPresenceIndicatorenum withOnline,Offline, andNone, mirroring the iOS SwiftUIAvatarIndicator.UserAvatarandChannelAvatarnow takeindicator: AvatarPresenceIndicator = None. The sharedOnlineIndicatordraws green forOnline, grey forOffline, and nothing forNone. This is the single place the dot is rendered, so every screen that shows a presence indicator is covered.AvatarPresenceIndicator.Offline, or override the avatar inChatComponentFactory. There is no theme flag, which matches how iOS does it.showIndicator: Booleanparameter is deprecated and kept on both composables and onUserAvatarParams/ChannelAvatarParams, alongside the newindicator. The deprecated path preserves today's behavior (green online, grey offline) so existing integrations do not change silently. The factory resolvesparams.indicator, falling back to the deprecatedshowIndicatorwhenindicatoris not set.🎨 UI Changes
Avatars that show a presence indicator no longer draw the grey dot when the user is offline; they show nothing. Online avatars are unchanged (green dot). This is visible on the channel and contact info screens, the members list, the channel actions sheet, search results, and thread items.
The updated Paparazzi snapshots in this PR capture the before/after (the grey offline dot is removed from
UserAvatarTest,ThreadListTest, andMentionListTest).Testing
Manual steps in the Compose sample app:
ChatThemecomponentFactoryoverride ofUserAvatar, passindicator = AvatarPresenceIndicator.Offline(orif (user.online) AvatarPresenceIndicator.Online else AvatarPresenceIndicator.Offline) and confirm the grey dot returns for offline users.AvatarPresenceIndicatorTestcovers the resolver mapping (online, offline with and without the opt-in, the channel "any member online" rule, and the null current user case).Summary by CodeRabbit
New Features
Bug Fixes
Tests