ReviewOS

also looking at this

craft-native/craft

fix(mobile): preserve native editing, navigation, and durable media requests

#369
Merged chris wants to merge codex/native-vertical-scroll-tab-swipes into main
36 files +864 -185

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

packages/ios/fixtures/native-navigation/NativeNavigationUnitTests.swiftmodified+19-0
Changes to packages/ios/fixtures/native-navigation/NativeNavigationUnitTests.swift
@@ -165,6 +165,25 @@ final class NativeNavigationUnitTests: XCTestCase {
165165 CraftChrome.shared.selected = "/"
166166 }
167167
168 func testVerticalNativeScrollDoesNotPreventTheHorizontalTabGesture() throws {
169 _ = shell.tabTapped("/details", reselect: false)
170 let details = try XCTUnwrap(stack("/details"))
171 details.view.layoutIfNeeded()
172 func scroll(in view: UIView) -> UIScrollView? {
173 if view.accessibilityIdentifier == "people-list" { return view as? UIScrollView }
174 return view.subviews.lazy.compactMap { scroll(in: $0) }.first
175 }
176 let people = try XCTUnwrap(scroll(in: details.view))
177 let tabPan = try XCTUnwrap(shell.view.gestureRecognizers?.compactMap { $0 as? UIPanGestureRecognizer }.first)
178 XCTAssertFalse(people.alwaysBounceHorizontal)
179 XCTAssertLessThanOrEqual(people.contentSize.width, people.bounds.width + 1)
180 XCTAssertTrue(shell.gestureRecognizer(tabPan, shouldRecognizeSimultaneouslyWith: people.panGestureRecognizer),
181 "the vertical list's pan must not win the horizontal tab gesture")
182 people.alwaysBounceHorizontal = true
183 XCTAssertFalse(shell.gestureRecognizer(tabPan, shouldRecognizeSimultaneouslyWith: people.panGestureRecognizer),
184 "a horizontal scroller must keep its own gesture")
185 }
186
168187 func testNativeLinkRetainsItsTapRecognizerAcrossUnrelatedUpdates() throws {
169188 let controller = CraftNativeScreenController(config: CraftConfig())
170189 controller.loadViewIfNeeded()