Skip to content

feat(mobile): experiment with v5 stacks and native iPad columns - #12646

Draft
juliusmarminge wants to merge 15 commits into
mobile/sdk58-android-foreground-alertsfrom
mobile/rns-v5-migration
Draft

juliusmarminge wants to merge 15 commits into
mobile/sdk58-android-foreground-alertsfrom
mobile/rns-v5-migration

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 19, 2026 •

Copy link
Copy Markdown
Member

Our current iPad workspace simulates columns in React and depends on a large react-native-screens header patch. This draft moves iPhone navigation to v5 stacks and the iPad workspace to native split-column stacks, with Duo in #12648 above it.

It builds on the Expo 58 stack ending at #12052. RNS is pinned to Software Mansion's split-column prototype from #4666, commit b604a9f78f4c4ff2ea7b68d6f0a0efc06821fde5; the published v5 alpha does not contain this split navigator.

  • Keep React Navigation 7's router, static screen definitions, linking, and application callbacks. Render pushes with v5 Stack.Host and Stack.Screen; retain outgoing descriptors until native dismissal completes.
  • Let UIKit own iPad primary, detail, and inspector columns, insets, and sidebar animation. The sidebar inset uses the darker drawer color; the frame and conversation use the lighter screen color. Settings and filters stay at the top, search sits below them, and there is no iPad bottom toolbar.
  • Keep the iPhone's native filter/search/compose bottom toolbar. Translate existing screen options into the neutral v5 header API, including native menu state, search placement, and appearance colors. The old iOS header/search/toolbar implementation is removed; a presentation-only legacy wrapper remains for sheets.
  • Register the real thread-list ScrollView through v5's ScrollViewMarker. Use native column measurements for top clearance. Both FlatList and LegendList keep rows below the header at rest, and Android retains its existing scroll view behavior.
  • Use UIKit's automatic scroll-edge effect on iOS 26 and 27. Port main's native title-geometry compatibility fix into RNS v5's custom title/subtitle wrappers so UIKit recognizes Fabric header content. The effect samples scrolling content beneath the title. The forced bar material and added blur binding are removed. This is a generic RNS custom-header fix, with no application-specific option.
  • Resize markdown during native column layout and give Files loading and terminal Back controls a single owner.

The RNS patch file shrinks from 2,223 to 1,290 lines. Remaining patches cover neutral-header background/shadow, custom-title scroll-edge geometry, search and toolbar bindings, app-owned menu state, empty-column/sidebar animation fixes, packaging, and legacy TypeScript/Android compatibility. Patch-file size includes diff context and excludes the new navigator adapter.

Validation: mobile typecheck passes on both layers; the existing focused navigation/layout suites passed 59 tests here and 69 in the Duo layer. The four scroll-edge helper tests pass after this follow-up. Fresh native builds pass on iPhone, iOS 27.0, and iPad, iOS 26.5, with matching installed fingerprints. The iPhone shows the automatic effect sampling content beneath the custom title, native bottom search filtering to one thread, Cancel clearing the query and dismissing the keyboard, and filters opening without a keyboard. The fresh iPad client retains its native fade, top controls, floating search, and darker sidebar inset with the automatic style. The isolated backend has 43 seeded threads; the iPad capture uses a longer cached fixture while reconnecting. Scrolled screenshots and the scroll-effect recording use the list's existing scroll API through CDP, rather than physical scroll gestures. Search, Cancel, and filter checks use native taps. Targeted lint retains existing HomeScreen warnings; React Doctor reports no errors in changed files and retains its existing complexity warning.

The broader mobile test run previously passed 183 files and failed notification-center-manager.test.ts and permissions-service.test.ts; both failures reproduce on the unchanged Expo base. This is a progress draft: modal wrappers, header option parity/accessibility, interactive dismissal, iPad multitasking, and Android still need verification.

Before — existing iPad workspace on the Expo base:

Before: existing iPad workspace

After — native v5 columns with the corrected sidebar background, top controls, search, and preserved draft:

After: v5 native iPad workspace with the selected conversation and draft

Native Files inspector with the screen background:

Native iPad primary, conversation, and Files inspector columns

Earlier sidebar collapse/expand recording with keyboard and draft retained. This recording invokes the existing sidebar button callback through CDP; UIKit performs the column transition. It is not evidence of a physical touch test.

iOS 27 automatic scroll-edge effect: before and after

Before, the forced bar material hid content beneath the title:

Before: forced navigation-bar material on iOS 27

After, UIKit's automatic effect samples content beneath the custom title:

After: iOS 27 automatic scroll-edge blur beneath the custom title

At rest:

Transparent native header at the top of the thread list

Automatic scroll-edge rendering while the list scrolls. The recording uses the existing list scroll API through CDP.

Native bottom search filtering to one seeded thread

Native filter menu without the keyboard

Fresh iOS 26 iPad client: automatic native sidebar fade

iOS 26 automatic sidebar fade and native top controls

Files loading and terminal Back: before and after

Before: duplicate loading indicators in the Files inspector:

Before: two loading indicators in the Files inspector

After: one loader in the Files inspector:

After: a single Files inspector loader

Before: two terminal Back buttons:

Before: duplicated terminal Back buttons

After: one terminal Back button beside the sidebar control:

After: a single terminal Back button beside the sidebar control

The after captures use a cached disconnected fixture to keep the initial loading state visible. The terminal Back was exercised through a native tap.

Built with GPT-6 in the Codex harness.

@github-actions github-actions Bot added the vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. label Sep 19, 2026
@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. labels Sep 19, 2026
@juliusmarminge
juliusmarminge added this pull request to stack #12649 September 19, 2026 22:56
@github-actions

github-actions Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 13.5 KiB — 15.1 KiB ✅
Codex Thread snapshot wire — 7.1 KiB — 7.3 KiB ✅
Codex Live turn WebSocket wire — 6.5 KiB — 7.8 KiB ✅
Codex Live turn WebSocket decoded — 56.3 KiB — 66.4 KiB ✅
Codex Live turn messages — 10 — 21 ✅
Claude Total thread wire — 13.5 KiB — 15.1 KiB ✅
Claude Thread snapshot wire — 7.1 KiB — 7.3 KiB ✅
Claude Live turn WebSocket wire — 6.4 KiB — 7.8 KiB ✅
Claude Live turn WebSocket decoded — 57.0 KiB — 66.4 KiB ✅
Claude Live turn messages — 9 — 21 ✅

Baseline: unavailable · PR result: bc16e28 · Source CI: failure

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.9 KiB
  • Claude decoded thread snapshot: 114.6 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant