Skip to content

Port v6 XML poll improvements to develop#6468

Merged
gpunto merged 14 commits into
developfrom
v7-xml-poll-port
May 27, 2026
Merged

Port v6 XML poll improvements to develop#6468
gpunto merged 14 commits into
developfrom
v7-xml-poll-port

Conversation

@gpunto
Copy link
Copy Markdown
Contributor

@gpunto gpunto commented May 25, 2026

Goal

Port the recent v6 XML changes over to develop.

Bundles the following v6 PRs:

https://linear.app/stream/issue/AND-603/xmlpolls-some-features-are-missing

Implementation

  • Cherry-picks each commit from v6 onto develop.
  • Adapts the cherry-picks to develop's renamed APIs:
    • MessageListListenerContainer / MessageListListenerContainerImpl are MessageListListeners / MessageListListenersImpl on develop.
    • CreatePollDialogListener.onCreatePoll takes CreatePollParams instead of PollConfig.
    • StateRegistry and the state() extension now live under io.getstream.chat.android.client.api.state.
    • The stream_ui_poll_action_view_comments plural lives in ui-common, so PollView references it via UiCommonR.plurals instead of R.plurals.

UI Changes

Same as the original PRs.

Testing

  • Open a channel with a poll that has allowAnswers = true: an "Add a comment" entry shows up until the current user posts an answer; afterwards a "View N comments" entry replaces it.
  • Open a poll that allows suggesting options: tap "Suggest an option" and confirm ChatUI.pollsConfig.optionTextLimit is enforced on the input.
  • Open the create-poll dialog with a custom PollsConfig: confirm question/option character limits and feature toggles (multiple votes, anonymous voting, suggest options, add comments) behave as configured.

Summary by CodeRabbit

New Features

  • Added configurable poll creation with customizable features including multiple votes, anonymous settings, text length limits, and comment support
  • Introduced poll comment system allowing users to add and view poll responses
  • Added poll option suggestion feature enabling users to propose custom poll choices
  • Expanded poll UI with new interaction listeners and styling options

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@gpunto gpunto added the pr:new-feature New feature label May 25, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.82 MB 5.82 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.02 MB 11.06 MB 0.04 MB 🟢
stream-chat-android-compose 12.44 MB 12.44 MB 0.00 MB 🟢

gpunto and others added 7 commits May 25, 2026 10:27
* Add configurable character limits and feature toggles for polls

Introduces PollsConfig to control poll feature availability and enforce character limits on questions and options. Poll features (multiple votes, anonymous voting, suggest options, add comments) can now be
hidden or preset with default values through ChatUI.pollsConfig or passed directly to CreatePollDialogFragment.

* addressing pr comments

* 1. Detekt - Fixed the MaxLineLength violation in PollsConfig.kt:23 by breaking the long comment line
  2. Spotless - Applied formatting fixes (added license header to PollFeatureConfig.kt)
  3. API Check - Regenerated the API dump file

* Update stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/composer/attachment/picker/poll/PollsConfig.kt

Co-authored-by: Gianmarco <47775302+gpunto@users.noreply.github.com>

* Apply suggestion from @gpunto

---------

Co-authored-by: Gianmarco <47775302+gpunto@users.noreply.github.com>
* Allow voters to suggest poll options in UI Components

* Use doAfterTextChanged

* Align Compose & XML option name trimming
* Allow voters to add poll comments in UI Components

* Add missing KDoc and default params
- Use UiCommonR for stream_ui_poll_action_view_comments plural
- Update StateRegistry imports to client.api.state package
@gpunto gpunto force-pushed the v7-xml-poll-port branch from bc889eb to 0db6638 Compare May 25, 2026 08:27
@gpunto gpunto marked this pull request as ready for review May 25, 2026 09:21
@gpunto gpunto requested a review from a team as a code owner May 25, 2026 09:21
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Walkthrough

This PR adds comprehensive poll comment and suggestion features to the Stream Chat Android UI, including new dialog fragments for user interactions, configuration types for feature enablement/limits, listener interfaces for click handling, and corresponding view model events and rendering updates across the message list.

Changes

Poll Comments & Suggestions Integration

