Repository navigation
Conversation
The pager reports the page as soon as it becomes the nearest one mid-swipe, so PHP's round trip overlaps the animation. That is right for a media feed. On a screen whose frame is large, the frame the report causes lands during the animation and the swipe stutters. report-on-settle (reportOnSettle()) makes the pager report only once the scroll comes to rest. iOS keeps tracking the nearest page but only reports from the idle phase. Android reports settledPage instead of currentPage. Both platforms now remember the page PHP last knew about, which includes a page PHP jumped to. Without that, on settle, a swipe back to the page before a jump could go unreported on iOS. Android also reported the start page straight after the pager appeared, which iOS never did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 17, 2026
simonhamp
added a commit
to NativePHP/dev-null-app
that referenced
this pull request
Oct 17, 2026
The tabs above both pagers were drawn in PHP, so they only moved once the pager reported a page and PHP sent a frame. Reporting mid-swipe made that frame land during the animation, which is what made swipes stutter. Reporting only once the swipe settled fixed the stutter but left the tabs about 200ms behind. Both pagers now draw their own tabs (mobile-ui's tabs attribute) and report on settle. The underline follows your finger, the label you're nearest lights up past halfway, and a tap scrolls the pager there, all on the phone. PHP hears once the pager settles. A tap on the tab you're on comes through as a reselect and takes that page back to its top, as before. The tabs keep DESIGN.md's look: Geist SemiBold in ink and ink-muted over a 3px blue underline, with the hairline below. The Notifications filters change slightly. Their font="medium" isn't one of the app's font aliases, so they were drawn in the system font; they now match the Log. They also scroll themselves to keep the filter you're on in view, which the PHP row couldn't do. The error and refresh banners now sit above the tabs, as they do on Profile. mobile-ui is the dev-null app branch at f197a0a, which adds NativePHP/mobile-ui#135, #136 and #131 (the iOS pager now opens on the tab you last had open). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The pager reports its page as soon as the page becomes the nearest one during a swipe. That is on purpose. In a media feed, PHP's round trip overlaps the animation and the next video starts loading early.
On a screen with a big frame it hurts. The dev-null app pages between its Log tabs, and each report makes PHP send a frame of about 1,500 nodes. That frame lands in the middle of the swipe and the swipe stutters. With the mid-swipe report taken out, the same swipes were smooth on an iPhone.
This adds an opt-in:
reportOnSettle()does the same on the element. Without it nothing changes about when pages are reported.settledPageinstead ofcurrentPage.Bookkeeping
Both platforms now keep the page PHP last knew about, and that includes a page PHP jumped to with
page.These two apply with or without the new option. Watch for anything that relied on hearing back about its own jump on iOS, or about the start page on Android.
Tests
PagerTestcovers the prop.PagerReportOnSettleTestchecks the Swift and Kotlin source, the same way the other iOS tests do. They fail onmain.How I tested
A test app from mobile-starter on an iPhone 17 Pro simulator (iOS 27.0) and an Android 15 emulator. The test screen logs every page report and every render with a timestamp, so I could line them up with the touches.
Not tested: a physical device, and a video feed. The default path is the same code as before apart from the bookkeeping above.
The tab strip in #136 (stacked on this one) is the reason this came up. It is separate because this option is useful on its own and is small enough to review in a few minutes.
🤖 Generated with Claude Code