From 7ffdee96336fc9b9b2964bcd94d5a19c14f647e9 Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Mon, 16 Dec 2024 15:23:37 -0800 Subject: [PATCH 1/6] Add a helper func to prevent showing modal for invitees --- src/libs/Navigation/NavigationRoot.tsx | 6 +++++- src/libs/onboardingSelectors.ts | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index d6e021d014b3..435e11611310 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -100,6 +100,10 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh selector: hasCompletedGuidedSetupFlowSelector, }); + const [wasInvited = false] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, { + selector: wasInvitedToNewDot, + }); + const initialState = useMemo(() => { if (!user || user.isFromPublicDomain) { return; @@ -107,7 +111,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh // If the user haven't completed the flow, we want to always redirect them to the onboarding flow. // We also make sure that the user is authenticated. - if (!NativeModules.HybridAppModule && !isOnboardingCompleted && authenticated && !shouldShowRequire2FAModal) { + if (!NativeModules.HybridAppModule && !isOnboardingCompleted && !wasInvited && authenticated && !shouldShowRequire2FAModal) { const {adaptedState} = getAdaptedStateFromPath(getOnboardingInitialPath(isPrivateDomain), linkingConfig.config); return adaptedState; } diff --git a/src/libs/onboardingSelectors.ts b/src/libs/onboardingSelectors.ts index 91185e5c67bf..b888052c186b 100644 --- a/src/libs/onboardingSelectors.ts +++ b/src/libs/onboardingSelectors.ts @@ -56,4 +56,8 @@ function hasSeenTourSelector(onboarding: OnyxValue): boolean | undefined { + return introSelected?.inviteType !== undefined; +} + +export {hasCompletedGuidedSetupFlowSelector, tryNewDotOnyxSelector, hasSeenTourSelector, wasInvitedToNewDot}; From bfdf4119645f6b235cfde48a88d69a13949429f6 Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Mon, 16 Dec 2024 15:29:14 -0800 Subject: [PATCH 2/6] Fix the names of things --- src/libs/Navigation/NavigationRoot.tsx | 8 ++++---- src/libs/onboardingSelectors.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 435e11611310..8a6169b215d0 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -13,7 +13,7 @@ import Firebase from '@libs/Firebase'; import {FSPage} from '@libs/Fullstory'; import Log from '@libs/Log'; import * as LoginUtils from '@libs/LoginUtils'; -import {hasCompletedGuidedSetupFlowSelector} from '@libs/onboardingSelectors'; +import {hasCompletedGuidedSetupFlowSelector, wasInvitedToNewDotSelector} from '@libs/onboardingSelectors'; import {getPathFromURL} from '@libs/Url'; import {updateLastVisitedPath} from '@userActions/App'; import {updateOnboardingLastVisitedPath} from '@userActions/Welcome'; @@ -100,8 +100,8 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh selector: hasCompletedGuidedSetupFlowSelector, }); - const [wasInvited = false] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, { - selector: wasInvitedToNewDot, + const [wasInvitedToNewDot = false] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, { + selector: wasInvitedToNewDotSelector, }); const initialState = useMemo(() => { @@ -111,7 +111,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh // If the user haven't completed the flow, we want to always redirect them to the onboarding flow. // We also make sure that the user is authenticated. - if (!NativeModules.HybridAppModule && !isOnboardingCompleted && !wasInvited && authenticated && !shouldShowRequire2FAModal) { + if (!NativeModules.HybridAppModule && !isOnboardingCompleted && !wasInvitedToNewDot && authenticated && !shouldShowRequire2FAModal) { const {adaptedState} = getAdaptedStateFromPath(getOnboardingInitialPath(isPrivateDomain), linkingConfig.config); return adaptedState; } diff --git a/src/libs/onboardingSelectors.ts b/src/libs/onboardingSelectors.ts index b888052c186b..c14b13008bc1 100644 --- a/src/libs/onboardingSelectors.ts +++ b/src/libs/onboardingSelectors.ts @@ -56,8 +56,8 @@ function hasSeenTourSelector(onboarding: OnyxValue): boolean | undefined { +function wasInvitedToNewDotSelector(introSelected: OnyxValue): boolean | undefined { return introSelected?.inviteType !== undefined; } -export {hasCompletedGuidedSetupFlowSelector, tryNewDotOnyxSelector, hasSeenTourSelector, wasInvitedToNewDot}; +export {hasCompletedGuidedSetupFlowSelector, tryNewDotOnyxSelector, hasSeenTourSelector, wasInvitedToNewDotSelector}; From 29e49bf8aa0a656edf14c38d0efde18d5b059f7a Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Mon, 16 Dec 2024 15:33:13 -0800 Subject: [PATCH 3/6] Add some documentation for the new selector --- src/libs/onboardingSelectors.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libs/onboardingSelectors.ts b/src/libs/onboardingSelectors.ts index c14b13008bc1..bb4faa725c7e 100644 --- a/src/libs/onboardingSelectors.ts +++ b/src/libs/onboardingSelectors.ts @@ -56,6 +56,13 @@ function hasSeenTourSelector(onboarding: OnyxValue): boolean | undefined { return introSelected?.inviteType !== undefined; } From 80b06403c42a8910ffea3a621dfac2151709870e Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Wed, 18 Dec 2024 16:54:12 -0800 Subject: [PATCH 4/6] Do not show modal if user has non-personal policy --- src/ONYXKEYS.ts | 4 ++++ src/libs/Navigation/NavigationRoot.tsx | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index bd77ed7e8af4..a7f72abe419b 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -153,6 +153,9 @@ const ONYXKEYS = { /** This NVP contains the choice that the user made on the engagement modal */ NVP_INTRO_SELECTED: 'nvp_introSelected', + /** Whether the user is a member of a policy other than their personal */ + NVP_HAS_NON_PERSONAL_POLICY: 'nvp_hasNonPersonalPolicy', + /** This NVP contains the active policyID */ NVP_ACTIVE_POLICY_ID: 'nvp_expensify_activePolicyID', @@ -931,6 +934,7 @@ type OnyxValuesMapping = { [ONYXKEYS.LAST_EXPORT_METHOD]: OnyxTypes.LastExportMethod; [ONYXKEYS.NVP_RECENT_WAYPOINTS]: OnyxTypes.RecentWaypoint[]; [ONYXKEYS.NVP_INTRO_SELECTED]: OnyxTypes.IntroSelected; + [ONYXKEYS.NVP_HAS_NON_PERSONAL_POLICY]: boolean; [ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES]: OnyxTypes.LastSelectedDistanceRates; [ONYXKEYS.NVP_SEEN_NEW_USER_MODAL]: boolean; [ONYXKEYS.PUSH_NOTIFICATIONS_ENABLED]: boolean; diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 8a6169b215d0..5e727ceaf9aa 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -99,10 +99,10 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh const [isOnboardingCompleted = true] = useOnyx(ONYXKEYS.NVP_ONBOARDING, { selector: hasCompletedGuidedSetupFlowSelector, }); - const [wasInvitedToNewDot = false] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, { selector: wasInvitedToNewDotSelector, }); + const [hasNonPersonalPolicy] = useOnyx(ONYXKEYS.NVP_HAS_NON_PERSONAL_POLICY); const initialState = useMemo(() => { if (!user || user.isFromPublicDomain) { @@ -111,7 +111,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh // If the user haven't completed the flow, we want to always redirect them to the onboarding flow. // We also make sure that the user is authenticated. - if (!NativeModules.HybridAppModule && !isOnboardingCompleted && !wasInvitedToNewDot && authenticated && !shouldShowRequire2FAModal) { + if (!NativeModules.HybridAppModule && !hasNonPersonalPolicy && !isOnboardingCompleted && !wasInvitedToNewDot && authenticated && !shouldShowRequire2FAModal) { const {adaptedState} = getAdaptedStateFromPath(getOnboardingInitialPath(isPrivateDomain), linkingConfig.config); return adaptedState; } From 94d76ceb35e5aab2d89daaa5aee82534cbbb3acb Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Mon, 30 Dec 2024 14:40:54 -0800 Subject: [PATCH 5/6] Remove NPV prefix from hasNonPersonalPolicy since it isn't an NVP --- src/ONYXKEYS.ts | 8 ++++---- src/libs/Navigation/NavigationRoot.tsx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 4e4b74b4225e..99c3fd39b54d 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -115,6 +115,9 @@ const ONYXKEYS = { STASHED_SESSION: 'stashedSession', BETAS: 'betas', + /** Whether the user is a member of a policy other than their personal */ + HAS_NON_PERSONAL_POLICY: 'hasNonPersonalPolicy', + /** NVP keys */ /** This NVP contains list of at most 5 recent attendees */ @@ -153,9 +156,6 @@ const ONYXKEYS = { /** This NVP contains the choice that the user made on the engagement modal */ NVP_INTRO_SELECTED: 'nvp_introSelected', - /** Whether the user is a member of a policy other than their personal */ - NVP_HAS_NON_PERSONAL_POLICY: 'nvp_hasNonPersonalPolicy', - /** This NVP contains the active policyID */ NVP_ACTIVE_POLICY_ID: 'nvp_expensify_activePolicyID', @@ -939,7 +939,7 @@ type OnyxValuesMapping = { [ONYXKEYS.LAST_EXPORT_METHOD]: OnyxTypes.LastExportMethod; [ONYXKEYS.NVP_RECENT_WAYPOINTS]: OnyxTypes.RecentWaypoint[]; [ONYXKEYS.NVP_INTRO_SELECTED]: OnyxTypes.IntroSelected; - [ONYXKEYS.NVP_HAS_NON_PERSONAL_POLICY]: boolean; + [ONYXKEYS.HAS_NON_PERSONAL_POLICY]: boolean; [ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES]: OnyxTypes.LastSelectedDistanceRates; [ONYXKEYS.NVP_SEEN_NEW_USER_MODAL]: boolean; [ONYXKEYS.PUSH_NOTIFICATIONS_ENABLED]: boolean; diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 4f5bf16ce67a..aefaea757a3d 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -12,7 +12,7 @@ import useThemePreference from '@hooks/useThemePreference'; import Firebase from '@libs/Firebase'; import {FSPage} from '@libs/Fullstory'; import Log from '@libs/Log'; -import {hasCompletedGuidedSetupFlowSelector} from '@libs/onboardingSelectors'; +import {hasCompletedGuidedSetupFlowSelector, wasInvitedToNewDotSelector} from '@libs/onboardingSelectors'; import {getPathFromURL} from '@libs/Url'; import {updateLastVisitedPath} from '@userActions/App'; import * as Session from '@userActions/Session'; @@ -101,7 +101,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh const [wasInvitedToNewDot = false] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, { selector: wasInvitedToNewDotSelector, }); - const [hasNonPersonalPolicy] = useOnyx(ONYXKEYS.NVP_HAS_NON_PERSONAL_POLICY); + const [hasNonPersonalPolicy] = useOnyx(ONYXKEYS.HAS_NON_PERSONAL_POLICY); const initialState = useMemo(() => { if (!user || user.isFromPublicDomain) { From ba368b40f71f011ff63aeaba07af6486f5c19b28 Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Thu, 2 Jan 2025 12:23:36 -0800 Subject: [PATCH 6/6] Update doc comment --- src/libs/Navigation/NavigationRoot.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index aefaea757a3d..c044422a7cc7 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -109,7 +109,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh } // If the user haven't completed the flow, we want to always redirect them to the onboarding flow. - // We also make sure that the user is authenticated. + // We also make sure that the user is authenticated, isn't part of a group workspace, & wasn't invited to NewDot. if (!NativeModules.HybridAppModule && !hasNonPersonalPolicy && !isOnboardingCompleted && !wasInvitedToNewDot && authenticated && !shouldShowRequire2FAModal) { const {adaptedState} = getAdaptedStateFromPath(getOnboardingInitialPath(isPrivateDomain), linkingConfig.config); return adaptedState;