From 4a44ef25ce41a11bf81ba6de3c8fd9c86ef02d12 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 12 Jan 2024 10:49:10 +0700 Subject: [PATCH] fix: compose box is shown after tapping header and returning back --- src/components/Composer/index.android.tsx | 8 ++++++++ src/components/Composer/index.ios.tsx | 9 ++++++++- src/hooks/useResetComposerFocus.ts | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/hooks/useResetComposerFocus.ts diff --git a/src/components/Composer/index.android.tsx b/src/components/Composer/index.android.tsx index d60a41e0f263..ade1513c8613 100644 --- a/src/components/Composer/index.android.tsx +++ b/src/components/Composer/index.android.tsx @@ -3,6 +3,7 @@ import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import type {TextInput} from 'react-native'; import {StyleSheet} from 'react-native'; import RNTextInput from '@components/RNTextInput'; +import useResetComposerFocus from '@hooks/useResetComposerFocus'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ComposerUtils from '@libs/ComposerUtils'; @@ -28,6 +29,7 @@ function Composer( ref: ForwardedRef, ) { const textInput = useRef(null); + const {isFocused, shouldResetFocus} = useResetComposerFocus(textInput); const styles = useThemeStyles(); const theme = useTheme(); @@ -89,6 +91,12 @@ function Composer( /* eslint-disable-next-line react/jsx-props-no-spreading */ {...props} readOnly={isDisabled} + onBlur={(e) => { + if (!isFocused) { + shouldResetFocus.current = true; // detect the input is blurred when the page is hidden + } + props?.onBlur?.(e); + }} /> ); } diff --git a/src/components/Composer/index.ios.tsx b/src/components/Composer/index.ios.tsx index b1357fef9a46..07736e5ddcba 100644 --- a/src/components/Composer/index.ios.tsx +++ b/src/components/Composer/index.ios.tsx @@ -3,6 +3,7 @@ import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import type {TextInput} from 'react-native'; import {StyleSheet} from 'react-native'; import RNTextInput from '@components/RNTextInput'; +import useResetComposerFocus from '@hooks/useResetComposerFocus'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ComposerUtils from '@libs/ComposerUtils'; @@ -28,7 +29,7 @@ function Composer( ref: ForwardedRef, ) { const textInput = useRef(null); - + const {isFocused, shouldResetFocus} = useResetComposerFocus(textInput); const styles = useThemeStyles(); const theme = useTheme(); @@ -84,6 +85,12 @@ function Composer( /* eslint-disable-next-line react/jsx-props-no-spreading */ {...props} readOnly={isDisabled} + onBlur={(e) => { + if (!isFocused) { + shouldResetFocus.current = true; // detect the input is blurred when the page is hidden + } + props?.onBlur?.(e); + }} /> ); } diff --git a/src/hooks/useResetComposerFocus.ts b/src/hooks/useResetComposerFocus.ts new file mode 100644 index 000000000000..e9f88ed93346 --- /dev/null +++ b/src/hooks/useResetComposerFocus.ts @@ -0,0 +1,19 @@ +import {useIsFocused} from '@react-navigation/native'; +import type {MutableRefObject} from 'react'; +import {useEffect, useRef} from 'react'; +import type {TextInput} from 'react-native'; + +export default function useResetComposerFocus(inputRef: MutableRefObject) { + const isFocused = useIsFocused(); + const shouldResetFocus = useRef(false); + + useEffect(() => { + if (!isFocused || !shouldResetFocus.current) { + return; + } + inputRef.current?.focus(); // focus input again + shouldResetFocus.current = false; + }, [isFocused, inputRef]); + + return {isFocused, shouldResetFocus}; +}