From 1748ca3f9e70753f0cd3fc5a1d27d96b4f3dae18 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 25 Oct 2023 18:35:30 +0700 Subject: [PATCH 1/4] fix: 24473 Deepliink - Keyboard displayed upon splash screen --- src/Expensify.js | 22 +++++++++++++++---- src/hooks/useAutoFocusInput.js | 9 +++++--- src/pages/NewChatPage.js | 7 +++--- src/pages/tasks/TaskAssigneeSelectorModal.js | 8 +++---- .../TaskShareDestinationSelectorModal.js | 8 +++---- src/pages/workspace/WorkspaceNewRoomPage.js | 11 ++++------ 6 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/Expensify.js b/src/Expensify.js index 6010824cf275..a7f7601c3368 100644 --- a/src/Expensify.js +++ b/src/Expensify.js @@ -91,6 +91,8 @@ const defaultProps = { isCheckingPublicRoom: true, }; +const SplashScreenHiddenContext = React.createContext({}); + function Expensify(props) { const appStateChangeListener = useRef(null); const [isNavigationReady, setIsNavigationReady] = useState(false); @@ -106,6 +108,14 @@ function Expensify(props) { }, [props.isCheckingPublicRoom]); const isAuthenticated = useMemo(() => Boolean(lodashGet(props.session, 'authToken', null)), [props.session]); + + const contextValue = useMemo( + () => ({ + isSplashHidden, + }), + [isSplashHidden], + ); + const shouldInit = isNavigationReady && (!isAuthenticated || props.isSidebarLoaded) && hasAttemptedToOpenPublicRoom; const shouldHideSplash = shouldInit && !isSplashHidden; @@ -217,10 +227,12 @@ function Expensify(props) { {hasAttemptedToOpenPublicRoom && ( - + + + )} {shouldHideSplash && } @@ -252,3 +264,5 @@ export default compose( }, }), )(Expensify); + +export {SplashScreenHiddenContext}; diff --git a/src/hooks/useAutoFocusInput.js b/src/hooks/useAutoFocusInput.js index 6611f867f210..5ca4995d8ea8 100644 --- a/src/hooks/useAutoFocusInput.js +++ b/src/hooks/useAutoFocusInput.js @@ -1,20 +1,23 @@ import {useFocusEffect} from '@react-navigation/native'; -import {useState, useEffect, useRef, useCallback} from 'react'; +import {useState, useEffect, useRef, useCallback, useContext} from 'react'; import CONST from '../CONST'; +import * as Expensify from '../Expensify'; export default function useAutoFocusInput() { const [isInputInitialized, setIsInputInitialized] = useState(false); const [isScreenTransitionEnded, setIsScreenTransitionEnded] = useState(false); + const {isSplashHidden} = useContext(Expensify.SplashScreenHiddenContext); + const inputRef = useRef(null); const focusTimeoutRef = useRef(null); useEffect(() => { - if (!isScreenTransitionEnded || !isInputInitialized || !inputRef.current) { + if (!isScreenTransitionEnded || !isInputInitialized || !inputRef.current || !isSplashHidden) { return; } inputRef.current.focus(); - }, [isScreenTransitionEnded, isInputInitialized]); + }, [isScreenTransitionEnded, isInputInitialized, isSplashHidden]); useFocusEffect( useCallback(() => { diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index 381564b82600..208e6fdb6c84 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -21,7 +21,7 @@ import personalDetailsPropType from './personalDetailsPropType'; import reportPropTypes from './reportPropTypes'; import variables from '../styles/variables'; import useNetwork from '../hooks/useNetwork'; -import useDelayedInputFocus from '../hooks/useDelayedInputFocus'; +import useAutoFocusInput from '../hooks/useAutoFocusInput'; const propTypes = { /** Beta features list */ @@ -51,7 +51,6 @@ const defaultProps = { const excludedGroupEmails = _.without(CONST.EXPENSIFY_EMAILS, CONST.EMAIL.CONCIERGE); function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, isSearchingForReports}) { - const optionSelectorRef = React.createRef(null); const [searchTerm, setSearchTerm] = useState(''); const [filteredRecentReports, setFilteredRecentReports] = useState([]); const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); @@ -213,7 +212,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i setSearchTerm(text); }, []); - useDelayedInputFocus(optionSelectorRef, 600); + const {inputCallbackRef} = useAutoFocusInput(); return ( 0 ? safeAreaPaddingBottomStyle : {}]}> { const {recentReports, personalDetails, userToInvite, currentUserOption} = OptionsListUtils.getFilteredOptions( @@ -208,7 +209,6 @@ function TaskAssigneeSelectorModal(props) { return ( optionRef.current && optionRef.current.textInput.focus()} testID={TaskAssigneeSelectorModal.displayName} > {({didScreenTransitionEnd, safeAreaPaddingBottomStyle}) => ( @@ -229,7 +229,7 @@ function TaskAssigneeSelectorModal(props) { textInputLabel={props.translate('optionsSelector.nameEmailOrPhoneNumber')} safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle} autoFocus={false} - ref={optionRef} + ref={inputCallbackRef} /> diff --git a/src/pages/tasks/TaskShareDestinationSelectorModal.js b/src/pages/tasks/TaskShareDestinationSelectorModal.js index 2fc8f0eab014..75fcb2ff2275 100644 --- a/src/pages/tasks/TaskShareDestinationSelectorModal.js +++ b/src/pages/tasks/TaskShareDestinationSelectorModal.js @@ -1,5 +1,5 @@ /* eslint-disable es/no-optional-chaining */ -import React, {useState, useEffect, useMemo, useCallback, useRef} from 'react'; +import React, {useState, useEffect, useMemo, useCallback} from 'react'; import _ from 'underscore'; import {View} from 'react-native'; import PropTypes from 'prop-types'; @@ -19,6 +19,7 @@ import reportPropTypes from '../reportPropTypes'; import * as Task from '../../libs/actions/Task'; import * as ReportUtils from '../../libs/ReportUtils'; import ROUTES from '../../ROUTES'; +import useAutoFocusInput from '../../hooks/useAutoFocusInput'; const propTypes = { /* Onyx Props */ @@ -46,7 +47,7 @@ function TaskShareDestinationSelectorModal(props) { const [headerMessage, setHeaderMessage] = useState(''); const [filteredRecentReports, setFilteredRecentReports] = useState([]); - const optionRef = useRef(); + const {inputCallbackRef} = useAutoFocusInput(); const filteredReports = useMemo(() => { const reports = {}; @@ -115,7 +116,6 @@ function TaskShareDestinationSelectorModal(props) { return ( optionRef.current && optionRef.current.textInput.focus()} testID={TaskShareDestinationSelectorModal.displayName} > {({didScreenTransitionEnd, safeAreaPaddingBottomStyle}) => ( @@ -138,7 +138,7 @@ function TaskShareDestinationSelectorModal(props) { textInputLabel={props.translate('optionsSelector.nameEmailOrPhoneNumber')} safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle} autoFocus={false} - ref={optionRef} + ref={inputCallbackRef} /> diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index 80c1a13731bd..b944258dacc5 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -1,4 +1,4 @@ -import React, {useState, useEffect, useCallback, useMemo, useRef} from 'react'; +import React, {useState, useEffect, useCallback, useMemo} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import {withOnyx} from 'react-native-onyx'; @@ -25,8 +25,8 @@ import policyMemberPropType from '../policyMemberPropType'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import compose from '../../libs/compose'; import variables from '../../styles/variables'; -import useDelayedInputFocus from '../../hooks/useDelayedInputFocus'; import ValuePicker from '../../components/ValuePicker'; +import useAutoFocusInput from '../../hooks/useAutoFocusInput'; const propTypes = { /** All reports shared with the user */ @@ -156,10 +156,7 @@ function WorkspaceNewRoomPage(props) { [translate], ); - const roomNameInputRef = useRef(null); - - // use a 600ms delay for delayed focus on the room name input field so that it works consistently on native iOS / Android - useDelayedInputFocus(roomNameInputRef, 600); + const {inputCallbackRef} = useAutoFocusInput(); return ( (roomNameInputRef.current = el)} + ref={inputCallbackRef} inputID="roomName" isFocused={props.isFocused} shouldDelayFocus From 4d7eebfd2fc2b40b91e8dee7b76ccb6605c45bd1 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 25 Oct 2023 22:15:25 +0700 Subject: [PATCH 2/4] fix: disable autoFocus --- src/pages/NewChatPage.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index 208e6fdb6c84..f6c912903756 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -255,6 +255,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')} safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle} isLoadingNewOptions={isSearchingForReports} + autoFocus={false} /> From fb1a21c44c7c1bb153b965bfb70a16e03d0e6316 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 3 Nov 2023 09:47:23 +0700 Subject: [PATCH 3/4] fix: lint --- src/pages/NewChatPage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index 2702ab3dfafc..6373d9eb5276 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -9,7 +9,6 @@ import OptionsSelector from '@components/OptionsSelector'; import ScreenWrapper from '@components/ScreenWrapper'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; -import useDelayedInputFocus from '@hooks/useDelayedInputFocus'; import useNetwork from '@hooks/useNetwork'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; @@ -22,9 +21,9 @@ import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import useAutoFocusInput from '@hooks/useAutoFocusInput'; import personalDetailsPropType from './personalDetailsPropType'; import reportPropTypes from './reportPropTypes'; -import useAutoFocusInput from '@hooks/useAutoFocusInput'; const propTypes = { /** Beta features list */ From 1f3eca319dd5565504784fd462e42f3794b34a54 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 3 Nov 2023 10:07:17 +0700 Subject: [PATCH 4/4] prettier fix --- src/hooks/useAutoFocusInput.js | 2 +- src/pages/NewChatPage.js | 2 +- src/pages/tasks/TaskAssigneeSelectorModal.js | 2 +- src/pages/tasks/TaskShareDestinationSelectorModal.js | 2 +- src/pages/workspace/WorkspaceNewRoomPage.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hooks/useAutoFocusInput.js b/src/hooks/useAutoFocusInput.js index c793126ca278..af3084669699 100644 --- a/src/hooks/useAutoFocusInput.js +++ b/src/hooks/useAutoFocusInput.js @@ -1,5 +1,5 @@ import {useFocusEffect} from '@react-navigation/native'; -import {useState, useEffect, useRef, useCallback, useContext} from 'react'; +import {useCallback, useContext, useEffect, useRef, useState} from 'react'; import CONST from '@src/CONST'; import * as Expensify from '@src/Expensify'; diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index 6373d9eb5276..22af82041f7b 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -9,6 +9,7 @@ import OptionsSelector from '@components/OptionsSelector'; import ScreenWrapper from '@components/ScreenWrapper'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; +import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useNetwork from '@hooks/useNetwork'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; @@ -21,7 +22,6 @@ import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import useAutoFocusInput from '@hooks/useAutoFocusInput'; import personalDetailsPropType from './personalDetailsPropType'; import reportPropTypes from './reportPropTypes'; diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.js b/src/pages/tasks/TaskAssigneeSelectorModal.js index 61ce0ec2b8dc..131755e02dfa 100644 --- a/src/pages/tasks/TaskAssigneeSelectorModal.js +++ b/src/pages/tasks/TaskAssigneeSelectorModal.js @@ -11,6 +11,7 @@ import OptionsSelector from '@components/OptionsSelector'; import ScreenWrapper from '@components/ScreenWrapper'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useAutoFocusInput from '@hooks/useAutoFocusInput'; import compose from '@libs/compose'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; @@ -22,7 +23,6 @@ import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import useAutoFocusInput from '@hooks/useAutoFocusInput'; const propTypes = { /** Beta features list */ diff --git a/src/pages/tasks/TaskShareDestinationSelectorModal.js b/src/pages/tasks/TaskShareDestinationSelectorModal.js index f8cf602505dd..e3f992ea9b5a 100644 --- a/src/pages/tasks/TaskShareDestinationSelectorModal.js +++ b/src/pages/tasks/TaskShareDestinationSelectorModal.js @@ -8,6 +8,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import OptionsSelector from '@components/OptionsSelector'; import ScreenWrapper from '@components/ScreenWrapper'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useNetwork from '@hooks/useNetwork'; import * as Report from '@libs/actions/Report'; import compose from '@libs/compose'; @@ -21,7 +22,6 @@ import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import useAutoFocusInput from '@hooks/useAutoFocusInput'; const propTypes = { /* Onyx Props */ diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index 61b9ff6feacb..ad4bd651fb01 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -13,6 +13,7 @@ import Text from '@components/Text'; import TextInput from '@components/TextInput'; import ValuePicker from '@components/ValuePicker'; import withNavigationFocus from '@components/withNavigationFocus'; +import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useWindowDimensions from '@hooks/useWindowDimensions'; @@ -29,7 +30,6 @@ import * as App from '@userActions/App'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import useAutoFocusInput from '@hooks/useAutoFocusInput'; const propTypes = { /** All reports shared with the user */