Skip to content

Fix BatchRemovingTransitionContext completion being called multiple times#191

Draft
muukii wants to merge 4 commits intomainfrom
fix/batch-removing-completion-called-once
Draft

Fix BatchRemovingTransitionContext completion being called multiple times#191
muukii wants to merge 4 commits intomainfrom
fix/batch-removing-completion-called-once

Conversation

@muukii
Copy link
Copy Markdown
Collaborator

@muukii muukii commented Apr 9, 2026

Summary

  • Fix BatchRemovingTransitionContext completion callbacks firing multiple times when multiple StackingPlatterViews share the same context
  • Add hasNotifiedCompletion flag to ensure callbacks fire exactly once (via invalidate(), transitionSucceeded(), or notifyCompleted())
  • Add isInvalidated guard in onCompleted closure, matching the existing _startRemoving pattern in RemovingTransitionContext

Test plan

  • Added testBatchRemovingCompletionCalledOnce — verifies removeViewController batch path calls completion exactly once
  • Added testRemoveAllViewControllerCompletionCalledOnce — verifies removeAllViewController calls completion exactly once
  • All 23 existing tests pass

🤖 Generated with Claude Code

muukii and others added 4 commits April 9, 2026 22:51
…imes

When multiple StackingPlatterViews shared the same BatchRemovingTransitionContext,
each swapTransitionContext call would invoke invalidate() on the shared context,
causing completion callbacks to fire N times instead of once.

Changes:
- Add hasNotifiedCompletion flag to ensure callbacks fire exactly once
- Add isInvalidated/isCompleted guard to notifyCompleted() (matching RemovingTransitionContext)
- Add isInvalidated guard in onCompleted closure (matching _startRemoving pattern)
- Add tests verifying completion is called exactly once

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove hasNotifiedCompletion flag, use isInvalidated guard instead
- Use XCTestExpectation for async batch transition test (crossDissolve)
- Place stack in UIWindow so animation completes properly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e and transitionSucceeded

Ensures callbacks fire exactly once regardless of which path triggers
first. Both invalidate() and transitionSucceeded() check and set the
flag before firing callbacks, preventing re-entry from either direction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prevent re-entry between invalidate(), transitionSucceeded(), and
notifyCancelled() so callbacks fire exactly once.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@muukii muukii marked this pull request as draft April 9, 2026 17:08
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.

1 participant