Layer / File(s) Summary
Poll configuration types and ChatUI integration
stream-chat-android-ui-components/src/main/kotlin/.../PollFeatureConfig.kt, .../PollsConfig.kt, .../ChatUI.kt
New PollFeatureConfig and PollsConfig Parcelable types define per-feature settings and optional text limits for poll creation. ChatUI.pollsConfig exposes global poll configuration with a Default preset.
Poll creation dialog and ViewModel configuration
stream-chat-android-ui-components/src/main/kotlin/.../CreatePollDialogFragment.kt, .../CreatePollViewModel.kt, .../OptionsAdapter.kt
CreatePollDialogFragment accepts optional PollsConfig and applies feature toggles/defaults; enforces question text limits. CreatePollViewModel adds allowAnswers flag. OptionsAdapter enforces optional optionTextLimit via InputFilter.
Poll interaction dialog fragments and layouts
stream-chat-android-ui-components/src/main/kotlin/.../SuggestPollOptionDialogFragment.kt, .../AddPollCommentDialogFragment.kt, .../res/layout/stream_ui_dialog_*.xml
SuggestPollOptionDialogFragment and AddPollCommentDialogFragment collect user input with optional length limits and return results via fragment-result API. Corresponding input layouts with themed EditText views.
Poll comments view and ViewModel
stream-chat-android-ui-components/src/main/kotlin/.../PollCommentsDialogFragment.kt, .../PollCommentsViewModel.kt, .../res/layout/stream_ui_fragment_poll_comments.xml, .../stream_ui_item_poll_comment.xml
PollCommentsViewModel streams Poll data for a message. PollCommentsDialogFragment displays answers with optional "add comment" CTA; CommentsAdapter renders individual comments and user info with formatted timestamps.
Message list poll listener interfaces and wiring
stream-chat-android-ui-components/src/main/kotlin/.../MessageListView.kt, .../MessageListListeners.kt, .../MessageListListenersImpl.kt
Three new listener interfaces (OnSuggestPollOptionClickListener, OnAddPollCommentClickListener, OnViewPollCommentsClickListener) with corresponding setter methods. MessageListListenersImpl wires listeners through delegated properties.
Poll view rendering and styling
stream-chat-android-ui-components/src/main/kotlin/.../internal/PollView.kt, .../PollViewStyle.kt, .../impl/PollViewHolder.kt, .../res/layout/stream_ui_item_poll_*.xml
PollView conditionally appends suggest/add-comment/view-comments items and wires callbacks. PollAdapter creates view holders for new items. PollViewStyle gains text styles for new elements. PollViewHolder delegates clicks to message list listeners.
ViewModel events and fragment result binding
stream-chat-android-ui-components/src/main/kotlin/.../MessageListViewModel.kt, .../MessageListViewModelBinding.kt
New PollOptionSuggested and PollAnswerCast events dispatched from fragment result listeners back to ViewModel onEvent. Events forward to MessageListController methods.
Poll option addition API refactoring
stream-chat-android-ui-common/src/main/kotlin/.../MessageListController.kt, .../api/stream-chat-android-ui-common.api, .../test/.../MessageListControllerTests.kt
addPollOption refactored to accept pollId and option String; existing Poll overload delegates to new API. Public API surface updated. Test verifies correct chatClient.createPollOption invocation.
Layout, string, and attribute resources
stream-chat-android-ui-components/src/main/res/layout/stream_ui_*.xml, values/strings.xml, values/attrs_poll_view.xml
Added XML layouts for poll dialogs/comments view, string resources for dialog labels and UI text, and extended PollView attributes with text-style declarations for suggest option, add comment, and view comments.
Test fixtures and test cases
stream-chat-android-core/src/testFixtures/kotlin/.../Mother.kt, stream-chat-android-ui-components/src/test/kotlin/.../MessageListViewModelTest.kt, .../PollCommentsViewModelTest.kt
Added randomVote fixture helper; new test cases verify addPollOption and PollAnswerCast event handling; PollCommentsViewModel tests cover poll observation and filtering.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

ui-components

Suggested reviewers

  • andremion

Poem

🐰 Hops through polls with glee,
Comments flow like carrots free,
Options suggested, votes now cast,
User voices heard at last!
Fuzzy magic, chat so fine!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.58% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: porting v6 XML poll improvements to develop. It is concise, clear, and specifically describes the primary objective of the changeset.
Description check ✅ Passed The description is comprehensive and well-structured. It clearly explains the Goal (porting v6 changes), Implementation (cherry-picks and API adaptations), mentions UI Changes (consistent with original PRs), provides Testing instructions with specific scenarios, and references the linear issue. The checklist items are not all marked but the PR includes required information.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch v7-xml-poll-port

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (2)
stream-chat-android-ui-components/src/main/res/layout/stream_ui_dialog_add_poll_comment.xml (1)

23-31: ⚡ Quick win

Consider adding a hint to improve UX.

