Repository navigation
fix(mobile): keep recent-review and repository rows inside landscape side insets - #8504
Conversation
The recent-reviews list and the security-agent repository picker built their content container from a fixed 24pt horizontal gutter. On a notched iPhone in landscape the safe-area side inset is wider than that gutter, so rows whose band overlaps the sensor housing drew their titles under it. Derive the content container padding from the safe-area side insets and keep the 24pt gutter on top of them, from one memoized style so recycled rows share the offset and a rotation re-derives it.
|
bot: Visual evidence from this VM against a local dev stack and a seeded fake account (eight terminal review rows, no production data).
The security-agent repository picker received the same content-container change and is covered by its mounted test; reaching it at runtime needs a connected provider and repository fixture, so it has no capture here. |
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe inset-derived content-container padding in both mobile lists is correct, memoized on primitive inset values, covered by portrait/landscape mounted tests, and introduces no double-padding, leak, or behavior change in portrait. Assumptions: Files Reviewed (4 files)
Reviewed by deepseek-flash-latest · Input: 98.4K · Output: 10.4K · Cached: 1M Review guidance: REVIEW.md from base branch |
|
bot: Follow-up verification of the head commit on both lists, on the iOS simulator lane and the Android emulator, against a local dev stack and a seeded fake account (eight terminal review rows, four repository rows). No production data. Measured row origins (app-reported accessibility rects, and the
Every row on both lists and in both orientations now starts at the same offset, recycled rows included, and the titles are fully readable. Screenshots to follow in this comment's attachments. |










Evidence
Evidence: demonstrated — the two lists were rendered with a seeded fake account on a leased iOS simulator lane (dev client loading the VM's Metro) and on the Android emulator, in landscape and portrait. On the base revision every row took the fixed gutter and sat under the sensor housing or display cutout (
63pxfor the Android landscape row titles,24ptfor the iOS portrait gutter); on the head revision every row starts at the inset plus the gutter —86pton an874ptiOS landscape screen,189pxon a2400pxAndroid landscape screen — with equal leading and trailing margins, and the same screen re-derived its offset when rotated back. Captures and per-row rects are in abot:comment on this pull request.What changed
Two mobile lists built their content container from a fixed 24pt horizontal gutter:
the recent-reviews list (
apps/mobile/src/components/code-reviewer/review-list-screen.tsx)and the security-agent repository picker
(
apps/mobile/src/components/security-agent/repository-settings-screen.tsx).On a device whose landscape safe area is wider than that gutter, every row drew its
leading characters under the sensor housing or the display cutout.
Both screens now derive the content-container padding from the safe-area side insets
and keep the 24pt gutter on top of them:
One memoized style per insets value, so every row — freshly mounted or recycled —
starts at the same offset and a rotation re-derives the padding once. This matches
the two pr-review FlashLists, which already read
useSafeAreaInsetsfor the samereason; portrait insets are zero, so the portrait layout is unchanged.
End-to-end evidence
Run on this work VM against a local dev stack with a seeded fake account
(
dev/seed/code-reviews/review-list.ts, eight terminal rows, and four cachedrepository rows for the picker).
iOS — leased simulator lane, dev client of this branch loading JS from the VM's Metro:
x = 86pton every row702ptof874ptx = 24pton every row354ptof402ptx = 86pton every row702ptof874pt86 = 62(landscape side inset)+ 24(gutter), and874 - 702 - 86 = 86, so theleading and trailing margins are equal. Rotating back to portrait restored
24pt, sothe offset is re-derived on rotation rather than kept from the previous frame.
Android — emulator with a
136pxdisplay cutout on the left edge in landscape:63px= 24dp189px=136pxcutout+ 53pxgutter189pxThe titles stay clear of the cutout band in landscape and the gutter is unchanged in
portrait.
Unit coverage:
full-surface-states.mounted.test.tsxandrepository-settings-screen.mounted.test.tsxassert the content-container padding forportrait (
24 / 24) and landscape (47 / 59insets →71 / 83). Both assertions failon the previous code and pass with this change;
oxlinton the four touched files isclean and
tsc --noEmitreports no errors.Not exercised at runtime: the picker's toggle and save paths (the list rendering, which
carries the padding, was exercised). Truncation of very long titles is unchanged — the
row text keeps
numberOfLines={1}.Proxy answers
The owner's proxy gave these answers in the owner's place.
code-reviewer/review-list-screen.tsx.components/security-agent/repository-settings-screen.tsxhas the identical fixedpaddingHorizontal: 24FlashList and no safe-area handling, so it has the same latent landscape clipping (not reported). Fix only the reported list, or both?Answer: Both lists in this PR
Confidence: 0.70 · Precedent: Fix the root cause and the class of the issue on every affected surface.
Answer: Raw
useSafeAreaInsetsConfidence: 0.50 · Precedent: Keep similar elements consistent across surfaces; this matches the sibling pr-review FlashLists and keeps the gutters symmetric.
Answer: After-fix iOS + Android proof
Confidence: 0.65 · Precedent: Do the least work possible with no drop in quality; the explorer's evidence already covers the base reproduction.