Skip to content
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

Fix the edit comment input getting focus when long-pressing on Android #13593

Merged
merged 6 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/libs/focusTextInputAfterAnimation/index.android.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* 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
* @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;
11 changes: 11 additions & 0 deletions src/libs/focusTextInputAfterAnimation/index.js
Original file line number Diff line number Diff line change
@@ -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 no longer triggered from a user interaction.
*
* @param {Object} inputRef
*/
const focusTextInputAfterAnimation = (inputRef) => {
inputRef.focus();
};

export default focusTextInputAfterAnimation;
5 changes: 4 additions & 1 deletion src/pages/home/report/ReportActionItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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() {
Expand Down