Skip to content

Apply UI fixes to the poll message and screens#6254

Open
gpunto wants to merge 14 commits intov7from
redesign/polls-fixes
Open

Apply UI fixes to the poll message and screens#6254
gpunto wants to merge 14 commits intov7from
redesign/polls-fixes

Conversation

@gpunto
Copy link
Contributor

@gpunto gpunto commented Mar 16, 2026

Goal

Apply UI fixes to the poll message and screens

  • Update poll creation button
  • Update poll subtitle text when there is no max to votes
  • Add placeholder to the "add comment" button
  • Show confirmation dialog and snackbar when ending polls
  • Use small size for poll option buttons
  • Fix excessive padding in poll results

Implementation

Describe the implementation

🎨 UI Changes

Please check the updated snapshots

Testing

Can be checked in hte sample

Summary by CodeRabbit

  • New Features

    • End poll confirmation dialog to prevent accidental closures
    • Snackbar notification displays when a poll ends
    • Improved input field with placeholder for adding poll answers
  • Improvements

    • Optimized spacing and sizing in poll result display
    • Refined poll creation header button styling
    • Enhanced handling of unlimited answer selections
    • Updated poll-related UI text and labels

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

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

Comment on lines +244 to +249
snackbarScope.launch {
snackbarHostState.showSnackbar(
message = pollEndedMessage,
duration = SnackbarDuration.Short,
)
}
Copy link
Contributor Author

@gpunto gpunto Mar 16, 2026

Choose a reason for hiding this comment

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

Here we're showing the snackbar as soon as we fire the action, but it could fail. The alternative would be to update the closePoll function to accept something like an onSuccess lambda. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if if would make sense to handle the success case similar to the error cases: ErrorEvent defined in the MessageListController. Basically to emit success/error events for this operation as well, and then collect and react to them in the UI.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea! I've added a new flow for generic events (so it can contain both successes and failures), but I also left the error flow there for compatibility. Let me know if you think this is overkill and we should just remove it

Copy link
Contributor

Choose a reason for hiding this comment

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

From my point of view looks pretty good!

@andremion maybe you can also take a look!

@gpunto
Copy link
Contributor Author

gpunto commented Mar 16, 2026

@coderabbitai review

@github-actions
Copy link
Contributor

github-actions bot commented Mar 16, 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.41 MB 🟡
stream-chat-android-compose 12.81 MB 12.06 MB -0.75 MB 🚀

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

coderabbitai bot commented Mar 16, 2026

Walkthrough

This PR enhances poll functionality by introducing an end-poll confirmation dialog, extracting the add-answer input into a dedicated component, and improving spacing with modifiers. It updates snackbar integration in MessagesScreen to notify users when polls close, refines button styling in poll creation, and expands string resources for unlimited answer descriptions. Additionally, it updates generated ComposableSingletons lambda fields due to Compose compiler regeneration.

Changes

Cohort / File(s) Summary
Generated ComposableSingletons API
api/stream-chat-android-compose.api
Extensive lambda field and getter signature updates across multiple ComposableSingletons classes (PollMessageContent, PollAnswers, ChannelFiles/MediaAttachments, ChannelInfo variants, ChannelList, MediaGallery, Messages, Attachments, etc.), reflecting Compose compiler regeneration with lambda arity shifts between Function2/Function3 and reindexed public getLambdaN$... accessors. No behavioral logic changes.
Poll UI Components
src/main/.../poll/PollMessageContent.kt, src/main/.../poll/PollAnswers.kt, src/main/.../poll/PollViewResultDialog.kt, src/main/.../poll/PollCreationHeader.kt
PollMessageContent introduces EndPollConfirmationDialog and showEndPollDialog state; PollAnswers extracts AddAnswerDialogInput as a new private composable; PollViewResultDialog adds Modifier parameter to PollViewResultItem for dynamic top padding and adjusts spacer heights; PollCreationHeader replaces IconButton with StreamButton for improved styling consistency.
Poll Integration & Snackbar
src/main/.../messages/MessagesScreen.kt
Adds snackbarHostState, snackbarScope, and onClosePoll callback to display confirmation snackbar when polls close. Integrates StreamSnackbarHost into Scaffold and wires poll-close action to trigger snackbar message via coroutine scope.
String Resources
src/main/res/values/strings.xml, stream-chat-android-ui-common/src/main/res/values/strings.xml
Added/updated strings for end poll confirmation (title, message, action), poll ended snackbar message, and unlimited poll answers description ("Select one or more").
Poll Utility Extension
stream-chat-android-ui-common/.../extensions/Poll.kt
Modified maxVotes calculation to remain nullable instead of defaulting to options.size, allowing explicit handling of unlimited answers via null case in when expression.

