From 11ddd9f129ad642333660f77bd0fc968fb9d961b Mon Sep 17 00:00:00 2001 From: Boris Yankov Date: Mon, 13 Aug 2018 23:03:51 +0300 Subject: [PATCH] composebox: Improve text resetting code, circumvent iOS bug Fixes: #2434 There is a simple hack/fix for the iOS-specific bug that was a blocker for us migrating the iOS version. If we set the text via `setNativeProps` twice in a row, it will indeed reset the contents, so the first time we use a space `' '` that looks empty but is different than the second time when we set it to an actually empty string '``'. We use `setTimeout` in order to give React Native a chance to update the native value before running the second time. For Android we don't need to call `setNativeProps` as the `TextInputReset.resetKeyboardInput` call does that. Also compared to the previous version we don't need to check if `TextInputReset` is defined as it isn't only for iOS and we `if` for that. --- src/compose/ComposeBox.js | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/compose/ComposeBox.js b/src/compose/ComposeBox.js index c31384a3151..c68b991e3bb 100644 --- a/src/compose/ComposeBox.js +++ b/src/compose/ComposeBox.js @@ -1,6 +1,6 @@ /* @flow */ import React, { PureComponent } from 'react'; -import { View, TextInput, findNodeHandle } from 'react-native'; +import { View, Platform, TextInput, findNodeHandle } from 'react-native'; import { connect } from 'react-redux'; import TextInputReset from 'react-native-text-input-reset'; import isEqual from 'lodash.isequal'; @@ -76,6 +76,20 @@ type State = { selection: InputSelectionType, }; +const clearTextInput = (textInput: TextInput): void => { + if (Platform.OS === 'ios') { + // Calling `setNativeProps` twice works around the currently present iOS bug + // We need to call it with different values, the ' ' looks like no text + textInput.setNativeProps({ text: ' ' }); + setTimeout(() => { + textInput.setNativeProps({ text: '' }); + }, 0); + } else { + // Force reset to fix an issue with some Android custom keyboards + TextInputReset.resetKeyboardInput(findNodeHandle(textInput)); + } +}; + export const updateTextInput = (textInput: TextInput, text: string): void => { if (!textInput) { // Depending on the lifecycle events this function is called from, @@ -83,13 +97,14 @@ export const updateTextInput = (textInput: TextInput, text: string): void => { return; } - textInput.setNativeProps({ text }); - - if (text.length === 0 && TextInputReset) { - // React Native has problems with some custom keyboards when clearing - // the input's contents. Force reset to make sure it works. - TextInputReset.resetKeyboardInput(findNodeHandle(textInput)); + // Both iOS and Android have bugs related to clearing Input's contents + if (text.length === 0) { + clearTextInput(textInput); } + + setTimeout(() => { + textInput.setNativeProps({ text }); + }, 0); }; class ComposeBox extends PureComponent {