Skip to content
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
3 changes: 1 addition & 2 deletions src/libs/focusTextInputAfterAnimation/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* 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.
* This library is a no-op for all platforms except for Android and iOS and will immediately focus the given input without any delays.
*
* @param {Object} inputRef
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/**
* 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.
* Focus the text input with a slight delay to make sure modals are closed first.
* Since in react-native-modal `onModalHide` is called before the modal is actually hidden.
* It results in the keyboard being dismissed right away on both iOS and Android.
* See this discussion for more details: https://github.com/Expensify/App/issues/18300
*
* @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);
Expand Down
5 changes: 1 addition & 4 deletions src/pages/home/report/ReportActionItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ import RenameAction from '../../../components/ReportActionItem/RenameAction';
import InlineSystemMessage from '../../../components/InlineSystemMessage';
import styles from '../../../styles/styles';
import SelectionScraper from '../../../libs/SelectionScraper';
import focusTextInputAfterAnimation from '../../../libs/focusTextInputAfterAnimation';
import * as User from '../../../libs/actions/User';
import * as ReportUtils from '../../../libs/ReportUtils';
import OfflineWithFeedback from '../../../components/OfflineWithFeedback';
import * as ReportActions from '../../../libs/actions/ReportActions';
import * as ReportActionsUtils from '../../../libs/ReportActionsUtils';
import reportPropTypes from '../../reportPropTypes';
import {ShowContextMenuContext} from '../../../components/ShowContextMenuContext';
import focusTextInputAfterAnimation from '../../../libs/focusTextInputAfterAnimation';
import ChronosOOOListActions from '../../../components/ReportActionItem/ChronosOOOListActions';
import ReportActionItemReactions from '../../../components/Reactions/ReportActionItemReactions';
import * as Report from '../../../libs/actions/Report';
Expand Down Expand Up @@ -114,9 +114,6 @@ function ReportActionItem(props) {
return;
}

// 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(textInputRef.current, 100);
}, [isDraftEmpty]);

Expand Down