Skip to content

Update design of poll options and comments screens#6246

Open
gpunto wants to merge 5 commits intov7from
redesign/poll-options-n-comments
Open

Update design of poll options and comments screens#6246
gpunto wants to merge 5 commits intov7from
redesign/poll-options-n-comments

Conversation

@gpunto
Copy link
Contributor

@gpunto gpunto commented Mar 13, 2026

Goal

Update design of poll options and comments screens

Implementation

  • Removed showBorder from AvatarStack -> checked with Jurgen that this is not something we use by default
  • Update design of the two screens

🎨 UI Changes

Add relevant screenshots

Before After
Screenshot_20260313_093029 Screenshot_20260313_092629
Screenshot_20260313_093019 Screenshot_20260313_092652

Testing

You can check the options screen in polls that have more than 5 options & the comments screen in polls that have comments enabled.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added edit functionality to poll answers within the poll dialog.
    • Enhanced poll results visualization with vote counts and progress indicators per option.
  • Improvements

    • Redesigned poll dialog with improved scrollable layout.
    • Removed avatar borders from message threads, typing indicators, and poll components for a cleaner appearance.
    • Reduced maximum visible poll options from 10 to 5.
    • Updated answer editing label text.

@gpunto gpunto added the pr:improvement Improvement label Mar 13, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 13, 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.

🎉 Great job! This PR is ready for review.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 13, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.25 MB 5.70 MB 0.45 MB 🟡
stream-chat-android-ui-components 10.60 MB 11.00 MB 0.40 MB 🟡
stream-chat-android-compose 12.81 MB 12.03 MB -0.78 MB 🚀

@gpunto gpunto force-pushed the redesign/poll-options-n-comments branch from e8b2099 to 32e699c Compare March 13, 2026 10:21
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

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

See analysis details on SonarQube Cloud

@gpunto gpunto marked this pull request as ready for review March 13, 2026 13:07
@gpunto gpunto requested a review from a team as a code owner March 13, 2026 13:07
@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Walkthrough

This pull request refactors poll UI composables by removing the showBorder parameter from UserAvatarStack, switching poll dialogs from LazyColumn to scrollable Column layouts, adding an optional trailingContent parameter to PollDialogHeader, renaming PollResultSection to PollSection, and reducing the maximum visible poll options from 10 to 5. Function2 lambda types replace Function3 in compiled API signatures.

Changes

Cohort / File(s) Summary
Poll Dialog Infrastructure
stream-chat-android-compose/api/stream-chat-android-compose.api
Public API signatures updated with Function2 lambda parameters replacing Function3; new Function2-typed lambda fields added to ComposableSingletons classes for PollAnswers, PollDialogHeader, and PollMoreOptionsDialog.
Poll Composables - Major Refactoring
src/.../poll/PollAnswers.kt, src/.../poll/PollMoreOptionsDialog.kt
Switched from LazyColumn-based layouts to scrollable Column; introduced new Content composables with conditional header rendering and edit functionality; added showUpdateButton parameter and onUpdateClick callback to PollAnswersItem; added avatar stacks and animated vote-count progress bars in PollMoreOptionsDialog.
Poll Dialog Header & Result Layout
src/.../poll/PollDialogHeader.kt, src/.../poll/PollViewResultDialog.kt
Added optional trailingContent parameter to PollDialogHeader for composable trailing content; renamed PollResultSection to PollSection and made it internal for reuse across poll components.
Avatar Border Removal
src/.../avatar/AvatarStack.kt, src/.../messages/MessageThreadFooter.kt, src/.../messages/PollMessageContent.kt, src/.../messages/list/MessageItem.kt, src/.../threads/ThreadItem.kt
Removed showBorder parameter from UserAvatarStack public function and eliminated all showBorder=true arguments across five call sites; borders no longer render for avatars in message threads, typing indicators, poll messages, and thread participants.
Poll Configuration & Localization
stream-chat-android-ui-common/.../PollsConstants.kt, stream-chat-android-compose/src/main/res/values/strings.xml
Reduced MAX_NUMBER_OF_VISIBLE_OPTIONS constant from 10 to 5; updated edit-answer string resource text from "Update Comment" to "Update Your Comment".

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • VelikovPetar

