-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: blur the composer focus when open context menu #47621
Conversation
Small note: refocusing the edit composer after closing context menu will be handled here: #28238 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dominictb Thanks for the PR. I have just left a couple of review comments. Please have a look.
@@ -342,6 +343,8 @@ function ReportActionItem({ | |||
return; | |||
} | |||
|
|||
ReportActionComposeFocusManager.composerRef.current?.blur(); | |||
ReportActionComposeFocusManager.editComposerRef.current?.blur(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm let me check on this.
@@ -494,6 +494,9 @@ function ReportActionItemMessageEdit( | |||
style={[styles.textInputCompose, styles.flex1, styles.bgTransparent]} | |||
onFocus={() => { | |||
setIsFocused(true); | |||
if (textInputRef.current) { | |||
ReportActionComposeFocusManager.editComposerRef.current = textInputRef.current; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when ReportActionComposeFocusManager.clear we can reset
editComposerRef
Yes, that's what I meant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me check this and get back to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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
App/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx
Line 645 in 14b99ca
ReportActionComposeFocusManager.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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dominictb I have left few comments. Please have a look.
@@ -60,6 +63,7 @@ function clear(isPriorityCallback = false) { | |||
if (isPriorityCallback) { | |||
priorityFocusCallback = null; | |||
} else { | |||
editComposerRef.current = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we have to reset editComposerRef
when isPriorityCallback
is true because we call clear(true)
in ReportActionItemMessageEdit
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -494,6 +494,9 @@ function ReportActionItemMessageEdit( | |||
style={[styles.textInputCompose, styles.flex1, styles.bgTransparent]} | |||
onFocus={() => { | |||
setIsFocused(true); | |||
if (textInputRef.current) { | |||
ReportActionComposeFocusManager.editComposerRef.current = textInputRef.current; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dominictb Thanks for the merge. I have left some more review comments. Please have a look.
@@ -516,9 +530,6 @@ function ReportActionItemMessageEdit( | |||
style={[styles.textInputCompose, styles.flex1, styles.bgTransparent]} | |||
onFocus={() => { | |||
setIsFocused(true); | |||
if (textInputRef.current) { | |||
ReportActionComposeFocusManager.editComposerRef.current = textInputRef.current; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can. I'll update soon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rojiphil I updated
} | ||
return () => { | ||
ReportActionComposeFocusManager.editComposerRef.current = null; | ||
ReportActionComposeFocusManager.clear(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 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 theeditcomposer
if 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the result after refactoring
Screen.Recording.2024-10-01.at.11.21.52.mov
@rojiphil updated. Please re-review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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 Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.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