Skip to content

fix(mobile): Duo feed scroll indicator stays left of the vertical bar while streaming - #36063

Merged
juliusmarminge merged 1 commit into
mainfrom
fix/duo-feed-scroll-indicator
Nov 13, 2026
Merged

juliusmarminge merged 1 commit into
mainfrom
fix/duo-feed-scroll-indicator

Conversation

@juliusmarminge

Copy link
Copy Markdown
Member

Problem

On an unfolded iPhone Duo, the thread feed's scroll indicator flickers during a streaming run. It jumps between its correct place, left of the vertical bar, and the screen edge under the bar.

T3ScrollEdgeBleedView widens the feed's scroll view under the bar and sets verticalScrollIndicatorInsets.right so the indicator stays clear of it. Fabric's RCTScrollViewComponentView (RN 0.88.1, updateProps) assigns the whole scrollIndicatorInsets (both axes, right = 0) whenever that prop changes. The bleed view only restored the inset on its own layoutSubviews, so for those frames the indicator sat under the bar.

That prop changes far more often than ThreadFeed's { top, bottom: 0 } suggests. KeyboardAwareLegendList renders react-native-keyboard-controller's ScrollViewWithBottomPadding, which sends scrollIndicatorInsets through Reanimated animatedProps with bottom = keyboard + anchored end space. That end space shrinks as a streaming reply grows, so the prop changes over and over during a run. Header show/hide also changes top.

Fix

While bleeding, the bleed view KVO-observes the scroll view's indicator insets and puts right back right away, in the same main-thread pass as React Native's write. Off the Duo, bleed is zero: no observation is installed and nothing is written, same as before. Observations are dropped when the bleed ends or the view detaches.

Verification

  • vp run check:changed: format and typecheck pass. No Swift toolchain on the Linux dev box, so this PR's iOS dev-client build and SwiftLint in CI are the compile check.
  • No before/after device capture. I leased an iPhone Duo (iOS 27.2) simulator from the device pool and ran the app unfolded against a Replay-provider thread. But every available dev client, including this repo's mobile-dev-client workflow on macos-26, is built with the iOS 26.5 SDK. On the Duo that runs letterboxed in compatibility mode, and the bleed view's vertical-bar code (#if canImport(UIKit, _version: 9127.0.85)) is compiled out. Reproducing needs an iOS 27.1-SDK build, and no machine I could use had Xcode 27.1. Someone with that build should check it on a Duo before merging.
  • Not verified: the header fading in and out in the original recording. Nothing here changes it. If it persists after this fix, it is a separate issue.

Model and harness: Claude Opus 5.5 in Claude Code (T3 Code).

🤖 Generated with Claude Code

… while streaming

React Native rewrites all of a scroll view's indicator insets whenever its
scrollIndicatorInsets prop changes. The keyboard-aware thread list animates
that prop's bottom inset as a reply streams, so each update reset the right
inset that the scroll-edge bleed view sets, and the indicator jumped under
the bar until the bleed view's next layout pass. While bleeding, observe the
indicator insets and put the right inset back immediately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted Author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. labels Nov 13, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 4310f8d

Macroscope's review found this PR approvable — Keeps the Duo scroll indicator clear of the vertical bar when streaming updates rewrite its insets. The change is limited to active scroll-edge presentation, with observations removed when that behavior ends.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The scroll edge bleed view now observes changes to both scroll-indicator inset properties while bleeding. It reapplies the right vertical indicator inset when either property changes and clears the observations when bleeding ends.

Changes: Scroll indicator inset observation

Layer / File(s) Summary
Observe and apply indicator insets
apps/mobile/modules/t3-native-controls/ios/T3ScrollEdgeBleedView.swift
While bleeding, the view observes changes to verticalScrollIndicatorInsets and scrollIndicatorInsets and reapplies the right vertical indicator inset. It clears the observations when bleeding ends.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related PRs

  • pingdotgg/t3code#24732: Changes the same view's bleed behavior and its handling of the right-side vertical bar.

Suggested labels: bugfix

Suggested reviewers: macroscopeapp

Merge Risk: Minimal · up to 4310f

This change keeps the scroll indicator clear of the vertical bar on an unfolded Duo while a reply streams. No concrete defect was found. The author could not run a device check with the required SDK, so confirm on a Duo with the iOS 27.1 SDK before relying on the fix.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the main change: a fix for the Duo thread feed scroll indicator staying left of the vertical bar while streaming. It follows the conventional commit format, and the raw summary shows t…
Description check Passed The description covers Problem, Change, and Verification with specific detail on the root cause (Fabric updateProps resetting scrollIndicatorInsets) and the fix (KVO observation while bleeding). It di…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the main change: a fix for the Duo thread feed scroll indicator staying left of the vertical bar while streaming. It follows the conventional commit format, and the raw summary shows the change in T3ScrollEdgeBleedView restores the right indicator inset while bleeding. The title is 85 characters, which is long but still specific.

Full details: Description check

Explanation

The description covers Problem, Change, and Verification with specific detail on the root cause (Fabric updateProps resetting scrollIndicatorInsets) and the fix (KVO observation while bleeding). It discloses that no before/after device capture exists and explains why. The Scope section is incomplete: it does not link an issue that shows the bug, and it does not explain why the fix needs no issue. The template asks for that link or justification. The model and harness line is present. Overall the description is mostly complete.

Resolution

Consider adding to the Scope section a link to the issue that shows the bug, or a short reason why no issue is needed. The Verification section also needs before/after screenshots or a recording, or a clear statement that none exist, which the author already provides.

Finishing Touches

Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between b80531d and 4310f8d.

Files selected for processing: 1

  • apps/mobile/modules/t3-native-controls/ios/T3ScrollEdgeBleedView.swift

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

@juliusmarminge juliusmarminge added the 🚀 Mobile Continuous Deployment Trigger Expo preview build label Nov 13, 2026
@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

🤖 Android preview

  🤖 Android
Fingerprint 0a2a4751f45a06fbb416126172b2c4e6584b774f
Dev client Install
Update Details Update Permalink
Update QR

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Expo continuous deployment is ready!

  • Project → t3-code
  • Platform → ios
  • Scheme → t3code-preview
  🤖 Android 🍎 iOS
Fingerprint n/a bd9dcfffd9dcfe3797e9a4940621686383139f53
Build Details n/a Build Permalink
DetailsDistribution: INTERNAL
Build profile: preview:dev
Runtime version: bd9dcfffd9dcfe3797e9a4940621686383139f53
App version: 2.3.0
Git commit: b1dd6c0795d6f18f4330e33925afaafb20fea38b
Update Details n/a Update Permalink
DetailsBranch: pr-36063
Runtime version: bd9dcfffd9dcfe3797e9a4940621686383139f53
Git commit: b1dd6c0795d6f18f4330e33925afaafb20fea38b
Update QR n/a

@juliusmarminge
juliusmarminge merged commit ca6e09c into main Nov 13, 2026
42 checks passed
@juliusmarminge
juliusmarminge deleted the fix/duo-feed-scroll-indicator branch November 13, 2026 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚀 Mobile Continuous Deployment Trigger Expo preview build 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. size:S 10-29 changed lines (additions + deletions). vouch:trusted 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