Allow voters to add poll comments in UI Components#6444
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 adds poll comment functionality to the Stream Chat Android message list UI. It introduces new listener interfaces and public setter methods on ChangesPoll Comment Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 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.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
stream-chat-android-ui-components/api/stream-chat-android-ui-components.api (1)
3254-3279:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift
PollViewStylenow has a breaking constructor/copy signature change.This widens the public data-class-style surface without preserving the old constructor/copy shape. Any consumer instantiating or copying
PollViewStyledirectly will need source changes after upgrading.🤖 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 3254 - 3279, The PollViewStyle data-class API changed its public constructor/copy signature (seen in PollViewStyle.<init>, copy and copy$default) which breaks callers relying on the previous parameter order/shape; restore binary compatibility by reintroducing the old constructor and copy overload(s) delegating to the new implementation (add a deprecated constructor and a synthetic copy overload with the previous parameter list that forwards to the new copy), or provide `@JvmOverloads/explicit` overloads on PollViewStyle to preserve the original parameter permutations so existing consumers (calling componentX(), copy(...), or using the constructor) continue to work.stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/MessageListListenerContainerImpl.kt (1)
41-66:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftConstructor now trips Detekt
LongParameterListand blocks CI.This constructor expansion is the direct cause of the current CI failure (
:stream-chat-android-ui-components:detekt). Please reduce top-level constructor args by grouping related poll listeners into a single parameter object.Suggested refactor sketch
internal class MessageListListenerContainerImpl( @@ - onPollOptionClickListener: OnPollOptionClickListener, - onShowAllPollOptionClickListener: OnShowAllPollOptionClickListener, - onPollCloseClickListener: OnPollCloseClickListener, - onViewPollResultClickListener: OnViewPollResultClickListener, - onSuggestPollOptionClickListener: OnSuggestPollOptionClickListener, - onAddPollCommentClickListener: OnAddPollCommentClickListener, - onViewPollCommentsClickListener: OnViewPollCommentsClickListener, + pollListeners: PollListeners, ) : MessageListListeners { + + internal data class PollListeners( + val onPollOptionClickListener: OnPollOptionClickListener, + val onShowAllPollOptionClickListener: OnShowAllPollOptionClickListener, + val onPollCloseClickListener: OnPollCloseClickListener, + val onViewPollResultClickListener: OnViewPollResultClickListener, + val onSuggestPollOptionClickListener: OnSuggestPollOptionClickListener, + val onAddPollCommentClickListener: OnAddPollCommentClickListener, + val onViewPollCommentsClickListener: OnViewPollCommentsClickListener, + ) @@ override var onPollOptionClickListener: OnPollOptionClickListener by ListenerDelegate( - onPollOptionClickListener, + pollListeners.onPollOptionClickListener, @@ override var onShowAllPollOptionClickListener: OnShowAllPollOptionClickListener by ListenerDelegate( - onShowAllPollOptionClickListener, + pollListeners.onShowAllPollOptionClickListener, @@ override var onPollCloseClickListener: OnPollCloseClickListener by ListenerDelegate( - onPollCloseClickListener, + pollListeners.onPollCloseClickListener, @@ override var onViewPollResultClickListener: OnViewPollResultClickListener by ListenerDelegate( - onViewPollResultClickListener, + pollListeners.onViewPollResultClickListener, @@ override var onSuggestPollOptionClickListener: OnSuggestPollOptionClickListener by ListenerDelegate( - onSuggestPollOptionClickListener, + pollListeners.onSuggestPollOptionClickListener, @@ override var onAddPollCommentClickListener: OnAddPollCommentClickListener by ListenerDelegate( - onAddPollCommentClickListener, + pollListeners.onAddPollCommentClickListener, @@ override var onViewPollCommentsClickListener: OnViewPollCommentsClickListener by ListenerDelegate( - onViewPollCommentsClickListener, + pollListeners.onViewPollCommentsClickListener,🤖 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/adapter/MessageListListenerContainerImpl.kt` around lines 41 - 66, The MessageListListenerContainerImpl constructor has too many top-level parameters (causing Detekt LongParameterList); create a single data class (e.g., PollListeners or PollListenerConfig) that groups all poll-related listeners (onPollOptionClickListener, onShowAllPollOptionClickListener, onPollCloseClickListener, onViewPollResultClickListener, onSuggestPollOptionClickListener, onAddPollCommentClickListener, onViewPollCommentsClickListener) and replace those individual parameters in MessageListListenerContainerImpl's constructor with one parameter of that new type, update usages and assignments inside the class to access the grouped listeners via the new property, and ensure default values or helper constructors are provided to keep existing call sites working.stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/PollView.kt (1)
90-99:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDetekt
LongParameterListis a merge blocker here.The constructor now has 8 parameters (Line 152+), and CI already fails on this exact rule. Group callbacks into a single holder object (or equivalent) to get back under the threshold.
♻️ Suggested refactor sketch
+private data class PollAdapterCallbacks( + val onOptionClick: (Option) -> Unit, + val onClosePollClick: () -> Unit, + val onViewPollResultsClick: () -> Unit, + val onShowAllOptionsClick: () -> Unit, + val onSuggestOptionClick: () -> Unit, + val onAddCommentClick: () -> Unit, + val onViewCommentsClick: () -> Unit, +) + private class PollAdapter( private val pollViewStyle: PollViewStyle, - private val onOptionClick: (Option) -> Unit, - private val onClosePollClick: () -> Unit, - private val onViewPollResultsClick: () -> Unit, - private val onShowAllOptionsClick: () -> Unit, - private val onSuggestOptionClick: () -> Unit, - private val onAddCommentClick: () -> Unit, - private val onViewCommentsClick: () -> Unit, + private val callbacks: PollAdapterCallbacks, ) : ListAdapter<PollItem, PollItemViewHolder<out PollItem>>(PollItemDiffCallback)Also applies to: 152-161
🤖 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/adapter/view/internal/PollView.kt` around lines 90 - 99, The PollAdapter constructor call in PollView currently passes eight separate callback parameters (onOptionClick, onClosePollClick, onViewPollResultsClick, onShowAllOptionsClick, onSuggestOptionClick, onAddCommentClick, onViewCommentsClick) causing a Detekt LongParameterList violation; fix it by introducing a single callback holder data class (e.g., PollAdapter.Callbacks or PollCallbacks) that aggregates these lambdas, update PollAdapter's constructor and usages to accept that single holder, and change the PollView instantiation to pass one callbacks object (populate with the existing lambdas like { option -> onOptionClick(option) } and { onClosePollClick(poll) } etc.); ensure you update any other call sites (mentioned also around lines 152-161) to use the new holder type and keep the existing lambda behaviors intact.
🤖 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-ui-components/api/stream-chat-android-ui-components.api`:
- Around line 5009-5022: The new public event type
MessageListViewModel.Event.PollAnswerCast should not be added to the public
Event hierarchy; change its visibility and placement so it is internal to the
module and not part of the public sealed interface used by callers.
Specifically, remove or revert the public nested class PollAnswerCast from
MessageListViewModel.Event and instead implement the wiring as an
internal/top-level internal class or a private nested type (e.g., internal class
PollAnswerCast or private object used by the fragment-result handler) so
downstream when-expressions are unaffected; ensure references to
MessageListViewModel.Event.PollAnswerCast in the fragment-result code are
updated to the new internal symbol and that no public API surface exposes this
type.
- Around line 3168-3173: The new abstract getters added to MessageListListeners
(getOnAddPollCommentClickListener, getOnPollCloseClickListener,
getOnPollOptionClickListener, getOnShowAllPollOptionClickListener,
getOnSuggestPollOptionClickListener, getOnViewPollCommentsClickListener) are a
binary/source breaking change for external implementers; change them to
non-abstract defaulted accessors (provide default implementations that return
null or a no-op listener) or remove them from the public interface and expose
them via an internal/optional extension so existing implementers continue to
compile—locate the MessageListListeners interface and replace each abstract
getter with a default method implementation returning a safe default.
In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/PollView.kt`:
- Around line 136-141: The "Add a comment" gating currently uses
poll.answers.isEmpty(), which blocks users who haven't answered from adding a
comment after someone else has; change the condition to check whether the
current user has already answered instead. In PollView.kt, compute a
userHasAnswered boolean from poll.answers (e.g., poll.answers.any { it.userId ==
currentUserId } or equivalent) and replace the poll.answers.isEmpty() check in
the PollItem.AddComment branch with !userHasAnswered while keeping
poll.allowAnswers and !poll.closed; keep PollItem.ViewComments logic as-is.
In
`@stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/viewmodels/messages/MessageListViewModelTest.kt`:
- Around line 208-212: The invocation of
MessageListViewModel.Event.PollAnswerCast (with messageId = message1.id, pollId
= pollId, answer = answer) violates Spotless formatting because it is missing
the required trailing comma; update the call site for PollAnswerCast to include
a trailing comma after the final argument so ktlint/Spotless pass (run ./gradlew
spotlessApply to auto-fix and ./gradlew spotlessCheck to verify).
---
Outside diff comments:
In `@stream-chat-android-ui-components/api/stream-chat-android-ui-components.api`:
- Around line 3254-3279: The PollViewStyle data-class API changed its public
constructor/copy signature (seen in PollViewStyle.<init>, copy and copy$default)
which breaks callers relying on the previous parameter order/shape; restore
binary compatibility by reintroducing the old constructor and copy overload(s)
delegating to the new implementation (add a deprecated constructor and a
synthetic copy overload with the previous parameter list that forwards to the
new copy), or provide `@JvmOverloads/explicit` overloads on PollViewStyle to
preserve the original parameter permutations so existing consumers (calling
componentX(), copy(...), or using the constructor) continue to work.
In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/MessageListListenerContainerImpl.kt`:
- Around line 41-66: The MessageListListenerContainerImpl constructor has too
many top-level parameters (causing Detekt LongParameterList); create a single
data class (e.g., PollListeners or PollListenerConfig) that groups all
poll-related listeners (onPollOptionClickListener,
onShowAllPollOptionClickListener, onPollCloseClickListener,
onViewPollResultClickListener, onSuggestPollOptionClickListener,
onAddPollCommentClickListener, onViewPollCommentsClickListener) and replace
those individual parameters in MessageListListenerContainerImpl's constructor
with one parameter of that new type, update usages and assignments inside the
class to access the grouped listeners via the new property, and ensure default
values or helper constructors are provided to keep existing call sites working.
In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/PollView.kt`:
- Around line 90-99: The PollAdapter constructor call in PollView currently
passes eight separate callback parameters (onOptionClick, onClosePollClick,
onViewPollResultsClick, onShowAllOptionsClick, onSuggestOptionClick,
onAddCommentClick, onViewCommentsClick) causing a Detekt LongParameterList
violation; fix it by introducing a single callback holder data class (e.g.,
PollAdapter.Callbacks or PollCallbacks) that aggregates these lambdas, update
PollAdapter's constructor and usages to accept that single holder, and change
the PollView instantiation to pass one callbacks object (populate with the
existing lambdas like { option -> onOptionClick(option) } and {
onClosePollClick(poll) } etc.); ensure you update any other call sites
(mentioned also around lines 152-161) to use the new holder type and keep the
existing lambda behaviors intact.
🪄 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: 602a4ba6-e38f-4c38-b934-b516f3a75d53
📒 Files selected for processing (22)
stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.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/AddPollCommentDialogFragment.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/PollCommentsDialogFragment.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/kotlin/io/getstream/chat/android/ui/viewmodel/messages/PollCommentsViewModel.ktstream-chat-android-ui-components/src/main/res/layout/stream_ui_dialog_add_poll_comment.xmlstream-chat-android-ui-components/src/main/res/layout/stream_ui_fragment_poll_comments.xmlstream-chat-android-ui-components/src/main/res/layout/stream_ui_item_poll_add_comment.xmlstream-chat-android-ui-components/src/main/res/layout/stream_ui_item_poll_comment.xmlstream-chat-android-ui-components/src/main/res/layout/stream_ui_item_poll_view_comments.xmlstream-chat-android-ui-components/src/main/res/values/attrs_poll_view.xmlstream-chat-android-ui-components/src/main/res/values/strings.xmlstream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/viewmodels/messages/MessageListViewModelTest.ktstream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/viewmodels/messages/PollCommentsViewModelTest.kt
92cd74e to
f86ec7c
Compare
3bcd819 to
9c84142
Compare
9c84142 to
e167412
Compare
|



Goal
Bring the "voters can add comments" poll feature to the XML UI Components, matching what's already available in the Compose UI.
Implementation
PollViewrenders two new entries: "Add a comment" whenpoll.allowAnswersistrue, the poll is open, and the user hasn't commented yet; and "View N comments" once any answer exists.AddPollCommentDialogFragmentcollects the comment text and returns it via the fragment-result API;MessageListViewModel.bindViewlistens for the result and emitsEvent.PollAnswerCast(messageId, pollId, answer), which the view model forwards toMessageListController.castAnswer.PollCommentsDialogFragmentlists comments and shows an "Add a comment" / "Update comment" CTA depending on whether the current user has already answered.PollViewStylegainspollAddCommentTextStyleandpollViewCommentsTextStylewith matchingstreamUiPollAddComment*andstreamUiPollViewComments*attributes for customization.UI Changes
Testing
allowAnswers = true: an "Add a comment" entry shows up until the current user posts an answer; afterwards a "View N comments" entry replaces it.Summary by CodeRabbit
New Features
Tests