The EditText has no android:hint attribute. Adding a hint would provide better user guidance about what to enter. However, if the hint is set programmatically in the dialog, this can be skipped.

💡 Suggested enhancement
     <androidx.appcompat.widget.AppCompatEditText
         android:id="@+id/answerInput"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="center_vertical"
+        android:hint="`@string/stream_ui_poll_add_a_comment_label`"
         android:imeOptions="actionDone"
         android:inputType="text"
         android:textAppearance="`@style/StreamUiTextAppearance.Headline`"
         />
🤖 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/res/layout/stream_ui_dialog_add_poll_comment.xml`
around lines 23 - 31, The EditText with id "answerInput"
(androidx.appcompat.widget.AppCompatEditText) has no android:hint, which harms
UX; add a descriptive android:hint attribute (e.g., "Enter answer" or localized
string resource) to the XML for stream_ui_dialog_add_poll_comment.xml unless the
hint is intentionally set in code—if it's set programmatically, verify and leave
as-is, otherwise add the hint to the layout and reference a string resource.
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/PollView.kt (1)

153-153: ⚡ Quick win

Document the LongParameterList suppression (or remove it via callback grouping).

This suppression is currently undocumented; add a brief rationale comment to align with repo Kotlin rules.

Proposed fix
-@Suppress("LongParameterList")
+// Suppressed intentionally: constructor wires discrete UI callbacks explicitly.
+@Suppress("LongParameterList")
 private class PollAdapter(
As per coding guidelines `**/*.kt`: "Use `@OptIn` annotations 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-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/PollView.kt`
at line 153, The `@Suppress`("LongParameterList") on PollView lacks a rationale
comment; update the suppression on PollView (the `@Suppress` declaration in
PollView.kt) to include a short comment explaining why the long parameter list
is acceptable here (e.g., grouping of callback params or UI binding constraints)
or remove the suppression by refactoring/grouping callbacks into a single data
class or listener to reduce parameters; reference the
`@Suppress`("LongParameterList") token and the PollView component when making the
change.
🤖 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 3064-3069: The diff added new abstract getters on the public
interface MessageListListeners (getOnAddPollCommentClickListener,
getOnPollCloseClickListener, getOnPollOptionClickListener,
getOnShowAllPollOptionClickListener, getOnSuggestPollOptionClickListener,
getOnViewPollCommentsClickListener), which is a binary-breaking change; instead
either make each of these methods a default interface method with a safe default
(e.g., return null or a no-op listener) in MessageListListeners so existing
implementers remain compatible, or move these poll-related hooks into a new
interface (e.g., MessageListPollListeners) and keep MessageListListeners
unchanged so implementers can opt-in; update usages to call the default methods
or the new interface without changing the existing abstract surface.
- Around line 3150-3176: PollViewStyle's ABI changed because two new properties
were added to the data class primary constructor (which altered the generated
primary constructor, copy and componentN signatures like
component10/component11); revert ABI break by removing the new properties from
the data class primary constructor and instead declare them as regular
properties with default values inside the class body (keep the original 11
primary-constructor params intact so generated copy/componentN/constructor
signatures remain unchanged), update any internal usage to read the new in-body
vals and keep the existing getter names (getPollAddCommentTextStyle,
getPollViewCommentsTextStyle) so consumers can still access them without ABI
changes.

In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/composer/attachment/picker/poll/OptionsAdapter.kt`:
- Around line 72-75: The init block in OptionsAdapter applies an
InputFilter.LengthFilter unconditionally when optionTextLimit is non-null, which
breaks input for 0 or negative limits; change the guard to only apply the filter
when optionTextLimit != null && optionTextLimit > 0 (mirror the question limit
check), i.e., update the init logic around binding.option.filters and the
optionTextLimit handling in OptionsAdapter so the LengthFilter is only set for
positive limits.

In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/composer/attachment/picker/poll/PollsConfig.kt`:
- Around line 39-48: Add validation in the PollsConfig init block to ensure
questionTextLimit and optionTextLimit, when non-null, are positive integers;
update the existing init (which already validates multipleVotes) to also
require(questionTextLimit == null || questionTextLimit > 0) and
require(optionTextLimit == null || optionTextLimit > 0) with clear error
messages referencing questionTextLimit/optionTextLimit so invalid non-positive
limits are rejected at construction.

In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/PollViewStyle.kt`:
- Around line 41-43: The new PollViewStyle constructor adds
pollSuggestOptionTextStyle without a default which breaks existing callers; give
pollSuggestOptionTextStyle a default value (e.g., TextStyle()) in the
PollViewStyle declaration so it matches pollAddCommentTextStyle and
pollViewCommentsTextStyle and preserves backward-compatible construction of
PollViewStyle.

In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/SuggestPollOptionDialogFragment.kt`:
- Around line 56-57: The dialog currently reads raw input into val text =
binding.optionInput.text?.toString().orEmpty() and later validates using trimmed
text, which allows whitespace-padded options to be submitted and leaves the
confirm button state stale on reopen/restore; update
SuggestPollOptionDialogFragment to always normalize input by using the trimmed
string for both validation and submission (e.g., derive textTrimmed =
binding.optionInput.text?.toString().orEmpty().trim()), replace usages of the
raw text with textTrimmed, and when initializing/restoring the dialog set the
confirm button enabled state from textTrimmed.isNotBlank() so the confirm button
reflects the current input without requiring further edits (apply same change to
the other occurrence around lines 70-75).

---

Nitpick comments:
In
`@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/PollView.kt`:
- Line 153: The `@Suppress`("LongParameterList") on PollView lacks a rationale
comment; update the suppression on PollView (the `@Suppress` declaration in
PollView.kt) to include a short comment explaining why the long parameter list
is acceptable here (e.g., grouping of callback params or UI binding constraints)
or remove the suppression by refactoring/grouping callbacks into a single data
class or listener to reduce parameters; reference the
`@Suppress`("LongParameterList") token and the PollView component when making the
change.

In
`@stream-chat-android-ui-components/src/main/res/layout/stream_ui_dialog_add_poll_comment.xml`:
- Around line 23-31: The EditText with id "answerInput"
(androidx.appcompat.widget.AppCompatEditText) has no android:hint, which harms
UX; add a descriptive android:hint attribute (e.g., "Enter answer" or localized
string resource) to the XML for stream_ui_dialog_add_poll_comment.xml unless the
hint is intentionally set in code—if it's set programmatically, verify and leave
as-is, otherwise add the hint to the layout and reference a string resource.
🪄 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: edeb4362-4ae8-4305-90cf-76b289bf08fc

📥 Commits

Reviewing files that changed from the base of the PR and between 152245e and 0db6638.

📒 Files selected for processing (34)
  • stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt
  • stream-chat-android-ui-common/api/stream-chat-android-ui-common.api
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/MessageListController.kt
  • stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/MessageListControllerTests.kt
  • stream-chat-android-ui-components/api/stream-chat-android-ui-components.api
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/ChatUI.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/composer/attachment/picker/poll/CreatePollDialogFragment.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/composer/attachment/picker/poll/CreatePollViewModel.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/composer/attachment/picker/poll/OptionsAdapter.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/composer/attachment/picker/poll/PollFeatureConfig.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/composer/attachment/picker/poll/PollsConfig.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/MessageListView.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/MessageListListeners.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/MessageListListenersImpl.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/PollViewStyle.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/PollView.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/viewholder/impl/PollViewHolder.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/AddPollCommentDialogFragment.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/PollCommentsDialogFragment.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/internal/poll/SuggestPollOptionDialogFragment.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/viewmodel/messages/MessageListViewModel.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/viewmodel/messages/MessageListViewModelBinding.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/viewmodel/messages/PollCommentsViewModel.kt
  • stream-chat-android-ui-components/src/main/res/layout/stream_ui_dialog_add_poll_comment.xml
  • stream-chat-android-ui-components/src/main/res/layout/stream_ui_dialog_suggest_poll_option.xml
  • stream-chat-android-ui-components/src/main/res/layout/stream_ui_fragment_poll_comments.xml
  • stream-chat-android-ui-components/src/main/res/layout/stream_ui_item_poll_add_comment.xml
  • stream-chat-android-ui-components/src/main/res/layout/stream_ui_item_poll_comment.xml
  • stream-chat-android-ui-components/src/main/res/layout/stream_ui_item_poll_suggest_option.xml
  • stream-chat-android-ui-components/src/main/res/layout/stream_ui_item_poll_view_comments.xml
  • stream-chat-android-ui-components/src/main/res/values/attrs_poll_view.xml
  • stream-chat-android-ui-components/src/main/res/values/strings.xml
  • stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/viewmodels/messages/MessageListViewModelTest.kt
  • stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/viewmodels/messages/PollCommentsViewModelTest.kt

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
75.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@gpunto gpunto enabled auto-merge (squash) May 27, 2026 15:53
@gpunto gpunto merged commit 7203869 into develop May 27, 2026
15 of 16 checks passed
@gpunto gpunto deleted the v7-xml-poll-port branch May 27, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:new-feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants