Skip to content

Commit

Permalink
Adjust onboarding to BE changes
Browse files Browse the repository at this point in the history
  • Loading branch information
filip-solecki committed Apr 20, 2024
1 parent 8ecab8f commit c5d61ae
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 43 deletions.
5 changes: 5 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {ValueOf} from 'type-fest';
import type CONST from './CONST';
import type * as FormTypes from './types/form';
import type * as OnyxTypes from './types/onyx';
import type Onboarding from './types/onyx/Onboarding';
import type AssertTypesEqual from './types/utils/AssertTypesEqual';
import type DeepValueOf from './types/utils/DeepValueOf';

Expand Down Expand Up @@ -114,6 +115,9 @@ const ONYXKEYS = {
/** Boolean flag only true when first set */
NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER: 'nvp_isFirstTimeNewExpensifyUser',

/** This NVP contains the choice that the user made on the engagement modal */
NVP_ONBOARDING: 'nvp_onboarding',

/** Contains the user preference for the LHN priority mode */
NVP_PRIORITY_MODE: 'nvp_priorityMode',

Expand Down Expand Up @@ -562,6 +566,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.ACCOUNT]: OnyxTypes.Account;
[ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID]: string;
[ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER]: boolean;
[ONYXKEYS.NVP_ONBOARDING]: Onboarding | [];
[ONYXKEYS.ACTIVE_CLIENTS]: string[];
[ONYXKEYS.DEVICE_ID]: string;
[ONYXKEYS.IS_SIDEBAR_LOADED]: boolean;
Expand Down
2 changes: 2 additions & 0 deletions src/libs/actions/Session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import * as Device from '@userActions/Device';
import * as PriorityMode from '@userActions/PriorityMode';
import redirectToSignIn from '@userActions/SignInRedirect';
import Timing from '@userActions/Timing';
import * as Welcome from '@userActions/Welcome';
import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -642,6 +643,7 @@ function resetHomeRouteParams() {
function cleanupSession() {
Pusher.disconnect();
Timers.clearAll();
Welcome.resetAllChecks();
PriorityMode.resetHasReadRequiredDataFromStorage();
MainQueue.clear();
HttpUtils.cancelPendingRequests();
Expand Down
71 changes: 28 additions & 43 deletions src/libs/actions/Welcome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,44 @@ import type {OnyxCollection} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import type {SelectedPurposeType} from '@pages/OnboardingPurpose/BaseOnboardingPurpose';
import ONYXKEYS from '@src/ONYXKEYS';
import type Onboarding from '@src/types/onyx/Onboarding';
import type OnyxPolicy from '@src/types/onyx/Policy';
import type {EmptyObject} from '@src/types/utils/EmptyObject';

let hasSelectedPurpose: boolean | undefined;
let hasProvidedPersonalDetails: boolean | undefined;
let isFirstTimeNewExpensifyUser: boolean | undefined;
let onboarding: Onboarding | [] | undefined;
let hasDismissedModal: boolean | undefined;
let isLoadingReportData = true;

type DetermineOnboardingStatusProps = {
onAble?: () => void;
onNotAble?: () => void;
};

type HasCompletedOnboardingFlowProps = {
onCompleted?: () => void;
onNotCompleted?: () => void;
};

let resolveIsReadyPromise: (value?: Promise<void>) => void | undefined;
const isServerDataReadyPromise = new Promise<void>((resolve) => {
let isServerDataReadyPromise = new Promise<void>((resolve) => {
resolveIsReadyPromise = resolve;
});

let resolveOnboardingFlowStatus: (value?: Promise<void>) => void | undefined;
const isOnboardingFlowStatusKnownPromise = new Promise<void>((resolve) => {
let isOnboardingFlowStatusKnownPromise = new Promise<void>((resolve) => {
resolveOnboardingFlowStatus = resolve;
});

function onServerDataReady(): Promise<void> {
return isServerDataReadyPromise;
}

/**
* Checks if Onyx keys required to determine the
* onboarding flow status have been loaded (namely,
* are not undefined).
*/
function isAbleToDetermineOnboardingStatus({onAble, onNotAble}: DetermineOnboardingStatusProps) {
const hasRequiredOnyxKeysBeenLoaded = [hasProvidedPersonalDetails, hasSelectedPurpose].every((value) => value !== undefined);

if (hasRequiredOnyxKeysBeenLoaded) {
onAble?.();
} else {
onNotAble?.();
}
}

/**
* A promise returning the onboarding flow status.
* Returns true if user has completed the onboarding
* flow, false otherwise.
*/
function isOnboardingFlowCompleted({onCompleted, onNotCompleted}: HasCompletedOnboardingFlowProps) {
isOnboardingFlowStatusKnownPromise.then(() => {
if (!isFirstTimeNewExpensifyUser) {
if (Array.isArray(onboarding) || onboarding?.hasCompletedGuidedSetupFlow === undefined) {
return;
}

const onboardingFlowCompleted = hasProvidedPersonalDetails && hasSelectedPurpose;

if (onboardingFlowCompleted) {
if (onboarding?.hasCompletedGuidedSetupFlow) {
onCompleted?.();
} else {
// This key is only updated when we call ReconnectApp, setting it to false now allows the user to navigate normally instead of always redirecting to the workspace chat
Onyx.set(ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER, false);

onNotCompleted?.();
}
});
Expand All @@ -82,12 +53,13 @@ function isOnboardingFlowCompleted({onCompleted, onNotCompleted}: HasCompletedOn
* - Whether we have loaded all reports the server knows about
*/
function checkOnReady() {
const hasRequiredOnyxKeysBeenLoaded = [isFirstTimeNewExpensifyUser, hasDismissedModal].every((value) => value !== undefined);
const hasRequiredOnyxKeysBeenLoaded = [onboarding, hasSelectedPurpose, hasDismissedModal, hasProvidedPersonalDetails].every((value) => value !== undefined);

if (isLoadingReportData || !hasRequiredOnyxKeysBeenLoaded) {
return;
}

resolveOnboardingFlowStatus?.();
resolveIsReadyPromise?.();
}

Expand All @@ -101,7 +73,7 @@ function getPersonalDetails(accountID: number | undefined) {
}

hasProvidedPersonalDetails = !!value[accountID]?.firstName && !!value[accountID]?.lastName;
isAbleToDetermineOnboardingStatus({onAble: resolveOnboardingFlowStatus});
checkOnReady();
},
});
}
Expand All @@ -111,13 +83,14 @@ function setOnboardingPurposeSelected(value: SelectedPurposeType) {
}

Onyx.connect({
key: ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER,
key: ONYXKEYS.NVP_ONBOARDING,
initWithStoredValues: false,
callback: (value) => {
// If isFirstTimeNewExpensifyUser was true do not update it to false. We update it to false inside the Welcome.isOnboardingFlowCompleted logic
// More context here https://github.com/Expensify/App/pull/16962#discussion_r1167351359
if (value === null) {
return;
}

isFirstTimeNewExpensifyUser = value ?? undefined;
onboarding = value;

checkOnReady();
},
Expand All @@ -128,7 +101,8 @@ Onyx.connect({
initWithStoredValues: true,
callback: (value) => {
hasSelectedPurpose = !!value;
isAbleToDetermineOnboardingStatus({onAble: resolveOnboardingFlowStatus});

checkOnReady();
},
});

Expand Down Expand Up @@ -179,4 +153,15 @@ Onyx.connect({
},
});

export {onServerDataReady, isOnboardingFlowCompleted, setOnboardingPurposeSelected};
function resetAllChecks() {
isServerDataReadyPromise = new Promise((resolve) => {
resolveIsReadyPromise = resolve;
});
isOnboardingFlowStatusKnownPromise = new Promise((resolve) => {
resolveOnboardingFlowStatus = resolve;
});
onboarding = undefined;
isLoadingReportData = true;
}

export {onServerDataReady, isOnboardingFlowCompleted, setOnboardingPurposeSelected, resetAllChecks};
6 changes: 6 additions & 0 deletions src/types/onyx/Onboarding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type Onboarding = {
/** A Boolean that informs whether the user has completed onboarding. */
hasCompletedGuidedSetupFlow: boolean;
};

export default Onboarding;

0 comments on commit c5d61ae

Please sign in to comment.