Allow voters to suggest poll options in UI Components#6439
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
SDK Size Comparison 📏
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
WalkthroughThis PR implements end-to-end support for user-suggested poll options in the message list UI. It refactors the ChangesSuggest Poll Option Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 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.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
stream-chat-android-ui-components/api/stream-chat-android-ui-components.api (2)
3074-3086:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftUse a default method instead of abstract to maintain binary compatibility.
Adding a new abstract method to a public interface breaks binary compatibility with existing compiled implementations. Pre-compiled code implementing
MessageListListenerswill fail at runtime when the JVM expects the new method. Replace the abstract getter with a default method that returns a sensible default (or no-op) implementation.🤖 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-components/api/stream-chat-android-ui-components.api` around lines 3074 - 3086, The new abstract getter getOnSuggestPollOptionClickListener added to the MessageListListeners interface breaks binary compatibility; change it from an abstract declaration to a default method on interface io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListListeners that returns a safe default (e.g., null or a no-op MessageListView.OnSuggestPollOptionClickListener) so existing compiled implementors continue to work; implement the default directly on the interface alongside the other getters (e.g., provide default fun getOnSuggestPollOptionClickListener(): MessageListView.OnSuggestPollOptionClickListener? = null).
3167-3178:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftThis
PollViewStylesignature change is ABI-breaking.Adding a new primary-constructor property changes the public constructor,
copy,copy$default, andcomponentNsurface of an existing public type. Existing compiled consumers of the old API won't link cleanly. Preserve the old constructor/copy ABI and surface the new style through a compatibility-preserving API.🤖 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-components/api/stream-chat-android-ui-components.api` around lines 3167 - 3178, The change to PollViewStyle added a new primary-constructor property which breaks the public ABI (constructor, copy, copy$default, componentN); restore backward compatibility by preserving the old constructor/copy/component methods: keep the original constructor signature available (add a secondary/overload that matches the previous parameter list and delegates to the new primary, supplying a sensible default for the new property), and provide compatibility shims for copy/copy$default and component1..componentN (implement overloads or synthetic forwarding methods with the original signatures that delegate to the new implementations) so existing compiled consumers can still link against PollViewStyle while exposing the new property via the new API.
🧹 Nitpick comments (2)
stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/MessageListController.kt (1)
2453-2463: ⚡ Quick winConsider adding error handling for better user experience.
The method silently swallows errors when the API call fails, leaving users without feedback when suggesting an option fails. For consistency with other
pollId-based methods in this class (e.g.,closePoll(pollId: String)at line 2004,castVoteat line 1945), consider using the.enqueue(onError = ...)pattern to handle errors gracefully.Suggested error handling pattern
public fun addPollOption(pollId: String, option: String) { - scope.launch { - chatClient.createPollOption(pollId, PollOption(text = option)).await() - } + chatClient.createPollOption(pollId, PollOption(text = option)) + .enqueue(onError = { error -> + onActionResult(error) { + ErrorEvent.PollCastingVoteError(it) + } + }) }🤖 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/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/MessageListController.kt` around lines 2453 - 2463, The addPollOption method currently launches a coroutine and calls chatClient.createPollOption(...).await() but swallows errors; update addPollOption(pollId: String, option: String) to use the same enqueue(onError = ...) pattern used by closePoll and castVote: call chatClient.createPollOption(pollId, PollOption(text = option)).enqueue(onError = { /* log or surface error to UI / callback */ }) (or propagate the error via the controller callback/state) so failures are logged/handled instead of silently ignored.stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/SuggestPollOptionDialogFragment.kt (1)
19-19: 💤 Low valuePrefer
androidx.appcompat.app.AlertDialogfor consistency with AppCompat base class.Since this fragment extends
AppCompatDialogFragment, usingandroidx.appcompat.app.AlertDialoginstead ofandroid.app.AlertDialogwould be more consistent with the AndroidX/AppCompat ecosystem.♻️ Suggested import change
-import android.app.AlertDialog +import androidx.appcompat.app.AlertDialog🤖 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-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/SuggestPollOptionDialogFragment.kt` at line 19, Replace the platform AlertDialog import with the AppCompat one for consistency: in SuggestPollOptionDialogFragment (class extending AppCompatDialogFragment) remove import android.app.AlertDialog and use androidx.appcompat.app.AlertDialog instead so the fragment uses AppCompat's AlertDialog; update any fully-qualified references if present to the androidx.appcompat.app.AlertDialog symbol.
🤖 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.
Outside diff comments:
In `@stream-chat-android-ui-components/api/stream-chat-android-ui-components.api`:
- Around line 3074-3086: The new abstract getter
getOnSuggestPollOptionClickListener added to the MessageListListeners interface
breaks binary compatibility; change it from an abstract declaration to a default
method on interface
io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListListeners
that returns a safe default (e.g., null or a no-op
MessageListView.OnSuggestPollOptionClickListener) so existing compiled
implementors continue to work; implement the default directly on the interface
alongside the other getters (e.g., provide default fun
getOnSuggestPollOptionClickListener():
MessageListView.OnSuggestPollOptionClickListener? = null).
- Around line 3167-3178: The change to PollViewStyle added a new
primary-constructor property which breaks the public ABI (constructor, copy,
copy$default, componentN); restore backward compatibility by preserving the old
constructor/copy/component methods: keep the original constructor signature
available (add a secondary/overload that matches the previous parameter list and
delegates to the new primary, supplying a sensible default for the new
property), and provide compatibility shims for copy/copy$default and
component1..componentN (implement overloads or synthetic forwarding methods with
the original signatures that delegate to the new implementations) so existing
compiled consumers can still link against PollViewStyle while exposing the new
property via the new API.
---
Nitpick comments:
In
`@stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/MessageListController.kt`:
- Around line 2453-2463: The addPollOption method currently launches a coroutine
and calls chatClient.createPollOption(...).await() but swallows errors; update
addPollOption(pollId: String, option: String) to use the same enqueue(onError =
...) pattern used by closePoll and castVote: call
chatClient.createPollOption(pollId, PollOption(text = option)).enqueue(onError =
{ /* log or surface error to UI / callback */ }) (or propagate the error via the
controller callback/state) so failures are logged/handled instead of silently
ignored.
In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/SuggestPollOptionDialogFragment.kt`:
- Line 19: Replace the platform AlertDialog import with the AppCompat one for
consistency: in SuggestPollOptionDialogFragment (class extending
AppCompatDialogFragment) remove import android.app.AlertDialog and use
androidx.appcompat.app.AlertDialog instead so the fragment uses AppCompat's
AlertDialog; update any fully-qualified references if present to the
androidx.appcompat.app.AlertDialog symbol.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 0f4de5d3-8cc1-4dbb-b1b8-7b7a31adbac6
📒 Files selected for processing (16)
stream-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/list/MessageListController.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/MessageListListenerContainer.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/MessageListListenerContainerImpl.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/PollViewStyle.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/PollView.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/viewholder/impl/PollViewHolder.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/SuggestPollOptionDialogFragment.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/viewmodel/messages/MessageListViewModel.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/viewmodel/messages/MessageListViewModelBinding.ktstream-chat-android-ui-components/src/main/res/layout/stream_ui_dialog_suggest_poll_option.xmlstream-chat-android-ui-components/src/main/res/layout/stream_ui_item_poll_suggest_option.xmlstream-chat-android-ui-components/src/main/res/values/attrs_poll_view.xmlstream-chat-android-ui-components/src/main/res/values/strings.xml
ea18512 to
d0a51b5
Compare
|



Goal
Bring the "voters can suggest new options" poll feature to the XML UI Components, matching what's
already available in the Compose UI.
Implementation
PollViewrenders a new "Suggest an option" entry whenpoll.allowUserSuggestedOptionsistrueand the poll is open. Tapping it routes through a new
OnSuggestPollOptionClickListeneronMessageListView, whose default handler showsSuggestPollOptionDialogFragment.SuggestPollOptionDialogFragmentcollects the option text and returns it via the fragment-resultAPI;
MessageListViewModel.bindViewlistens for the result and emits a newEvent.PollOptionSuggested(pollId, option).MessageListControllernow exposes anaddPollOption(pollId, option)overload so the suggestedoption can be added without first resolving a
Poll. The existingaddPollOption(Poll, String)delegates to it.
PollViewStylegainspollSuggestOptionTextStylewith matchingstreamUiPollSuggestOption*attributes for customization.
UI Changes
Testing
allowUserSuggestedOptions = true: a "Suggest an option"button shows up; closed polls and polls without the flag do not show it.
confirming adds the option to the poll, dismissing does not.
Summary by CodeRabbit
Release Notes
New Features
Style