Skip to content

fix: tapping buttons in composite messages (e.g. polls) - WPB-19793#3696

Merged
caldrian merged 12 commits intodevelopfrom
fix/polls-proteus-WPB-19765
Oct 9, 2025
Merged

fix: tapping buttons in composite messages (e.g. polls) - WPB-19793#3696
caldrian merged 12 commits intodevelopfrom
fix/polls-proteus-WPB-19765

Conversation

@caldrian
Copy link
Copy Markdown
Contributor

@caldrian caldrian commented Oct 7, 2025

BugWPB-19793 [iOS] Selecting option in poll option doesn't work

Issue

A performance improvement #2921 earlier this year broke composite messages.
Some dangling Core Data objects from a temporary background context remain in the view/model hierarchy.
So when a button of a composite message is tapped, it cannot be handled properly.

This PR adds a workaround which forces the recreation of conversation message views if the message is a composite message.

Testing

Create a poll in a Proteus conversation and try to vote.


Checklist

  • Title contains a reference JIRA issue number like [WPB-XXX].
  • Description is filled and free of optional paragraphs.
  • Adds/updates automated tests.

UI accessibility checklist

If your PR includes UI changes, please utilize this checklist:

  • Make sure you use the API for UI elements that support large fonts.
  • All colors are taken from WireDesign.ColorTheme or constructed using WireDesign.BaseColorPalette.
  • New UI elements have Accessibility strings for VoiceOver.

Comment on lines -119 to +129
guard let moc = parentMessage.managedObjectContext,
let buttonId = button?.id,
let messageId = parentMessage.nonce,
!hasSelectedButton else { return }
guard let context = parentMessage.managedObjectContext else { return }

context.performGroupedBlock { [weak self] in
guard let self, let messageId = parentMessage.nonce, let buttonId = button?.id, !hasSelectedButton else { return }

moc.performGroupedBlock { [weak self] in
guard let self else { return }
let buttonState = buttonState ??
ButtonState.insert(with: buttonId, message: parentMessage, inContext: moc)
ButtonState.insert(with: buttonId, message: parentMessage, inContext: context)
parentMessage.buttonStates?.resetExpired()
guard parentMessage.isSenderInConversation else {
buttonState.isExpired = true
moc.saveOrRollback()
context.saveOrRollback()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Two things done here:

  1. rename moc to context
  2. move accessing nonce into the context.perform closure, so that it works with any context

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

question: was it a background context before that had no parent? or just no automaticallySaveToParent?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, some views or models belonging to views have core data entities set which have been fetched on a background context.

Comment thread wire-ios/Wire-iOS/Wire-Info.plist
@caldrian caldrian marked this pull request as ready for review October 7, 2025 09:18
@caldrian caldrian changed the title fix: tapping buttons in composite messages (e.g. polls) - WPB-19765 fix: tapping buttons in composite messages (e.g. polls) - WPB-19765x Oct 7, 2025
@caldrian caldrian changed the title fix: tapping buttons in composite messages (e.g. polls) - WPB-19765x fix: tapping buttons in composite messages (e.g. polls) - WPB-19765 Oct 7, 2025
@caldrian caldrian enabled auto-merge October 7, 2025 09:32
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Oct 7, 2025

Test Results

4 265 tests   4 238 ✅  6m 16s ⏱️
  544 suites     27 💤
    2 files        0 ❌

Results for commit 2911e30.

♻️ This comment has been updated with latest results.

@caldrian caldrian changed the title fix: tapping buttons in composite messages (e.g. polls) - WPB-19765 fix: tapping buttons in composite messages (e.g. polls) - WPB-19793 Oct 7, 2025
@caldrian caldrian requested review from a team, David-Henner, Copilot and netbe and removed request for a team October 7, 2025 10:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes an issue where tapping buttons in composite messages (like polls) wasn't working due to dangling Core Data objects from a background context remaining in the view hierarchy after a performance improvement.

  • Adds a workaround to force recreation of conversation message views for composite messages
  • Ensures composite messages use the correct Core Data context by checking isComposite property
  • Updates dependency versions and reorganizes plist configuration

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
ConversationTableViewDataSource.swift Implements the main fix by forcing cell description recreation for composite messages
CompositeMessageItemContent.swift Improves code style with final class modifier and simplifies variable naming
Wire-Info.plist Reorganizes configuration keys (moves OpenLinksExternally and adds UIDesignRequiresCompatibility)
Package.resolved Updates swift-argument-parser dependency from 1.5.0 to 1.6.1

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

caldrian and others added 2 commits October 7, 2025 12:24
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Collaborator

@netbe netbe left a comment

Choose a reason for hiding this comment

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

Fix looks good, I left some comments please have a look.

Comment thread wire-ios/Wire-iOS/Wire-Info.plist
Comment on lines -119 to +129
guard let moc = parentMessage.managedObjectContext,
let buttonId = button?.id,
let messageId = parentMessage.nonce,
!hasSelectedButton else { return }
guard let context = parentMessage.managedObjectContext else { return }

context.performGroupedBlock { [weak self] in
guard let self, let messageId = parentMessage.nonce, let buttonId = button?.id, !hasSelectedButton else { return }

moc.performGroupedBlock { [weak self] in
guard let self else { return }
let buttonState = buttonState ??
ButtonState.insert(with: buttonId, message: parentMessage, inContext: moc)
ButtonState.insert(with: buttonId, message: parentMessage, inContext: context)
parentMessage.buttonStates?.resetExpired()
guard parentMessage.isSenderInConversation else {
buttonState.isExpired = true
moc.saveOrRollback()
context.saveOrRollback()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

question: was it a background context before that had no parent? or just no automaticallySaveToParent?

@caldrian caldrian requested a review from jullianm October 9, 2025 11:05
@caldrian caldrian added this pull request to the merge queue Oct 9, 2025
Merged via the queue into develop with commit 4dcae24 Oct 9, 2025
10 checks passed
@caldrian caldrian deleted the fix/polls-proteus-WPB-19765 branch October 9, 2025 13:53
caldrian added a commit that referenced this pull request Oct 15, 2025
…3696)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants