diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index f5f35fd21025..648bb94bab7c 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -1,10 +1,11 @@ import React, {memo, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import Onyx, {withOnyx} from 'react-native-onyx'; +import Onyx, {useOnyx} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import ActiveGuidesEventListener from '@components/ActiveGuidesEventListener'; import ComposeProviders from '@components/ComposeProviders'; +import {useSession} from '@components/OnyxProvider'; import OptionsListContextProvider from '@components/OptionListContextProvider'; import {SearchContextProvider} from '@components/Search/SearchContext'; import SearchRouterModal from '@components/Search/SearchRouter/SearchRouterModal'; @@ -22,6 +23,7 @@ import Log from '@libs/Log'; import getCurrentUrl from '@libs/Navigation/currentUrl'; import getOnboardingModalScreenOptions from '@libs/Navigation/getOnboardingModalScreenOptions'; import Navigation from '@libs/Navigation/Navigation'; +import shouldOpenOnAdminRoom from '@libs/Navigation/shouldOpenOnAdminRoom'; import type {AuthScreensParamList, CentralPaneName, CentralPaneScreensParamList} from '@libs/Navigation/types'; import NetworkConnection from '@libs/NetworkConnection'; import onyxSubscribe from '@libs/onyxSubscribe'; @@ -67,17 +69,6 @@ import OnboardingModalNavigator from './Navigators/OnboardingModalNavigator'; import RightModalNavigator from './Navigators/RightModalNavigator'; import WelcomeVideoModalNavigator from './Navigators/WelcomeVideoModalNavigator'; -type AuthScreensProps = { - /** Session of currently logged in user */ - session: OnyxEntry; - - /** The report ID of the last opened public room as anonymous user */ - lastOpenedPublicRoomID: OnyxEntry; - - /** The last Onyx update ID was applied to the client */ - initialLastUpdateIDAppliedToClient: OnyxEntry; -}; - const loadReportAttachments = () => require('../../../pages/home/report/ReportAttachments').default; const loadValidateLoginPage = () => require('../../../pages/ValidateLoginPage').default; const loadLogOutPreviousUserPage = () => require('../../../pages/LogOutPreviousUserPage').default; @@ -90,11 +81,6 @@ const loadReportAvatar = () => require('../../../pages/Rep const loadReceiptView = () => require('../../../pages/TransactionReceiptPage').default; const loadWorkspaceJoinUser = () => require('@pages/workspace/WorkspaceJoinUserPage').default; -function shouldOpenOnAdminRoom() { - const url = getCurrentUrl(); - return url ? new URL(url).searchParams.get('openOnAdminRoom') === 'true' : false; -} - function getCentralPaneScreenInitialParams(screenName: CentralPaneName, initialReportID?: string): Partial> { if (screenName === SCREENS.SEARCH.CENTRAL_PANE) { // Generate default query string with buildSearchQueryString without argument. @@ -226,7 +212,7 @@ const modalScreenListenersWithCancelSearch = { }, }; -function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDAppliedToClient}: AuthScreensProps) { +function AuthScreens() { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {shouldUseNarrowLayout, onboardingIsMediumOrLargerScreenWidth, isSmallScreenWidth} = useResponsiveLayout(); @@ -243,6 +229,10 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie const {isOnboardingCompleted} = useOnboardingFlowRouter(); let initialReportID: string | undefined; const isInitialRender = useRef(true); + const session = useSession(); + const [lastOpenedPublicRoomID] = useOnyx(ONYXKEYS.LAST_OPENED_PUBLIC_ROOM_ID); + const [initialLastUpdateIDAppliedToClient] = useOnyx(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT); + if (isInitialRender.current) { Timing.start(CONST.TIMING.HOMEPAGE_INITIAL_RENDER); @@ -602,14 +592,4 @@ AuthScreens.displayName = 'AuthScreens'; const AuthScreensMemoized = memo(AuthScreens, () => true); -export default withOnyx({ - session: { - key: ONYXKEYS.SESSION, - }, - lastOpenedPublicRoomID: { - key: ONYXKEYS.LAST_OPENED_PUBLIC_ROOM_ID, - }, - initialLastUpdateIDAppliedToClient: { - key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, - }, -})(AuthScreensMemoized); +export default AuthScreensMemoized; diff --git a/src/libs/Navigation/shouldOpenOnAdminRoom.ts b/src/libs/Navigation/shouldOpenOnAdminRoom.ts new file mode 100644 index 000000000000..a593e8c22768 --- /dev/null +++ b/src/libs/Navigation/shouldOpenOnAdminRoom.ts @@ -0,0 +1,6 @@ +import getCurrentUrl from './currentUrl'; + +export default function shouldOpenOnAdminRoom() { + const url = getCurrentUrl(); + return url ? new URL(url).searchParams.get('openOnAdminRoom') === 'true' : false; +} diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 3d016fab713d..e9657e775db2 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -65,7 +65,6 @@ import * as CurrencyUtils from './CurrencyUtils'; import DateUtils from './DateUtils'; import {hasValidDraftComment} from './DraftCommentUtils'; import getAttachmentDetails from './fileDownload/getAttachmentDetails'; -import getIsSmallScreenWidth from './getIsSmallScreenWidth'; import isReportMessageAttachment from './isReportMessageAttachment'; import localeCompare from './LocaleCompare'; import * as LocalePhoneNumber from './LocalePhoneNumber'; @@ -1360,12 +1359,6 @@ function findLastAccessedReport(ignoreDomainRooms: boolean, openOnAdminRoom = fa }); } - // if the user hasn't completed the onboarding flow, whether the user should be in the concierge chat or system chat - // should be consistent with what chat the user will land after onboarding flow - if (!getIsSmallScreenWidth() && !Array.isArray(onboarding) && !onboarding?.hasCompletedGuidedSetupFlow) { - return reportsValues.find(isChatUsedForOnboarding); - } - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const shouldFilter = excludeReportID || ignoreDomainRooms; if (shouldFilter) { diff --git a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx index a1ba324077db..41f8fa394ed9 100644 --- a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx +++ b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx @@ -10,13 +10,17 @@ import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; +import useActiveWorkspace from '@hooks/useActiveWorkspace'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; +import usePermissions from '@hooks/usePermissions'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; +import shouldOpenOnAdminRoom from '@libs/Navigation/shouldOpenOnAdminRoom'; +import * as ReportUtils from '@libs/ReportUtils'; import * as ValidationUtils from '@libs/ValidationUtils'; import * as PersonalDetails from '@userActions/PersonalDetails'; import * as Report from '@userActions/Report'; @@ -24,19 +28,22 @@ import * as Welcome from '@userActions/Welcome'; import * as OnboardingFlow from '@userActions/Welcome/OnboardingFlow'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import INPUT_IDS from '@src/types/form/DisplayNameForm'; import type {BaseOnboardingPersonalDetailsProps} from './types'; -function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNativeStyles, route}: BaseOnboardingPersonalDetailsProps) { +function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNativeStyles}: BaseOnboardingPersonalDetailsProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); const [onboardingAdminsChatReportID] = useOnyx(ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); - const {shouldUseNarrowLayout, isSmallScreenWidth, onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); + const {isSmallScreenWidth, onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); const {inputCallbackRef} = useAutoFocusInput(); const [shouldValidateOnChange, setShouldValidateOnChange] = useState(false); const {isOffline} = useNetwork(); + const {canUseDefaultRooms} = usePermissions(); + const {activeWorkspaceID} = useActiveWorkspace(); useEffect(() => { Welcome.setOnboardingErrorMessage(''); @@ -69,13 +76,20 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat Navigation.dismissModal(); - // Only navigate to concierge chat when central pane is visible - // Otherwise stay on the chats screen. - if (!shouldUseNarrowLayout && !route.params?.backTo) { - Report.navigateToConciergeChat(); + // When hasCompletedGuidedSetupFlow is true, OnboardingModalNavigator in AuthScreen is removed from the navigation stack. + // On small screens, this removal redirects navigation to HOME. Dismissing the modal doesn't work properly, + // so we need to specifically navigate to the last accessed report. + if (!isSmallScreenWidth) { + return; + } + const lastAccessedReportID = ReportUtils.findLastAccessedReport(!canUseDefaultRooms, shouldOpenOnAdminRoom(), activeWorkspaceID)?.reportID; + if (!lastAccessedReportID) { + return; } + const lastAccessedReportRoute = ROUTES.REPORT_WITH_ID.getRoute(lastAccessedReportID ?? '-1'); + Navigation.navigate(lastAccessedReportRoute); }, - [onboardingPurposeSelected, onboardingAdminsChatReportID, onboardingPolicyID, shouldUseNarrowLayout, route.params?.backTo], + [onboardingPurposeSelected, onboardingAdminsChatReportID, onboardingPolicyID, activeWorkspaceID, canUseDefaultRooms, isSmallScreenWidth], ); const validate = (values: FormOnyxValues<'onboardingPersonalDetailsForm'>) => { diff --git a/src/pages/signin/SignInModal.tsx b/src/pages/signin/SignInModal.tsx index bad93b29f8af..0c8373babae5 100644 --- a/src/pages/signin/SignInModal.tsx +++ b/src/pages/signin/SignInModal.tsx @@ -1,36 +1,35 @@ import React, {useEffect, useRef} from 'react'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import {useSession} from '@components/OnyxProvider'; import ScreenWrapper from '@components/ScreenWrapper'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import Navigation from '@libs/Navigation/Navigation'; +import {waitForIdle} from '@libs/Network/SequentialQueue'; import * as App from '@userActions/App'; import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; import SCREENS from '@src/SCREENS'; -import type {Session} from '@src/types/onyx'; import SignInPage from './SignInPage'; import type {SignInPageRef} from './SignInPage'; -type SignInModalOnyxProps = { - session: OnyxEntry; -}; - -type SignInModalProps = SignInModalOnyxProps; - -function SignInModal({session}: SignInModalProps) { +function SignInModal() { const theme = useTheme(); const StyleUtils = useStyleUtils(); const siginPageRef = useRef(null); + const session = useSession(); useEffect(() => { const isAnonymousUser = session?.authTokenType === CONST.AUTH_TOKEN_TYPES.ANONYMOUS; if (!isAnonymousUser) { // Signing in RHP is only for anonymous users Navigation.isNavigationReady().then(() => Navigation.dismissModal()); - App.openApp(); + + // To prevent deadlock when OpenReport and OpenApp overlap, wait for the queue to be idle before calling openApp. + // This ensures that any communication gaps between the client and server during OpenReport processing do not cause the queue to pause, + // which would prevent us from processing or clearing the queue. + waitForIdle().then(() => { + App.openApp(); + }); } }, [session?.authTokenType]); @@ -61,6 +60,4 @@ function SignInModal({session}: SignInModalProps) { SignInModal.displayName = 'SignInModal'; -export default withOnyx({ - session: {key: ONYXKEYS.SESSION}, -})(SignInModal); +export default SignInModal;