fix(mobile): reserve the bottom safe area on Android surfaces - #6003
fix(mobile): reserve the bottom safe area on Android surfaces#6003PollyGlot wants to merge 2 commits into
Conversation
|
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 |
897f11f to
30dbe7d
Compare
ApprovabilityVerdict: Needs human review This PR modifies runtime UI layout behavior across multiple mobile screens and introduces a new lint rule. A Medium-severity finding identifies a potential regression where pre-glass iOS devices may lose bottom safe area padding in FileTreeBrowser. The behavioral changes and potential regression warrant human review. You can customize Macroscope's approvability policy. Learn more. |
|
Thanks — all three findings were real. Fixed in cf1ca8c. iOS doubled bottom spacing (archived threads + file tree). Confirmed, and this repo already documents the mechanism in Both lists now apply the manual inset on Android only, so iOS spacing is byte-for-byte what it was before this PR: paddingBottom: Platform.OS === "android" ? Math.max(insets.bottom, 16) + 16 : 32The two other changes in this PR are unaffected: the terminal's floating button is absolutely positioned (no content inset involved) and Worth noting for a follow-up, out of scope here: on pre-liquid-glass iOS the file tree uses Rule: file-level inset flag. Fixed — inset reads are now tracked per top-level function instead of per file, so a header component that reads the inset no longer excuses a sibling list that ignores it. Nested functions ( This immediately paid off: the stricter rule flagged Rule: style arrays. Fixed — Test coverage went from 6 to 9 cases, one per finding. Repo-wide the rule now reports zero violations. |
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.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cf1ca8c. Configure here.
The terminal's floating keyboard button sat at a raw bottom: 16, the file tree and archived-threads lists ended in fixed padding, and the anchored menu treated the gesture bar as usable space. All four render under the Android gesture bar (and the iOS home indicator). Pad them with the house Math.max(insets.bottom, N) convention, and add a t3code/require-bottom-safe-area-inset lint rule so the next bottom-anchored surface cannot ship without it. The rule only fires on React Native files that pin content to the bottom edge and never read insets.bottom. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Macroscope was right about the iOS regression: where a list sets
contentInsetAdjustmentBehavior="automatic", UIKit already adds the safe
area to the content inset, so adding it again in contentContainerStyle
left a dead strip below the last row. The archived-threads and file-tree
lists now apply the manual inset on Android only, restoring the exact
pre-PR iOS spacing.
The rule itself had two gaps, both now covered by tests:
- inset reads were tracked per file, so a header component reading the
inset excused a sibling list that ignored it. They are now tracked per
top-level function, which immediately surfaced the same bug in
ReviewSheet's file navigator (fixed here).
- style arrays (contentContainerStyle={[base, { paddingBottom: 8 }]})
were skipped entirely; array elements are now flattened.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cf1ca8c to
ac333f9
Compare

What Changed
Four Android surfaces that anchor content to the bottom edge now reserve the safe-area inset, and a new
t3code/require-bottom-safe-area-insetlint rule keeps the next one from shipping without it.bottom: 16Math.max(insets.bottom, 16) + 16(same asAndroidHomeFab)paddingBottom: 0insets.bottompaddingBottom: 8Math.max(insets.bottom, 8) + 8paddingBottom: 32Math.max(insets.bottom, 16) + 16AndroidAnchoredMenumax(keyboard, insets.bottom)Why
Follow-up to the chat composer fix (#5988), which was one instance of a pattern.
contentInsetAdjustmentBehavior="automatic"only pads the safe area on iOS, so Android lists that relied on it ended flush against the gesture bar; the terminal button and the anchored menu never accounted for it at all.The lint rule fires only on React Native files that pin content to the bottom edge (
position: "absolute"with a fixed non-zerobottom, or a literalpaddingBottomincontentContainerStyle/contentInset) and never readinsets.bottom.bottom: 0is exempt: that is how a keyboard-synced overlay attaches to the edge while its child owns the padding. Across the whole repo it flagged exactly the three code sites fixed here and nothing else.UI Changes
Pixel emulator, API 35, gesture navigation, dev client against a local backend.
Verified on device: file tree, terminal button, and the anchored menu (no placement regression). The archived-threads padding is a code-level change I did not reproduce on screen; its previous 32 happened to exceed this device's 24dp inset, so it was fragile rather than visibly broken.
Checklist
oxlint-plugin-t3code/rules/require-bottom-safe-area-inset.test.ts)🤖 Generated with Claude Code
Note
Low Risk
Localized mobile layout and lint-only guardrails; iOS paths are explicitly unchanged aside from shared menu height math.
Overview
Fixes Android layouts where lists, menus, and floating controls sat under the gesture bar because
contentInsetAdjustmentBehavioronly applies on iOS.Runtime changes: Several screens now use
useSafeAreaInsets()and the house patternMath.max(insets.bottom, N) + Nfor listpaddingBottomon Android only (archived threads, file tree, review file list). The terminal addsinsets.bottomto scroll padding when the keyboard is hidden and lifts the “show keyboard” FAB the same way.AndroidAnchoredMenutreats usable height asoverlay.height - max(keyboardHeight, insets.bottom)so menus don’t open into the gesture bar when the keyboard is down.Lint: Adds
t3code/require-bottom-safe-area-inset(error invite.config.ts) for React Native files that pin content with a non-zerobottomor literalpaddingBottomon scroll content without readinginsets.bottom/bottomInset/SafeAreaViewin that component. Includes unit tests;bottom: 0edge overlays stay exempt.Reviewed by Cursor Bugbot for commit ac333f9. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Reserve bottom safe area insets on Android across mobile surfaces
insets.bottomfromuseSafeAreaInsets.require-bottom-safe-area-insetoxlint rule (enforced aserror) that detects React Native components anchoring content to the bottom without reserving safe-area insets, preventing regressions.Macroscope summarized ac333f9.