# fix\(mobile\): deliver the first tab selection after Duo folding · PR \#22980 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/22980)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: duo/tab-sync

Target branch: duo/reflow

Head commit: 3f0e6219d0f4d6f3a98911a8f592600cd50a096a

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/22980)

[Commits](https://git.cafe/pingdotgg/t3code/pull/22980/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/22980/diffs?format=markdown)

## Description

---

After a pose change, a Screens mount transaction could clear the pending user-selection flag before UIKit delivered the selection event. Vendor Screens t3.31 with upstream fixes [#4862](https://github.com/software-mansion/react-native-screens/pull/4862) and [#4890](https://github.com/software-mansion/react-native-screens/pull/4890). Extend Reanimated screen recognition to v5 containers so returning to a cleared tab does not delay removing its old detail and crash.

Verified on a clean Duo native client: first tap in both directions after folding, details in both tabs, next-row navigation, cancelled back swipe, and Back to list. Native event logs confirmed JS received the first selection. Mobile typecheck and focused tests passed.

The vendored tarball's source is published as [t3-v5.0.0-t3.31](https://github.com/pingdotgg/react-native-screens/tree/t3-v5.0.0-t3.31) and lands on the fork with [pingdotgg/react-native-screens#3](https://github.com/pingdotgg/react-native-screens/pull/3). This layer contains no search-observer swizzle; that is #23146.

Implemented with Claude Opus 5.5 in Claude Code; integrated and reviewed with GPT-6.1 in Codex.


## Motion verification

Fresh, real-time 30 fps recordings from the exact commits labeled in the videos, using fingerprint-matched debug native clients. Black cards mark cuts between displays.

**Before**

![Before — PR 22979](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/dda3a2634294aeba/pr22979-tabsync-BEFORE-7318f60880c.mp4)

**After**

![After — PR 22979](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f6d01f40cc48079a/pr22979-tabsync-AFTER-ee9cd8c1b4a.mp4)

These recordings demonstrate stale detail removal and the second-tap crash fix. They do not reproduce the approximately 150 ms first-tap race: automated taps landed 1–6 seconds after unfolding, so this video is not proof of that timing fix.

### Unfold-after-sheets assertion

Unfolding after using folded sheets hit a React Native touch-handler double-detach assertion in one of two runs at both `ee9cd8c1b4a` and `fe16f614bef`. Screens t3.35 in #23149 fixes it: the touch handler is attached and detached only when that changes something.

![Unfold-after-sheets assertion, before t3.35](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f5b18439ba0d019a/finding-unfold-after-folded-sheets-crash-ee9cd8c1b4a-fe16f614bef.mp4)

### Restack

Restacked onto main `a12d6ed942` on 2026-10-21. The commits are unchanged apart from lockfile peer strings. The recordings above show the pre-restack commits they name.

