diff --git a/src/NAVIGATORS.ts b/src/NAVIGATORS.ts index eea357322075..0b4a86c99247 100644 --- a/src/NAVIGATORS.ts +++ b/src/NAVIGATORS.ts @@ -10,5 +10,6 @@ export default { ONBOARDING_MODAL_NAVIGATOR: 'OnboardingModalNavigator', FEATURE_TRANING_MODAL_NAVIGATOR: 'FeatureTrainingModalNavigator', WELCOME_VIDEO_MODAL_NAVIGATOR: 'WelcomeVideoModalNavigator', + EXPLANATION_MODAL_NAVIGATOR: 'ExplanationModalNavigator', FULL_SCREEN_NAVIGATOR: 'FullScreenNavigator', } as const; diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 2cb615ae0af8..a15ae54cedea 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -115,6 +115,9 @@ const ONYXKEYS = { /** This NVP contains information about whether the onboarding flow was completed or not */ NVP_ONBOARDING: 'nvp_onboarding', + /** This NVP contains data associated with HybridApp */ + NVP_TRYNEWDOT: 'nvp_tryNewDot', + /** Contains the user preference for the LHN priority mode */ NVP_PRIORITY_MODE: 'nvp_priorityMode', @@ -154,6 +157,8 @@ const ONYXKEYS = { /** Whether the user has dismissed the hold educational interstitial */ NVP_DISMISSED_HOLD_USE_EXPLANATION: 'nvp_dismissedHoldUseExplanation', + /** Whether the user has seen HybridApp explanation modal */ + NVP_SEEN_NEW_USER_MODAL: 'nvp_seen_new_user_modal', /** Store the state of the subscription */ NVP_PRIVATE_SUBSCRIPTION: 'nvp_private_subscription', @@ -631,6 +636,9 @@ type OnyxValuesMapping = { // NVP_ONBOARDING is an array for old users. [ONYXKEYS.NVP_ONBOARDING]: Onboarding | []; + // ONYXKEYS.NVP_TRYNEWDOT is HybridApp onboarding data + [ONYXKEYS.NVP_TRYNEWDOT]: OnyxTypes.TryNewDot; + [ONYXKEYS.ACTIVE_CLIENTS]: string[]; [ONYXKEYS.DEVICE_ID]: string; [ONYXKEYS.IS_SIDEBAR_LOADED]: boolean; @@ -673,6 +681,7 @@ type OnyxValuesMapping = { [ONYXKEYS.NVP_RECENT_WAYPOINTS]: OnyxTypes.RecentWaypoint[]; [ONYXKEYS.NVP_INTRO_SELECTED]: OnyxTypes.IntroSelected; [ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES]: OnyxTypes.LastSelectedDistanceRates; + [ONYXKEYS.NVP_SEEN_NEW_USER_MODAL]: boolean; [ONYXKEYS.PUSH_NOTIFICATIONS_ENABLED]: boolean; [ONYXKEYS.PLAID_DATA]: OnyxTypes.PlaidData; [ONYXKEYS.IS_PLAID_DISABLED]: boolean; diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 5c8cfdcc8a68..c4afee12952e 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -825,6 +825,7 @@ const ROUTES = { ONBOARDING_WORK: 'onboarding/work', ONBOARDING_PURPOSE: 'onboarding/purpose', WELCOME_VIDEO_ROOT: 'onboarding/welcome-video', + EXPLANATION_MODAL_ROOT: 'onboarding/explanation', TRANSACTION_RECEIPT: { route: 'r/:reportID/transaction/:transactionID/receipt', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 5c5fc6c31092..5ef7f2693512 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -362,6 +362,10 @@ const SCREENS = { ROOT: 'Welcome_Video_Root', }, + EXPLANATION_MODAL: { + ROOT: 'Explanation_Modal_Root', + }, + I_KNOW_A_TEACHER: 'I_Know_A_Teacher', INTRO_SCHOOL_PRINCIPAL: 'Intro_School_Principal', I_AM_A_TEACHER: 'I_Am_A_Teacher', diff --git a/src/components/ExplanationModal.tsx b/src/components/ExplanationModal.tsx new file mode 100644 index 000000000000..ef49297078d5 --- /dev/null +++ b/src/components/ExplanationModal.tsx @@ -0,0 +1,41 @@ +import React, {useCallback} from 'react'; +import useLocalize from '@hooks/useLocalize'; +import Navigation from '@libs/Navigation/Navigation'; +import variables from '@styles/variables'; +import * as Welcome from '@userActions/Welcome'; +import CONST from '@src/CONST'; +import ROUTES from '@src/ROUTES'; +import FeatureTrainingModal from './FeatureTrainingModal'; + +function ExplanationModal() { + const {translate} = useLocalize(); + + const onConfirm = useCallback(() => { + Welcome.completeHybridAppOnboarding(); + + // We need to check if standard NewDot onboarding is completed. + Welcome.isOnboardingFlowCompleted({ + onNotCompleted: () => { + setTimeout(() => { + Navigation.isNavigationReady().then(() => { + Navigation.navigate(ROUTES.ONBOARDING_ROOT); + }); + }, variables.welcomeVideoDelay); + }, + }); + }, []); + + return ( + + ); +} + +ExplanationModal.displayName = 'ExplanationModal'; +export default ExplanationModal; diff --git a/src/components/FeatureTrainingModal.tsx b/src/components/FeatureTrainingModal.tsx index 88099b6d078b..221a582af75d 100644 --- a/src/components/FeatureTrainingModal.tsx +++ b/src/components/FeatureTrainingModal.tsx @@ -51,6 +51,9 @@ type FeatureTrainingModalProps = { /** Describe what is showing */ description?: string; + /** Secondary description rendered with additional space */ + secondaryDescription?: string; + /** Whether to show `Don't show me this again` option */ shouldShowDismissModalOption?: boolean; @@ -73,6 +76,7 @@ function FeatureTrainingModal({ videoAspectRatio: videoAspectRatioProp, title = '', description = '', + secondaryDescription = '', shouldShowDismissModalOption = false, confirmText = '', onConfirm = () => {}, @@ -199,6 +203,7 @@ function FeatureTrainingModal({ {title} {description} + {secondaryDescription.length > 0 && {secondaryDescription}} )} {shouldShowDismissModalOption && ( diff --git a/src/components/OnboardingWelcomeVideo.tsx b/src/components/OnboardingWelcomeVideo.tsx index c4378a258d5d..47444d133166 100644 --- a/src/components/OnboardingWelcomeVideo.tsx +++ b/src/components/OnboardingWelcomeVideo.tsx @@ -17,5 +17,4 @@ function OnboardingWelcomeVideo() { } OnboardingWelcomeVideo.displayName = 'OnboardingWelcomeVideo'; - export default OnboardingWelcomeVideo; diff --git a/src/components/TestToolMenu.tsx b/src/components/TestToolMenu.tsx index 2056b4ce4189..15c70f6be5ae 100644 --- a/src/components/TestToolMenu.tsx +++ b/src/components/TestToolMenu.tsx @@ -3,12 +3,17 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; import * as ApiUtils from '@libs/ApiUtils'; +import Navigation from '@libs/Navigation/Navigation'; +import variables from '@styles/variables'; import * as Network from '@userActions/Network'; +import * as Report from '@userActions/Report'; import * as Session from '@userActions/Session'; import * as User from '@userActions/User'; import CONFIG from '@src/CONFIG'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type {Network as NetworkOnyx, User as UserOnyx} from '@src/types/onyx'; import Button from './Button'; import {withNetwork} from './OnyxProvider'; @@ -30,6 +35,7 @@ const USER_DEFAULT: UserOnyx = {shouldUseStagingServer: undefined, isSubscribedT function TestToolMenu({user = USER_DEFAULT, network}: TestToolMenuProps) { const shouldUseStagingServer = user?.shouldUseStagingServer ?? ApiUtils.isUsingStagingApi(); const styles = useThemeStyles(); + const {isSmallScreenWidth} = useWindowDimensions(); const {translate} = useLocalize(); return ( @@ -88,6 +94,24 @@ function TestToolMenu({user = USER_DEFAULT, network}: TestToolMenuProps) { onPress={() => Session.invalidateCredentials()} /> + {/* Navigate to the Explanation Modal. This button is temporary to test Explanation Modal flow without HybridApp native module. */} + +