Sequence Diagram

sequenceDiagram
    actor User
    participant PollMessageContent
    participant EndPollConfirmationDialog
    participant MessagesScreen
    participant ListViewModel
    participant SnackbarHost

    User->>PollMessageContent: Clicks end poll option
    PollMessageContent->>PollMessageContent: Set showEndPollDialog = true
    PollMessageContent->>EndPollConfirmationDialog: Display dialog
    User->>EndPollConfirmationDialog: Confirms poll closure
    EndPollConfirmationDialog->>MessagesScreen: Invoke onClosePoll(pollId)
    MessagesScreen->>ListViewModel: closePoll(pollId)
    ListViewModel->>ListViewModel: Process poll closure
    MessagesScreen->>SnackbarHost: Show "Poll ended" message
    SnackbarHost->>User: Display snackbar notification
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • VelikovPetar

Poem

🐰 Polls now close with grace and care,
A dialog asks, "Are you sure there?"
Snackbars celebrate the end with cheer,
While endless answers appear clear,
Compose recompiles without fear!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description includes a clear Goal section listing specific UI fixes, but the Implementation section is left blank and UI Changes section lacks before/after images or videos as required by the template. Complete the Implementation section with technical details of how changes were made, and add before/after screenshots or videos to the UI Changes section as specified in the template.
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 (1 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'Apply UI fixes to the poll message and screens' accurately summarizes the main changes, which involve multiple UI improvements across poll-related components.

✏️ 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/polls-fixes
📝 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.

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.

♻️ Duplicate comments (1)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/MessagesScreen.kt (1)

240-251: ⚠️ Potential issue | 🟡 Minor

Snackbar displays before confirming poll closure success.

The snackbar is shown immediately after calling closePoll(), regardless of whether the operation succeeds. If the poll closure fails, users will see a misleading "Poll ended" message. Consider adding an onSuccess callback to closePoll to show the snackbar only on successful completion.

🤖 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/messages/MessagesScreen.kt`
around lines 240 - 251, The onClosePoll lambda currently calls
listViewModel.closePoll(pollId) then immediately shows the snackbar via
snackbarScope.launch and snackbarHostState.showSnackbar with pollEndedMessage;
change this so the snackbar is only shown after closePoll reports success —
either by using a provided onSuccess callback on listViewModel.closePoll (or
updating closePoll to accept one) or by awaiting/collecting the result (e.g., a
suspend function / Result/Flow) and only launching snackbarScope to show
pollEndedMessage when the operation succeeds; also handle and surface failures
(e.g., show an error snackbar) instead of unconditionally showing
pollEndedMessage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/MessagesScreen.kt`:
- Around line 240-251: The onClosePoll lambda currently calls
listViewModel.closePoll(pollId) then immediately shows the snackbar via
snackbarScope.launch and snackbarHostState.showSnackbar with pollEndedMessage;
change this so the snackbar is only shown after closePoll reports success —
either by using a provided onSuccess callback on listViewModel.closePoll (or
updating closePoll to accept one) or by awaiting/collecting the result (e.g., a
suspend function / Result/Flow) and only launching snackbarScope to show
pollEndedMessage when the operation succeeds; also handle and surface failures
(e.g., show an error snackbar) instead of unconditionally showing
pollEndedMessage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8c4b8e08-b5de-4264-ab3e-4ed72b5084de

📥 Commits

Reviewing files that changed from the base of the PR and between fc8918f and 0e35fd9.

⛔ Files ignored due to path filters (9)
  • 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_PollViewResultDialogTest_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.poll_PollViewResultDialogTest_light_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.attachments.poll_CreatePollScreenTest_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.attachments.poll_CreatePollScreenTest_light_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.attachments.poll_PollCreationHeaderTest_disabled.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.attachments.poll_PollCreationHeaderTest_enabled.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
📒 Files selected for processing (9)
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • 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/PollViewResultDialog.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/MessagesScreen.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/attachments/poll/PollCreationHeader.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/extensions/Poll.kt
  • stream-chat-android-ui-common/src/main/res/values/strings.xml

@gpunto gpunto force-pushed the redesign/polls-fixes branch from 0e35fd9 to 4df8cad Compare March 17, 2026 09:56
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

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

See analysis details on SonarQube Cloud

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.

2 participants