diff --git a/src/components/EmojiPicker/EmojiPicker.js b/src/components/EmojiPicker/EmojiPicker.js index 1eb4b5a5c496..285e0a6f4b8c 100644 --- a/src/components/EmojiPicker/EmojiPicker.js +++ b/src/components/EmojiPicker/EmojiPicker.js @@ -34,21 +34,6 @@ const EmojiPicker = forwardRef((props, ref) => { const onEmojiSelected = useRef(() => {}); const emojiSearchInput = useRef(); - useEffect(() => { - if (isEmojiPickerVisible) { - Keyboard.dismiss(); - } - - const emojiPopoverDimensionListener = Dimensions.addEventListener('change', () => { - calculateAnchorPosition(emojiPopoverAnchor.current).then((value) => { - setEmojiPopoverAnchorPosition(value); - }); - }); - return () => { - emojiPopoverDimensionListener.remove(); - }; - }, [isEmojiPickerVisible]); - /** * Show the emoji picker menu. * @@ -110,9 +95,7 @@ const EmojiPicker = forwardRef((props, ref) => { const selectEmoji = (emoji, emojiObject) => { // Prevent fast click / multiple emoji selection; // The first click will hide the emoji picker by calling the hideEmojiPicker() function - // and in that function the emojiPopoverAnchor ref to will be set to null (synchronously) - // thus we rely on that prop to prevent fast click / multiple emoji selection - if (!emojiPopoverAnchor.current) { + if (!isEmojiPickerVisible) { return; } @@ -130,7 +113,31 @@ const EmojiPicker = forwardRef((props, ref) => { */ const isActiveReportAction = (actionID) => Boolean(actionID) && reportAction.reportActionID === actionID; - useImperativeHandle(ref, () => ({showEmojiPicker, isActiveReportAction, hideEmojiPicker, isEmojiPickerVisible})); + const resetEmojiPopoverAnchor = () => (emojiPopoverAnchor.current = null); + + useImperativeHandle(ref, () => ({showEmojiPicker, isActiveReportAction, hideEmojiPicker, isEmojiPickerVisible, resetEmojiPopoverAnchor})); + + useEffect(() => { + if (isEmojiPickerVisible) { + Keyboard.dismiss(); + } + + const emojiPopoverDimensionListener = Dimensions.addEventListener('change', () => { + if (!emojiPopoverAnchor.current) { + // In small screen width, the window size change might be due to keyboard open/hide, we should avoid hide EmojiPicker in those cases + if (isEmojiPickerVisible && !props.isSmallScreenWidth) { + hideEmojiPicker(); + } + return; + } + calculateAnchorPosition(emojiPopoverAnchor.current).then((value) => { + setEmojiPopoverAnchorPosition(value); + }); + }); + return () => { + emojiPopoverDimensionListener.remove(); + }; + }, [isEmojiPickerVisible, props.isSmallScreenWidth]); // There is no way to disable animations, and they are really laggy, because there are so many // emojis. The best alternative is to set it to 1ms so it just "pops" in and out diff --git a/src/components/EmojiPicker/EmojiPickerButton.js b/src/components/EmojiPicker/EmojiPickerButton.js index 77e5bfa9ef7d..32a794911fd9 100644 --- a/src/components/EmojiPicker/EmojiPickerButton.js +++ b/src/components/EmojiPicker/EmojiPickerButton.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useEffect} from 'react'; import PropTypes from 'prop-types'; import styles from '../../styles/styles'; import * as StyleUtils from '../../styles/StyleUtils'; @@ -35,6 +35,7 @@ const defaultProps = { function EmojiPickerButton(props) { let emojiPopoverAnchor = null; + useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []); return ( EmojiPickerAction.resetEmojiPopoverAnchor, []); const onPress = () => { const openPicker = (refParam, anchorOrigin) => { diff --git a/src/libs/actions/EmojiPickerAction.js b/src/libs/actions/EmojiPickerAction.js index 458154913e3c..de462ac283f3 100644 --- a/src/libs/actions/EmojiPickerAction.js +++ b/src/libs/actions/EmojiPickerAction.js @@ -52,4 +52,11 @@ function isEmojiPickerVisible() { return emojiPickerRef.current.isEmojiPickerVisible; } -export {emojiPickerRef, showEmojiPicker, hideEmojiPicker, isActiveReportAction, isEmojiPickerVisible}; +function resetEmojiPopoverAnchor() { + if (!emojiPickerRef.current) { + return; + } + return emojiPickerRef.current.resetEmojiPopoverAnchor(); +} + +export {emojiPickerRef, showEmojiPicker, hideEmojiPicker, isActiveReportAction, isEmojiPickerVisible, resetEmojiPopoverAnchor};