feat: blur the composer focus when open context menu#47621
feat: blur the composer focus when open context menu#47621cead22 merged 14 commits intoExpensify:mainfrom
Conversation
|
Small note: refocusing the edit composer after closing context menu will be handled here: #28238 |
rojiphil
left a comment
There was a problem hiding this comment.
@dominictb Thanks for the PR. I have just left a couple of review comments. Please have a look.
| } | ||
|
|
||
| ReportActionComposeFocusManager.composerRef.current?.blur(); | ||
| ReportActionComposeFocusManager.editComposerRef.current?.blur(); |
There was a problem hiding this comment.
Instead of calling individual blur, can we define a utility function in ReportActionComposeFocusManager and call blur when focussed? I think that would be neater.
There was a problem hiding this comment.
hmm let me check on this.
| onFocus={() => { | ||
| setIsFocused(true); | ||
| if (textInputRef.current) { | ||
| ReportActionComposeFocusManager.editComposerRef.current = textInputRef.current; |
There was a problem hiding this comment.
Let us reset the editComposerRef when the focus is lost to avoid dangling references. One way to do this is by resetting it inside ReportActionComposeFocusManager.clear.
There was a problem hiding this comment.
I think we shouldn't reset editComposerRef since we use it to restore focus in case users open edit emoji picker then dismiss it
There was a problem hiding this comment.
Maybe I am missing something here but why would we need editComposerRef after ReportActionComposeFocusManager.clear is called here?
There was a problem hiding this comment.
Ah, when ReportActionComposeFocusManager.clear we can reset editComposerRef, but not when the focus is lost. So you mean to reset it when the edit composer disappears (not when it's blurred), right?
There was a problem hiding this comment.
when ReportActionComposeFocusManager.clear we can reset
editComposerRef
Yes, that's what I meant
There was a problem hiding this comment.
Can you please check if we also have to set the editComposerRef on component mount of ReportActionItemMessageEdit because I ran into issues where the edit composer did not blur as editComposerRef was not set at all? Here is a video that demonstrates this. Please have a look.
47621-mweb-safari-blurissue.mp4
There was a problem hiding this comment.
Let me check this and get back to you.
There was a problem hiding this comment.
@rojiphil after testing, there's a small change needed to fix this issue. As ReportActionComposeFocusManager.clear(); is triggered in both main and edit composer, when users open new edit composer, editComposerRef is set, then the logic clear
-> It’s wrong since the edit composer is still open
I think we should set/reset editComposerRef in ReportActionItemMessageEdit. I have pushed the latest commit with the change.
|
Will look into this |
|
On it now. |
|
@dominictb There are conflicts that must be resolved. Please resolve and ping me here when ready for review. Thanks. |
rojiphil
left a comment
There was a problem hiding this comment.
@dominictb I have left few comments. Please have a look.
| if (isPriorityCallback) { | ||
| priorityFocusCallback = null; | ||
| } else { | ||
| editComposerRef.current = null; |
There was a problem hiding this comment.
Don't we have to reset editComposerRef when isPriorityCallback is true because we call clear(true) in ReportActionItemMessageEdit?
| onFocus={() => { | ||
| setIsFocused(true); | ||
| if (textInputRef.current) { | ||
| ReportActionComposeFocusManager.editComposerRef.current = textInputRef.current; |
There was a problem hiding this comment.
Can you please check if we also have to set the editComposerRef on component mount of ReportActionItemMessageEdit because I ran into issues where the edit composer did not blur as editComposerRef was not set at all? Here is a video that demonstrates this. Please have a look.
47621-mweb-safari-blurissue.mp4
|
On it now. |
|
https://github.com/Expensify/App/pull/47621/files#diff-f0bdc7ab41060e24e6bcdc847f25185b372c5f9a072251fe5d3cae2a27887920L85-L96 Migrating withOnyx to useOnyx in this case seems non-trivial. Could we skip this in this PR? |
|
waiting on @rojiphil's review. |
@dominictb Can you please merge with the latest main? I will review this today. |
rojiphil
left a comment
There was a problem hiding this comment.
@dominictb Thanks for the merge. I have left some more review comments. Please have a look.
| onFocus={() => { | ||
| setIsFocused(true); | ||
| if (textInputRef.current) { | ||
| ReportActionComposeFocusManager.editComposerRef.current = textInputRef.current; |
There was a problem hiding this comment.
I am not sure why we removed this as I think we need to set the editComposerRef here too i.e. when the edit composer receives focus as there will be cases where the edit composer is mounted but the focus has changed. Here is a test video demonstrating the problem
47621-focus-issue-1.mp4
| ReportActionComposeFocusManager.editComposerRef.current = textInputRef.current; | ||
| } | ||
| return () => { | ||
| ReportActionComposeFocusManager.editComposerRef.current = null; |
There was a problem hiding this comment.
There was a problem hiding this comment.
Yes, we can. I'll update soon
| } | ||
| return () => { | ||
| ReportActionComposeFocusManager.editComposerRef.current = null; | ||
| ReportActionComposeFocusManager.clear(true); |
There was a problem hiding this comment.
- There is already a code used for handling unmount as mentioned here. Let us use that code to avoid duplicate coding.
- Also, shouldn't it be
ReportActionComposeFocusManager.clear();here as we do not want to reset theeditcomposerif focus already exists on another edit item. Here is a test video demonstrating the problem:
47621-clear-issue-1.mp4
There was a problem hiding this comment.
Here's the result after refactoring
Screen.Recording.2024-10-01.at.11.21.52.mov
|
@rojiphil updated. Please re-review. |
rojiphil
left a comment
There was a problem hiding this comment.
@dominictb The following comments are not addressed yet:
1 Also, shouldn't it be ReportActionComposeFocusManager.clear(); here as we do not want to reset the editcomposer if focus already exists on another edit item. Here is a test video demonstrating the problem:
You're right, I think we just call ReportActionComposeFocusManager.clear(true) when editComposerRef === textInputRef.current. Any thoughts? |
Yes. That make sense. |
Isn't this pending to be addressed?
Ok. This is addressed. Thanks.
And this is addressed here |
Addressed in the latest commit. |
|
Fixed in the latest commit. |
|
@dominictb This looks much closer to getting it done. Can you please merge it with the latest main? |
|
@rojiphil done! |
Reviewer Checklist
Screenshots/VideosiOS: mWeb Safari47621-mweb-safari-005.mp4Android: Native47621-android-native-005.mp4Android: mWeb Chrome47621-mweb-chrome-005.mp4iOS: Native47621-ios-native-005.mp4MacOS: Chrome / Safari47621-web-safari-005.mp4MacOS: Desktop47621-desktop-005.mp4mWeb Safari - Original Issue47621-mweb-safari-issue-repro.mp4 |
There was a problem hiding this comment.
@dominictb Thanks. I have just one comment related to test steps.
Please update the test cases as follows to include testing for editable messages:
Note: Tests are applicable only for native and mweb platforms.
- Go to any chat
- Click on the composer to bring the keyboard (if its not already open)
- While the keyboard is open long press on a message to bring the action menu
- Verify that the keyboard closes when the action menu is opened (Test 1)
- Click and focus inside an editable message so that the keyboard is displayed.
- While the keyboard is open long press on any other message to bring the action menu.
- Verify that the keyboard closes when the action menu is opened (Test 2)
@cead22 LGTM and works well too.
Over to you for review. Thanks.
|
@rojiphil I see a console warning on your iOS video for "Function components cannot be given refs", is that the same as the one in this issue #49062? If so, do we need to merge main into this branch to solve it? If it's different please report it in GH or slack, and don't forget checking for console errors is part of the checklist |
The warning is the same but this comes up in another flow. I have reported the same in slack here |
|
They linked the same GH issue #49062 on that slack thread. So let's merge main into this branch, test again, and if it doesn't happen, problem solved. If it does happen, we need to open a new GH issue to solve this for the flow in which is happening |
I still think they have got it wrong as I could reproduce this in the latest main and the mentioned duplicate issue's PR has already been merged since last one week. And our PR also contains that code. Anyway, I have responded to this in slack here. Meanwhile, I think we can go ahead and merge this as we have reported it. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/cead22 in version: 9.0.49-0 🚀
|
|
🚀 Deployed to production by https://github.com/marcaaron in version: 9.0.49-2 🚀
|
Details
Fixed Issues
$ #44042
PROPOSAL: #44042 (comment)
Tests
Verify that: The keyboard closes when the action menu is opened
Offline tests
QA Steps
Verify that: The keyboard closes when the action menu is opened
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)myBool && <MyComponent />.src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.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
compressed_android.webm.mp4
Android: mWeb Chrome
compressed_aweb.webm.mp4
iOS: Native
compressed_ios.mp4.mp4
iOS: mWeb Safari
compressed_iosweb.mp4.mp4
MacOS: Chrome / Safari
compressed_web.mov.mp4
MacOS: Desktop
compressed_web.mov.mp4