Poem

🐰 Polls now scroll with graceful ease,
Avatars border-free and pleased,
Headers trail with composable cheer,
Five options show what matters here!
Comments updated, structure refined,
Poll dialogs reborn, redesigned!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update design of poll options and comments screens' clearly and concisely summarizes the main change in the changeset, which focuses on redesigning poll-related UI components.
Description check ✅ Passed The pull request description includes all major template sections: Goal, Implementation, UI Changes with before/after screenshots, and Testing instructions. Minor sections like Testing details are adequately covered.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch redesign/poll-options-n-comments
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.

Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present.

Copy link

@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: 1

🧹 Nitpick comments (2)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollDialogHeader.kt (1)

37-64: Add KDoc for the new trailingContent parameter.

The public function now has a new parameter that should be documented for API consumers.

📝 Proposed KDoc addition
+/**
+ * A header for poll dialogs with a back button and title.
+ *
+ * `@param` title The title text to display.
+ * `@param` onBackPressed Handler invoked when the back button is pressed.
+ * `@param` trailingContent Optional composable content rendered at the end of the header row.
+ */
 `@Composable`
 public fun PollDialogHeader(
     title: String,
     onBackPressed: () -> Unit,
     trailingContent: `@Composable` () -> Unit = {},
 ) {

As per coding guidelines: "Document public APIs with KDoc, including thread expectations and state notes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollDialogHeader.kt`
around lines 37 - 64, Add KDoc to the public PollDialogHeader composable to
document the new trailingContent parameter: describe that trailingContent is a
slot for optional composable content shown at the end of the header, note any
threading expectations (called from Compose UI/main thread) and state
considerations (avoid holding long-lived state here; prefer hoisted state passed
in), and briefly document other params (title, onBackPressed) if missing;
reference the PollDialogHeader function and the trailingContent parameter so API
consumers can find it.
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollMoreOptionsDialog.kt (1)

247-335: Consider extracting the progress bar and avatar row into a separate composable to reduce cognitive complexity.

SonarCloud flags cognitive complexity of 18 (allowed: 15). While the current implementation is readable, extracting the row content (lines 286-311) into a helper composable like PollOptionInfoRow could improve maintainability.

♻️ Proposed extraction
`@Composable`
private fun PollOptionInfoRow(
    option: Option,
    users: List<User>,
    voteCount: Int,
    showAvatars: Boolean,
) {
    Row(Modifier.heightIn(min = AvatarSize.ExtraSmall)) {
        Text(
            modifier = Modifier.weight(1f),
            text = option.text,
            style = ChatTheme.typography.captionDefault,
            color = ChatTheme.colors.chatTextIncoming,
            maxLines = 2,
            overflow = TextOverflow.Ellipsis,
        )

        if (users.isNotEmpty() && showAvatars) {
            UserAvatarStack(
                overlap = StreamTokens.spacingXs,
                users = users.take(MaxStackedAvatars),
                avatarSize = AvatarSize.ExtraSmall,
                modifier = Modifier.padding(start = StreamTokens.spacingXs, end = StreamTokens.spacing2xs),
            )
        }

        Text(
            modifier = Modifier.align(Alignment.CenterVertically),
            text = voteCount.toString(),
            style = ChatTheme.typography.metadataDefault,
            color = ChatTheme.colors.chatTextIncoming,
        )
    }
}

Then use it in PollMoreOptionItem:

PollOptionInfoRow(
    option = option,
    users = users,
    voteCount = voteCount,
    showAvatars = poll.votingVisibility != VotingVisibility.ANONYMOUS,
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollMoreOptionsDialog.kt`
around lines 247 - 335, Extract the inner Row (the option text, optional avatar
stack, and vote count) from PollMoreOptionItem into a new `@Composable` named
PollOptionInfoRow(option: Option, users: List<User>, voteCount: Int,
showAvatars: Boolean) and replace the original Row invocation with
PollOptionInfoRow(...), passing showAvatars = poll.votingVisibility !=
VotingVisibility.ANONYMOUS and users.take(MaxStackedAvatars) behavior preserved
inside the new composable; leave the animateFloatAsState progress calculation
and the LinearProgressIndicator in PollMoreOptionItem unchanged, and ensure the
new PollOptionInfoRow uses the same typography/colors and alignment as the
extracted code (Text, UserAvatarStack, and trailing vote count) so behavior and
visuals remain identical.
🤖 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-compose/api/stream-chat-android-compose.api`:
- Line 1908: Add a changelog entry documenting the PollDialogHeader signature
change: note that PollDialogHeader now accepts an additional public slot
parameter (update the function signature shown), mark it under the v7 breaking
changes section, briefly describe the impact for SDK consumers and provide the
updated function signature so callers can migrate; reference the
PollDialogHeader composable name in the entry so it’s discoverable.

---

Nitpick comments:
In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollDialogHeader.kt`:
- Around line 37-64: Add KDoc to the public PollDialogHeader composable to
document the new trailingContent parameter: describe that trailingContent is a
slot for optional composable content shown at the end of the header, note any
threading expectations (called from Compose UI/main thread) and state
considerations (avoid holding long-lived state here; prefer hoisted state passed
in), and briefly document other params (title, onBackPressed) if missing;
reference the PollDialogHeader function and the trailingContent parameter so API
consumers can find it.

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollMoreOptionsDialog.kt`:
- Around line 247-335: Extract the inner Row (the option text, optional avatar
stack, and vote count) from PollMoreOptionItem into a new `@Composable` named
PollOptionInfoRow(option: Option, users: List<User>, voteCount: Int,
showAvatars: Boolean) and replace the original Row invocation with
PollOptionInfoRow(...), passing showAvatars = poll.votingVisibility !=
VotingVisibility.ANONYMOUS and users.take(MaxStackedAvatars) behavior preserved
inside the new composable; leave the animateFloatAsState progress calculation
and the LinearProgressIndicator in PollMoreOptionItem unchanged, and ensure the
new PollOptionInfoRow uses the same typography/colors and alignment as the
extracted code (Text, UserAvatarStack, and trailing vote count) so behavior and
visuals remain identical.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d73c485b-de5e-4591-9c9f-c4d4c284b9eb

📥 Commits

Reviewing files that changed from the base of the PR and between 6141c30 and 32e699c.

⛔ Files ignored due to path filters (13)
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.messages_MessageFooterTest_thread_start_with_footer.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.messages_MessageFooterTest_thread_start_with_no_replies.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.messages_MessageFooterTest_thread_start_with_replies.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.messages_PollMessageContentTest_poll_content.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.poll_PollMoreOptionsDialogTest_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.poll_PollMoreOptionsDialogTest_light_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.list_TypingIndicatorContentTest_multiple_users_typing.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages_MessageListTest_loaded_messages.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages_MessageListTest_loaded_messages_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadItemTest_threadItem.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loaded_threads.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loaded_threads_with_unread_banner.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loading_more_threads.png is excluded by !**/*.png
📒 Files selected for processing (12)
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/avatar/AvatarStack.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageThreadFooter.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/PollMessageContent.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/components/poll/PollDialogHeader.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollMoreOptionsDialog.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/poll/PollViewResultDialog.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/threads/ThreadItem.kt
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/utils/PollsConstants.kt
💤 Files with no reviewable changes (3)
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageThreadFooter.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/threads/ThreadItem.kt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:improvement Improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant