fix(mobile): stop long iOS threads from jumping while scrolling up - #4867
Conversation
Upgrade @legendapp/list 3.2.0 -> 3.3.3 and rebase the transparent-header inset patch onto it. 3.2.0 applied a separate scroll compensation for every history row whose measured size differed from the estimate (judder while scrolling up), and its unfinished scroll-to-end retry loop could yank the viewport back to the bottom seconds after opening a thread. 3.3.3 batches row measurements into one layout pass and fixes the stale end-scroll retries. Only mobile moves; web keeps its own unpatched 3.2.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR updates a third-party library patch to fix iOS scrolling behavior, but an unresolved review comment identifies that You can customize Macroscope's approvability policy. Learn more. |
The itemLayoutAnimation exists to smooth at-rest layout shifts (streaming text, work-log folds), but it also animated repositions that happen while the user scrolls history: MVCP compensation shifts (already offset by an equal contentOffset change, so animating turns an invisible correction into a lurch-and-settle) and container reuse for far-away rows (animating the container's jump from the old row's position sends content flying across the viewport). Gate the transition off during MVCP adjustments, active scrolling, and container reassignment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dismissing prior approval to re-evaluate 7a92d6b
[claude-fable-5] RESPONDING ON BEHALF OF THEOTheo reported jank persisted on this branch (his recording). Root-caused and pushed a second commit (7a92d6b). The remaining jank was not the library scroll math — it was our own
Fix extends the patch: the transition is skipped during MVCP adjustments, active scrolling (via the core's existing Verified in the sim on the same 119-message thread with the same flick pattern: frame-level analysis went from 6 lurch events per pass to 0 after the fix. 📹 after recording |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7a92d6b. Configure here.
* fix(desktop): restore T3 Connect sign-in (pingdotgg#4809) Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * Simplify files panel header (pingdotgg#4828) * build(desktop): reduce installed app size by ~300MB (pingdotgg#4824) * Update model version from claude-opus-4-8 to claude-opus-5 (pingdotgg#4832) * Preserve the thread shell while detail loads (pingdotgg#4830) * Reduce idle work and disk churn with native resource diagnostics (pingdotgg#2679) Co-authored-by: codex <codex@users.noreply.github.com> * fix(server): detect repositories after initialization (pingdotgg#4848) * perf(server): merge separate staged/unstaged numstat calls into single diff HEAD --numstat (pingdotgg#4843) * fix(git): disable external diff for review diff previews (pingdotgg#4854) * Fix editable file focus and live syntax highlighting (pingdotgg#3979) * fix(web): remember the rendered-markdown choice across threads (pingdotgg#4853) Co-authored-by: Simon Doba <simon.doba@orbit.de> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * chore(release): prepare v0.0.31 * fix(mobile): reduce thread feed scroll jank (pingdotgg#4874) * fix(web): restore sidebar v2 thread actions and terminal icon (pingdotgg#4712) * fix(web): settle button now works on hover, not just right-click (pingdotgg#4905) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(clients): disable add project while disconnected (pingdotgg#4834) * fix(composer): hide default Codex service tier (pingdotgg#4784) * docs: link iOS and Android app store downloads (pingdotgg#4902) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(web): align remote server update action (pingdotgg#4731) * fix(connect): suggest a serve command that matches how you ran connect (pingdotgg#4897) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(mobile): stop shared content errors in Personal Team builds (pingdotgg#4943) * perf(mobile): sends respond instantly, thread opens stop freezing (pingdotgg#4882) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(web): show Codex fast mode as a bolt (pingdotgg#4947) * docs: seed worktrees with a copy of real userdata instead of banning it (pingdotgg#4949) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(mobile): support dragged images in the composer (pingdotgg#4953) * fix(mobile): stop long iOS threads from jumping while scrolling up (pingdotgg#4867) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(web): keep worktree default when switching a draft's machine (pingdotgg#4964) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * perf(mobile): reconnect environments immediately on resume (pingdotgg#4878) * feat(web): pasting a huge screenshot now compresses it instead of erroring (pingdotgg#4967) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * feat(web): regenerate thread titles from sidebar (pingdotgg#4810) * fix(web): show server update progress through reconnect (pingdotgg#4903) --------- Co-authored-by: Alex <me@pixp.cc> Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: wukko <me@wukko.me> Co-authored-by: codex <codex@users.noreply.github.com> Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com> Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com> Co-authored-by: ohbentos <72638975+ohbentos@users.noreply.github.com> Co-authored-by: Jake Leventhal <jakeleventhal@me.com> Co-authored-by: Simon Doba <simon.doba@hotmail.de> Co-authored-by: Simon Doba <simon.doba@orbit.de> Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: Gabriel De Andrade <30420087+gabrielelpidio@users.noreply.github.com> Co-authored-by: Jono Kemball <Noojuno@users.noreply.github.com> Co-authored-by: Theo Browne <me@t3.gg> Co-authored-by: Max Katz <me@maxkatz.me>
## What's Changed * fix(mobile): support dragged images in the composer by @t3dotgg in pingdotgg/t3code#4953 * fix(mobile): stop long iOS threads from jumping while scrolling up by @t3dotgg in pingdotgg/t3code#4867 * fix(web): keep worktree default when switching a draft's machine by @t3dotgg in pingdotgg/t3code#4964 * perf(mobile): reconnect environments immediately on resume by @t3dotgg in pingdotgg/t3code#4878 * feat(web): pasting a huge screenshot now compresses it instead of erroring by @t3dotgg in pingdotgg/t3code#4967 * feat(web): regenerate thread titles from sidebar by @t3dotgg in pingdotgg/t3code#4810 * fix(web): show server update progress through reconnect by @t3dotgg in pingdotgg/t3code#4903 * feat(search): find threads by conversation content by @t3dotgg in pingdotgg/t3code#4959 * fix: marketing site Vercel builds no longer die after ~100 deploys by @t3dotgg in pingdotgg/t3code#4975 **Full Changelog**: pingdotgg/t3code@v0.0.32-nightly.20260730.955...v0.0.32-nightly.20260730.956 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.32-nightly.20260730.956
…ng up (pingdotgg#4867)" (#235) This reverts commit 90f3913. Co-authored-by: T3 Code PR Stack <41898282+github-actions[bot]@users.noreply.github.com>
Refresh against the approved codex-turn-mapping tip. CTM's LegendList 3.3.3 patch threads contentInsetStartAdjustment through the list's own scroll math, and pingdotgg#4867/pingdotgg#4874 carry the gated feed-item layout transition, so this merge keeps CTM's versions of both. The keyboard-side wiring is not upstream: the 3.3.3 patch never passes contentInsetStartCompensation into KeyboardChatScrollView, whose clamp floor defaults to 0, so the pingdotgg#4036 wiring is re-ported onto the 3.3.3 patch. The pingdotgg#4036-unique short-content underflow correction, Markdown rendering, and thread-detail changes are retained.

Scrolling up through a long thread on iOS was jumpy to the point of feeling broken: content juddered as you dragged through history, and the list could yank you back to the bottom seconds after opening a thread.
Both problems live in @legendapp/list 3.2.0's handling of estimated vs. measured row sizes. Our rows are estimated at 180px but really measure anywhere from 49px (turn folds) to 4000px+ (long markdown messages), so:
Fix: upgrade mobile to @legendapp/list 3.3.3, which batches row measurements into a single layout pass and fixes the stale end-scroll retries, and rebase our transparent-header inset patch onto it. 19 of 20 hunks applied cleanly; the one reject (
onScrollBeginDragforwarding) exists natively in 3.3.3, so only thedidUserDragflag was folded into its handler. Web keeps its own unpatched 3.2.0.Verified in the iOS simulator against a clone of real thread data (119-message thread): scroll offset traces went from ±7,600px mid-drag reversals to zero discontinuities, and the judder is gone. Mobile thread tests pass; mobile and web typecheck clean.
Change authored by Claude Fable 5 via Claude Code.
🤖 Generated with Claude Code
Note
Medium Risk
Touches core list scrolling, initial positioning, and MVCP compensation in a patched dependency used for thread UI; regressions could affect scroll position, keyboard insets, and header blur on iOS, though scope is mobile-only and web keeps 3.2.0.
Overview
Upgrades mobile
@legendapp/listfrom 3.2.0 to 3.3.3 and retargets the pnpm patch topatches/@legendapp__list@3.3.3.patch, addressing iOS thread scroll judder and late snap-to-bottom on long, variably-sized message rows.The rebased patch layers app-specific behavior on 3.3.3:
contentInsetStartAdjustmentfor transparent-header / automatic UIKit insets, keyboardKeyboardAwareLegendListinset compensation props,contentInsetEndAdjustmenton native (not web-only), an inset-end settle watchdog that holds first paint until scroll-to-end stabilizes, safer maintain-at-end when tail sizes are unknown, and Reanimated layout transitions gated off during MVCP adjustments and active scrolling.onScrollBeginDragnow setsdidUserDragfor the watchdog. Lockfile/workspace still wire web to unpatched 3.2.0 while mobile uses patched 3.3.3.Reviewed by Cursor Bugbot for commit 7a92d6b. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix iOS thread list jumping while scrolling up by upgrading
@legendapp/listUpgrades
@legendapp/listfrom 3.2.0 to 3.3.3 and updates the workspace patch to match. The new version fixes scroll position jumps in long threads by suppressing layout transitions inReanimatedPositionViewduring MVCP adjustments and native scroll activity.onScrollBeginDraghandler to track user drag state and prepare edge handlingsetInitialRenderStatereadiness wheninsetEndRevealHoldis activelastMVCPAdjustTimeto coordinate transition suppression in animated rowsinsetEndRevealHoldstate, which may delay first paint in some scroll configurationsMacroscope summarized 7a92d6b.