Repository navigation
fix(mobile): keep code reviewer instruction drafts and grow the editor field - #7892
Conversation
…r field The Custom instructions editor on the code reviewer platform screen had two problems with a multi-line stored value: 1. The multiline field used a fixed h-32, so a stored value longer than the box opened scrolled to the caret with the first line clipped and no scroll indicator. The field now uses min-h-32 and grows with content, so it opens at the first line. 2. The draft lived in a ref over an uncontrolled defaultValue with no back guard, so Android back while editing silently restored the stored text and discarded the rewrite with no confirmation. The route now wires the shared useSettingsBackGuard (same hook as the security-agent settings screens): any exit while dirty offers Keep editing, Discard, and Save; an Android back that only dismisses the keyboard still keeps the draft, and the save button bypasses the guard for its own back. The draft stays uncontrolled per apps/mobile/AGENTS.md "Text inputs": the loaded value reaches the field directly, the comparison baseline and the draft live in refs, and only the derived dirty flag reaches state. Mounted suite covers the growing field, the clean/dirty back paths, the dialog save, the save-button bypass, and the refetch-while-editing case.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe incremental delta since the last review (an iOS Assumptions: Files Reviewed (2 files)
Previous Review Summary (commit 8fb7e7a)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 8fb7e7a)Status: No Issues Found | Recommendation: Merge Executive SummaryThe two-file mobile change (a growing Custom-instructions editor plus a Files Reviewed (2 files)
Reviewed by deepseek-flash-latest · Input: 62.9K · Output: 12.6K · Cached: 725K Review guidance: REVIEW.md from base branch |
…nstructions-draft-guard # Conflicts: # apps/mobile/src/app/(app)/(tabs)/(3_profile)/code-reviewer/[scope]/[platform]/(edit)/instructions.tsx
…d suite The editor renders an iOS keyboard accessory bar and dismisses the keyboard from it, so the mounted suite's react-native stub provides those exports.
|
bot: Android proof from the local dev stack with an owned fake account and a seeded review configuration.
After Save, the stored configuration held the edited value, and back on a clean draft left the screen with no dialog. |
… long drafts (Kilo-Org#9206) * fix(mobile): bound the code reviewer instructions editor field A stored draft of a few thousand characters made the multiline field as tall as its whole content, so the deprecation note and Save sat outside the viewport, the page had almost no scroll range of its own, and with the keyboard up the field was clipped mid-text. Cap the field at ten `leading-[1.25rem]` line boxes plus its `p-3` padding, the same bounded-editor shape the profile, MCP, slash-command and skill editors already use, with a cap aligned to whole lines so a caret scroll never paints the top visible line cut. The `min-h-32` floor from Kilo-Org#7892 still grows the field for a short value, and above the cap the field scrolls its own text. A capped field opens at the platform caret, which sits at the end of the stored value, so the first line would be out of sight — the state Kilo-Org#7892 removed. Once the field and its content are measured, a value taller than the usable field puts the caret on the first line; a value that fits keeps the platform caret. * fix(mobile): leave the caret alone once the instructions draft is edited The first-line alignment belongs to the stored value's opening state. Both platforms report a content size for the empty field at mount, so it is normally spent before the reader touches the field; a mount that reports none, such as a recycled view, would leave it pending and fire it on the reader's own first paste, pulling the caret back to the start. Record the first text change and skip the alignment after it, with a mounted case that feeds an edit before the overflow measurement.


Change
apps/mobile/src/app/(app)/(tabs)/(3_profile)/code-reviewer/[scope]/[platform]/(edit)/instructions.tsx:h-32. A stored value longer than the box opened scrolled to the caret with the first line clipped and no scroll indicator. It now usesmin-h-32(same pattern as the multiline input insave-profile-sheet.tsx), so the field grows with content and opens at the first line.defaultValuewith no back guard, so Android back while editing silently restored the stored text and discarded the rewrite with no confirmation, undo, or warning. The route now wires the shareduseSettingsBackGuard(the same hook the security-agent settings screens use), so every way off the screen (header back, Android hardware back, iOS swipe-back) offers Keep editing / Discard / Save while the draft differs from the stored value. An Android back that only dismisses the keyboard never removes the screen, so the edit is kept. The bottom Save button setsskipNextGuardRefbefore its ownrouter.back()(same bypass asSettingsSaveButton).The draft stays uncontrolled per
apps/mobile/AGENTS.md"Text inputs": the loaded value reaches the field directly, the dirty baseline and the draft live in refs (seeded once, so later refetches never clobber in-progress edits), and only the derived dirty flag reaches state.Tests
New mounted suite
instructions.mounted.test.tsxkeeps the realuseSettingsBackGuard/useConfirmDialogchain and stubs only the native surfaces:min-h-32(noh-32),multiline, uncontrolled withdefaultValuefrom the stored text;pnpm test(apps/mobile): 1191 files, 17878 tests pass.tsgo --noEmitreports no errors in the changed files (the 963 pre-existing errors on this checkout are identical with the change stashed and all live in unrelated files).oxlint(mobile config) clean on both files.End-to-end verification (Android emulator, local dev stack)
Local stack:
pnpm dev:start(nextjs on 3000, Metro on 8081), fake-login user seeded, a six-line stored instructions value for the personal GitHub reviewer, dev client installed from themobile-native-buildartifact, JS served from Metro.Observed on device (
emulator-5554, Android 16):min-h-32floor (the old fixed box was 336 px),scrollable=false, first lineالسطر الأول: …fully visible at the top, all six lines readable without scrolling. Screenshots:/tmp/arabic-editor-final.png,/tmp/arabic-editor.png.mutateAsyncpayload verified in Postgres) and returned to the platform screen.Proxy answers
The owner's proxy gave these answers in the owner's place.
Answer: Trimmed comparison (Recommended)
Confidence: 0.75 · Precedent: Autonomy: make executive decisions yourself, with "is this reasonable?" as the test. The trimmed comparison matches what Save persists and avoids a stale dirty flag right after saving.
Answer: valid = true always (Recommended)
Confidence: 0.85 · Precedent: The "is this reasonable?" test. An empty instructions value is a legitimate save that clears the instructions, so blocking Save would be wrong.
Answer: Existing settingsSave copy (Recommended)
Confidence: 0.70 · Precedent: Do the least amount of work with no drop in quality; keep similar elements consistent across surfaces.
Answer: Keep bottom Save, no header Save (Recommended)
Confidence: 0.65 · Precedent: Cut unnecessary affordances; remove redundancy. Two save affordances on one small screen are redundant.
Answer: Grow with content (Recommended)
Confidence: 0.92 · Precedent: Fix the root cause and the class of the issue; the brief asks to replace h-32 with a minimum height.