-
Notifications
You must be signed in to change notification settings - Fork 302
Fixed an issue where a poll would not update if its a thread root #5968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Fixed an issue where a poll would not update if its a thread root #5968
Conversation
SDK Size Comparison 📏
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds messageId to poll-related events and wires poll event handling into thread logic so polls update live when the poll is on the thread parent message.
- Introduce messageId on HasPoll events and propagate through DTOs, mappings, and public API.
- Add ThreadMutableState helpers and ThreadLogic.handlePollEvents to update the parent message’s poll.
- Route HasPoll events to the appropriate active thread via EventHandlerSequential.
Reviewed Changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/channel/thread/internal/ThreadLogicTest.kt | Adds comprehensive tests covering poll event handling in threads. |
stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/state/channel/thread/internal/ThreadMutableState.kt | Adds parentMessage getter and updateParentMessagePoll(poll) to modify the thread parent’s poll. |
stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/channel/thread/internal/ThreadLogic.kt | Implements handlePollEvents to process HasPoll events and update parent poll. |
stream-chat-android-state/src/main/java/io/getstream/chat/android/state/event/handler/internal/EventHandlerSequential.kt | Groups HasPoll events by messageId and dispatches to active thread logic. |
stream-chat-android-client/src/test/java/io/getstream/chat/android/client/extensions/internal/PollExtensionsTests.kt | Updates tests to include messageId in poll events. |
stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/EventMappingTestArguments.kt | Extends mapping test args with messageId for poll events. |
stream-chat-android-client/src/main/java/io/getstream/chat/android/client/events/ChatEvent.kt | Adds messageId to HasPoll and poll event data classes. |
stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/EventDtos.kt | Adds message_id to poll-related DTOs. |
stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/EventMapping.kt | Maps message_id from DTOs to messageId in domain events. |
stream-chat-android-client/api/stream-chat-android-client.api | Updates public API signatures to include messageId. |
stream-chat-android-client-test/src/main/java/io/getstream/chat/android/client/test/Mother.kt | Adds test helpers to generate poll events with messageId. |
CHANGELOG.md | Notes the bug fix for polls in thread parent messages. |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
internal fun handlePollEvents(currentUserId: String?, events: List<HasPoll>) { | ||
// Don't handle poll events if there is no poll in the parent message (should never happen) | ||
val parentMessage = mutableState.parentMessage ?: return | ||
val poll = parentMessage.poll ?: return | ||
// Don't handle poll events if the poll in the parent message is different (should never happen) | ||
events | ||
.filter { it.poll.id == poll.id } | ||
.forEach { event -> | ||
val processedPoll = when (event) { | ||
is AnswerCastedEvent -> event.processPoll { poll } | ||
is PollClosedEvent -> event.processPoll { poll } | ||
is PollUpdatedEvent -> event.processPoll { poll } | ||
is VoteRemovedEvent -> event.processPoll { poll } | ||
is VoteCastedEvent -> event.processPoll(currentUserId) { poll } | ||
is VoteChangedEvent -> event.processPoll(currentUserId) { poll } | ||
is PollDeletedEvent -> null // poll is deleted, remove from state | ||
} | ||
mutableState.updateParentMessagePoll(processedPoll) | ||
} | ||
} |
Copilot
AI
Oct 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Events in a batch are processed against a stale poll snapshot captured before the loop. If multiple events for the same poll arrive in order (e.g., vote casted then vote changed), the second event won't apply on top of the updated state. Read the latest parentMessage.poll for each event (or update the local base after each iteration) to ensure sequential updates are applied cumulatively.
Copilot uses AI. Check for mistakes.
messageId?.let { | ||
logicRegistry.thread(it).handlePollEvents(currentUserId, events) | ||
} |
Copilot
AI
Oct 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Minor: messageId is already filtered to non-null keys, but still treated as nullable in the forEach. You can avoid the double null-check by unwrapping once (e.g., requireNotNull or a non-null filter) and pass it directly for clearer intent.
messageId?.let { | |
logicRegistry.thread(it).handlePollEvents(currentUserId, events) | |
} | |
logicRegistry.thread(messageId).handlePollEvents(currentUserId, events) |
Copilot uses AI. Check for mistakes.
🎯 Goal
Fixes the case where polls are not updated live when they are the root message of a thread.
Adds
HasPoll
event handling to theThreadLogic
.🛠 Implementation details
messageId
property on theHasPoll
events - used to identify the thread in which the poll livesHasPoll
event in theThreadLogic
- updating the thread parent message state🎨 UI Changes
thread.polls.before.mov
thread.polls.after.mov
🧪 Testing