From 97d284343849a02c499967411dfc7f1b5ae9f916 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 14 Dec 2022 12:36:10 -0700 Subject: [PATCH 1/5] Add a delay for android to allow animation to finish --- .../index.android.js | 17 +++++++++++++++++ src/libs/focusTextInputAfterAnimation/index.js | 11 +++++++++++ src/pages/home/report/ReportActionItem.js | 5 ++++- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/libs/focusTextInputAfterAnimation/index.android.js create mode 100644 src/libs/focusTextInputAfterAnimation/index.js diff --git a/src/libs/focusTextInputAfterAnimation/index.android.js b/src/libs/focusTextInputAfterAnimation/index.android.js new file mode 100644 index 00000000000..164219e373b --- /dev/null +++ b/src/libs/focusTextInputAfterAnimation/index.android.js @@ -0,0 +1,17 @@ +/** + * For native Android devices, if an input is focused while an animation is happening, then they keyboard is not displayed. Delaying the focus until after the animation is done will ensure + * that the keyboard opens properly. + * + * @param {Object} inputRef + * @param {Number} animationLength you must use your best guess as to what a good animationLength is. It can't be too short, or the animation won't be finished. It can't be too long or + * the user will notice that it feels sluggish + */ +const focusTextInputAfterAnimation = (inputRef, animationLength = 0) => { + // This setTimeout is necessary because there are some animations that are just impossible to listen to in order to determine when they are finished (like when items are added to + // a FlatList). + setTimeout(() => { + inputRef.focus(); + }, animationLength); +}; + +export default focusTextInputAfterAnimation; diff --git a/src/libs/focusTextInputAfterAnimation/index.js b/src/libs/focusTextInputAfterAnimation/index.js new file mode 100644 index 00000000000..c4b179eef93 --- /dev/null +++ b/src/libs/focusTextInputAfterAnimation/index.js @@ -0,0 +1,11 @@ +/** + * This library is a no-op for all platforms except for Android and will immediately focus the given input without any delays. This is important for native iOS clients because + * text inputs can only be focused from user interactions and wrapping the focus() inside a setTimeout breaks that use case since it's not longer triggered from a user interaction. + * + * @param {Object} inputRef + */ +const focusTextInputAfterAnimation = (inputRef) => { + inputRef.focus(); +}; + +export default focusTextInputAfterAnimation; diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 42f440d0fd5..7158f15f37b 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -33,6 +33,7 @@ import * as ReportUtils from '../../../libs/ReportUtils'; import OfflineWithFeedback from '../../../components/OfflineWithFeedback'; import * as ReportActions from '../../../libs/actions/ReportActions'; import reportPropTypes from '../../reportPropTypes'; +import focusTextInputAfterAnimation from '../../../libs/focusTextInputAfterAnimation'; const propTypes = { /** Report for this action */ @@ -95,7 +96,9 @@ class ReportActionItem extends Component { } // Only focus the input when user edits a message, skip it for existing drafts being edited of the report. - this.textInput.focus(); + // There is an animation when the comment is hidden and the edit form is shown, and there can be bugs on different mobile platforms + // if the input is given focus in the middle of that animation which can prevent the keyboard from opening. + focusTextInputAfterAnimation(this.textInput, 100); } checkIfContextMenuActive() { From ebbb2ac453c99e0bf35d316c3d802958220ecea2 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 14 Dec 2022 12:49:57 -0700 Subject: [PATCH 2/5] Reduce animation length to a minimum --- src/pages/home/report/ReportActionItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 7158f15f37b..f713c71093c 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -98,7 +98,7 @@ class ReportActionItem extends Component { // Only focus the input when user edits a message, skip it for existing drafts being edited of the report. // There is an animation when the comment is hidden and the edit form is shown, and there can be bugs on different mobile platforms // if the input is given focus in the middle of that animation which can prevent the keyboard from opening. - focusTextInputAfterAnimation(this.textInput, 100); + focusTextInputAfterAnimation(this.textInput, 10); } checkIfContextMenuActive() { From 455cb41a0f95370dcbf8532014aba94f4b69abb2 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 14 Dec 2022 12:56:45 -0700 Subject: [PATCH 3/5] Fix typo --- src/libs/focusTextInputAfterAnimation/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/focusTextInputAfterAnimation/index.js b/src/libs/focusTextInputAfterAnimation/index.js index c4b179eef93..068e8da887b 100644 --- a/src/libs/focusTextInputAfterAnimation/index.js +++ b/src/libs/focusTextInputAfterAnimation/index.js @@ -1,6 +1,6 @@ /** * This library is a no-op for all platforms except for Android and will immediately focus the given input without any delays. This is important for native iOS clients because - * text inputs can only be focused from user interactions and wrapping the focus() inside a setTimeout breaks that use case since it's not longer triggered from a user interaction. + * text inputs can only be focused from user interactions and wrapping the focus() inside a setTimeout breaks that use case since it's no longer triggered from a user interaction. * * @param {Object} inputRef */ From a7674d4daf43b49118c1cd3ef1dbbd8bdc2d3df7 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Thu, 15 Dec 2022 07:50:23 -0700 Subject: [PATCH 4/5] Update src/libs/focusTextInputAfterAnimation/index.android.js Co-authored-by: Sahil --- src/libs/focusTextInputAfterAnimation/index.android.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/focusTextInputAfterAnimation/index.android.js b/src/libs/focusTextInputAfterAnimation/index.android.js index 164219e373b..554c7a2f6b8 100644 --- a/src/libs/focusTextInputAfterAnimation/index.android.js +++ b/src/libs/focusTextInputAfterAnimation/index.android.js @@ -1,5 +1,5 @@ /** - * For native Android devices, if an input is focused while an animation is happening, then they keyboard is not displayed. Delaying the focus until after the animation is done will ensure + * For native Android devices, if an input is focused while an animation is happening, then the keyboard is not displayed. Delaying the focus until after the animation is done will ensure * that the keyboard opens properly. * * @param {Object} inputRef From fa187d8c8237f6314753f068e3b110422e9a74bc Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Thu, 15 Dec 2022 07:51:42 -0700 Subject: [PATCH 5/5] Increase animation time to 100ms --- src/pages/home/report/ReportActionItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index f713c71093c..7158f15f37b 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -98,7 +98,7 @@ class ReportActionItem extends Component { // Only focus the input when user edits a message, skip it for existing drafts being edited of the report. // There is an animation when the comment is hidden and the edit form is shown, and there can be bugs on different mobile platforms // if the input is given focus in the middle of that animation which can prevent the keyboard from opening. - focusTextInputAfterAnimation(this.textInput, 10); + focusTextInputAfterAnimation(this.textInput, 100); } checkIfContextMenuActive() {