Fix composer hidden behind keyboard on cold start into a chat - #97357
Fix composer hidden behind keyboard on cold start into a chat#97357MelvinBot wants to merge 1 commit into
Conversation
Co-authored-by: Bernhard Owen Josephus <bernhardoj@users.noreply.github.com>
|
I looked into the failing checks. There's nothing broken in the code — every automated check passes (typecheck, all 8 Jest test jobs, ESLint, Oxfmt, Storybook, perf tests, builds, spellcheck). The only failing check is PR Author Checklist / checklist, and it fails simply because none of the 38 checklist boxes are ticked yet:
This one isn't something I can fix by pushing code — it needs you (the human co-author) to actually run the manual test/QA steps and check the boxes in the PR description. Several of those items assert things like "I tested on Android: Native / iOS: Native" and "I wrote clear testing steps," which I shouldn't tick on your behalf since they'd be untrue until a person verifies them. To make this check pass:
Once the checklist is filled out, this check will go green. |
Explanation of Change
On a cold start (force-quit then reopen), the app can restore directly into a report via the
NavigationContainer'sinitialState, bypassing the LHN. React Navigation does not fireonStateChangefor the initial state, andupdateCurrentReportIDwas only ever called from theonStateChangehandler — socurrentReportIDstayed unset ('') for that first restored report.ReportScreengates its keyboard-avoiding view onisTopMostReportId = currentReportID === reportIDFromRoute. WithcurrentReportIDempty,isTopMostReportIdisfalse, soshouldEnableKeyboardAvoidingViewisfalseand the composer is not lifted above the keyboard — it ends up hidden behind it. Navigating back to the LHN and reopening the chat fires a real state change, which is why the workaround restored correct behavior.This change seeds
currentReportIDfrom the restored root state insideonReadyWithSentry(which runs once the container is ready), soisTopMostReportIdis correct on the very first report screen after a cold start. The existingupdateCurrentReportIDguards mean it safely no-ops when the cold start lands on a non-report screen (e.g. Inbox or Settings).Fixed Issues
$ #97295
PROPOSAL: #97295 (comment)
Tests
// TODO: The human co-author must fill out the manual test steps you ran before marking this PR as "ready for review".
// Suggested flow to validate: (1) open a chat and let it become the last-visited path, (2) force-quit the iOS app, (3) reopen so it restores directly into that chat, (4) tap the composer and verify it lifts above the keyboard with the cursor visible.
Offline tests
// TODO: The human co-author must fill out any relevant offline test steps.
QA Steps
// TODO: The human co-author must fill out the QA steps before marking this PR as "ready for review".
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari