Skip to content

Add merge account feature to ND #56911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 55 commits into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
cda8dad
draft version of merge account
allroundexperts Dec 16, 2024
e4bdee3
account details page draft
allroundexperts Dec 17, 2024
16d5fdc
add translations and forms
allroundexperts Dec 17, 2024
ec445e1
more files
allroundexperts Dec 18, 2024
06c15e5
Merge branch 'main' into feat-47073
allroundexperts Jan 8, 2025
717bc14
WIP: ad6007b6398 onboarding flow without errors
allroundexperts Feb 16, 2025
217ceb4
more finetunings
allroundexperts Feb 16, 2025
353a410
fix a bunch of lint errors
allroundexperts Feb 18, 2025
e79174a
working version
allroundexperts Feb 21, 2025
89ecf4e
remove delegate access wrappers
allroundexperts Feb 21, 2025
61ff190
merge with main
allroundexperts Feb 21, 2025
478de42
add confirmation screen
allroundexperts Feb 23, 2025
20f900e
fix spanish translations
allroundexperts Feb 23, 2025
3281bc5
merge with main
allroundexperts Feb 23, 2025
c2eeb1e
handle lint issues
allroundexperts Feb 23, 2025
305253c
more lint errors
allroundexperts Feb 23, 2025
78a5563
lint fix
allroundexperts Feb 23, 2025
6501b6d
fix: footer styles
allroundexperts Feb 23, 2025
a4800c2
merge with main
allroundexperts Feb 26, 2025
c210eda
Merge branch 'main' into feat-47073
allroundexperts Mar 7, 2025
9368bec
fix all the bugs
allroundexperts Mar 7, 2025
89f3947
fix lint errors
allroundexperts Mar 7, 2025
4474019
prettier
allroundexperts Mar 7, 2025
f4e5d37
fix type checks
allroundexperts Mar 7, 2025
6a8d5b8
revert back to onButton press
allroundexperts Mar 7, 2025
025b2a0
change order of menu
allroundexperts Mar 7, 2025
5b995df
prettier
allroundexperts Mar 7, 2025
54b1340
remove help button
allroundexperts Mar 7, 2025
c8f1ad0
update more designs
allroundexperts Mar 7, 2025
9cd1765
prettier
allroundexperts Mar 7, 2025
907e1eb
more edge cases fix
allroundexperts Mar 7, 2025
4f1c885
merge with main
allroundexperts Mar 18, 2025
aa49ff8
remove un-needed changes
allroundexperts Mar 18, 2025
abd253c
handle comments
allroundexperts Mar 18, 2025
d0c75e3
fix bugs
allroundexperts Mar 18, 2025
5a13183
sync mobile exfy
allroundexperts Mar 18, 2025
626a201
prettier + typechecks
allroundexperts Mar 18, 2025
06ad4b4
Merge branch 'main' into feat-47073
allroundexperts Mar 25, 2025
ff4cb72
add too many attempts page
allroundexperts Mar 25, 2025
a237ac2
prettier
allroundexperts Mar 25, 2025
f68a77f
clear form on starting
allroundexperts Mar 25, 2025
2adda02
prettier
allroundexperts Mar 25, 2025
3430d81
Type fix
allroundexperts Mar 25, 2025
5d3e750
handle comments
allroundexperts Mar 26, 2025
e23f9c9
handle comments
allroundexperts Mar 28, 2025
c1d9c8f
lint fixes
allroundexperts Mar 28, 2025
2c411da
Merge branch 'main' into feat-47073
allroundexperts Mar 30, 2025
24d2819
handle comments
allroundexperts Mar 31, 2025
244772c
Merge branch 'main' into feat-47073
allroundexperts Apr 1, 2025
1fc1783
fix more bugs
allroundexperts Apr 1, 2025
4ced55d
add another case of error
allroundexperts Apr 1, 2025
397b2a1
fix err_2fa
allroundexperts Apr 3, 2025
cb653ec
Merge branch 'main' into feat-47073
allroundexperts Apr 5, 2025
3ceb6d6
minor fixes
allroundexperts Apr 4, 2025
ddce6cf
change variable names
allroundexperts Apr 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/components/ConfirmationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ type ConfirmationPageProps = {
/** Description of the confirmation page */
description: React.ReactNode;

/** The text for the call to action */
cta?: React.ReactNode;

/** The text for the primary button label */
buttonText?: string;

Expand Down Expand Up @@ -49,6 +52,9 @@ type ConfirmationPageProps = {
/** Additional style for the description */
descriptionStyle?: TextStyle;

/** Additional style for the cta */
ctaStyle?: TextStyle;

/** Additional style for the footer */
footerStyle?: ViewStyle;

Expand All @@ -60,6 +66,7 @@ function ConfirmationPage({
illustration = LottieAnimations.Fireworks,
heading,
description,
cta,
buttonText = '',
onButtonPress = () => {},
shouldShowButton = false,
Expand All @@ -69,6 +76,7 @@ function ConfirmationPage({
headingStyle,
illustrationStyle,
descriptionStyle,
ctaStyle,
footerStyle,
containerStyle,
}: ConfirmationPageProps) {
Expand Down Expand Up @@ -99,6 +107,7 @@ function ConfirmationPage({
)}
<Text style={[styles.textHeadline, styles.textAlignCenter, styles.mv2, headingStyle]}>{heading}</Text>
<Text style={[styles.textAlignCenter, descriptionStyle]}>{description}</Text>
{cta ? <Text style={[styles.textAlignCenter, ctaStyle]}>{cta}</Text> : null}
</View>
{(shouldShowSecondaryButton || shouldShowButton) && (
<FixedFooter style={footerStyle}>
Expand Down
6 changes: 3 additions & 3 deletions src/components/ValidateCodeActionForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function ValidateCodeActionForm({
isLoading,
submitButtonText,
forwardedRef,
skipInitialValidation,
shouldSkipInitialValidation,
}: ValidateCodeActionFormProps) {
const themeStyles = useThemeStyles();

Expand All @@ -29,15 +29,15 @@ function ValidateCodeActionForm({
const isUnmounted = useRef(false);

useEffect(() => {
if (!skipInitialValidation) {
if (!shouldSkipInitialValidation) {
sendValidateCode();
}

return () => {
isUnmounted.current = true;
};
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
}, [skipInitialValidation]);
}, [shouldSkipInitialValidation]);

useEffect(() => {
return () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/ValidateCodeActionForm/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type ValidateCodeActionFormProps = {
submitButtonText?: string;

/** Skip the call to sendValidateCode fn on initial render */
skipInitialValidation?: boolean;
shouldSkipInitialValidation?: boolean;
};

// eslint-disable-next-line import/prefer-default-export
Expand Down
12 changes: 6 additions & 6 deletions src/libs/actions/MergeAccounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function requestValidationCodeForAccountMerge(email: string) {
API.write(WRITE_COMMANDS.GET_VALIDATE_CODE_FOR_ACCOUNT_MERGE, parameters, {optimisticData, successData, failureData});
}

function clearRequestValidationCodeForAccountMerge() {
function clearGetValidateCodeForAccountMerge() {
Onyx.merge(ONYXKEYS.ACCOUNT, {
getValidateCodeForAccountMerge: {
errors: null,
Expand All @@ -80,7 +80,7 @@ function mergeWithValidateCode(email: string, validateCode: string) {
value: {
mergeWithValidateCode: {
isLoading: true,
accountMerged: false,
isAccountMerged: false,
errors: null,
},
},
Expand All @@ -94,7 +94,7 @@ function mergeWithValidateCode(email: string, validateCode: string) {
value: {
mergeWithValidateCode: {
isLoading: false,
accountMerged: true,
isAccountMerged: true,
errors: null,
},
},
Expand All @@ -108,7 +108,7 @@ function mergeWithValidateCode(email: string, validateCode: string) {
value: {
mergeWithValidateCode: {
isLoading: false,
accountMerged: false,
isAccountMerged: false,
},
},
},
Expand All @@ -127,9 +127,9 @@ function clearMergeWithValidateCode() {
mergeWithValidateCode: {
errors: null,
isLoading: false,
accountMerged: false,
isAccountMerged: false,
},
});
}

export {requestValidationCodeForAccountMerge, clearRequestValidationCodeForAccountMerge, mergeWithValidateCode, clearMergeWithValidateCode};
export {requestValidationCodeForAccountMerge, clearGetValidateCodeForAccountMerge, mergeWithValidateCode, clearMergeWithValidateCode};
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigat
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import {parsePhoneNumber} from '@libs/PhoneNumber';
import {isNumericWithSpecialChars} from '@libs/ValidationUtils';
import {clearRequestValidationCodeForAccountMerge, requestValidationCodeForAccountMerge} from '@userActions/MergeAccounts';
import {clearGetValidateCodeForAccountMerge, requestValidationCodeForAccountMerge} from '@userActions/MergeAccounts';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
Expand Down Expand Up @@ -87,7 +87,7 @@ function AccountDetailsPage() {
useFocusEffect(
useCallback(() => {
return () => {
clearRequestValidationCodeForAccountMerge();
clearGetValidateCodeForAccountMerge();
};
}, []),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import {
clearGetValidateCodeForAccountMerge,
clearMergeWithValidateCode,
clearRequestValidationCodeForAccountMerge,
mergeWithValidateCode as mergeWithValidateCodeAction,
requestValidationCodeForAccountMerge,
} from '@userActions/MergeAccounts';
Expand Down Expand Up @@ -73,7 +73,7 @@ function AccountValidatePage() {
const mergeWithValidateCode = account?.mergeWithValidateCode;
const getValidateCodeForAccountMerge = account?.getValidateCodeForAccountMerge;

const accountMerged = mergeWithValidateCode?.accountMerged;
const isAccountMerged = mergeWithValidateCode?.isAccountMerged;

const latestError = getLatestErrorMessage(mergeWithValidateCode);
const errorKey = getMergeErrorKey(latestError);
Expand All @@ -83,27 +83,27 @@ function AccountValidatePage() {

useFocusEffect(
useCallback(() => {
if (!accountMerged || !email) {
if (!isAccountMerged || !email) {
return;
}
return Navigation.navigate(ROUTES.SETTINGS_MERGE_ACCOUNTS_RESULT.getRoute(email, 'success'));
}, [accountMerged, email]),
return Navigation.navigate(ROUTES.SETTINGS_MERGE_ACCOUNTS_RESULT.getRoute(email, 'success'), {forceReplace: true});
}, [isAccountMerged, email]),
);

useFocusEffect(
useCallback(() => {
if (!errorKey || !email) {
return;
}
return Navigation.navigate(ROUTES.SETTINGS_MERGE_ACCOUNTS_RESULT.getRoute(email, errorKey));
return Navigation.navigate(ROUTES.SETTINGS_MERGE_ACCOUNTS_RESULT.getRoute(email, errorKey), {forceReplace: true});
}, [errorKey, email]),
);

useFocusEffect(
useCallback(() => {
return () => {
clearMergeWithValidateCode();
clearRequestValidationCodeForAccountMerge();
clearGetValidateCodeForAccountMerge();
};
}, []),
);
Expand Down Expand Up @@ -140,9 +140,9 @@ function AccountValidatePage() {
sendValidateCode={() => {
requestValidationCodeForAccountMerge(email);
}}
skipInitialValidation
shouldSkipInitialValidation
clearError={() => clearMergeWithValidateCode()}
validateError={mergeWithValidateCode?.errors}
validateError={!errorKey ? mergeWithValidateCode?.errors : undefined}
hasMagicCodeBeenSent={getValidateCodeForAccountMerge?.validateCodeSent}
submitButtonText={translate('mergeAccountsPage.mergeAccount')}
forwardedRef={validateCodeFormRef}
Expand Down
11 changes: 7 additions & 4 deletions src/pages/settings/Security/MergeAccounts/MergeResultPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,11 @@ function MergeResultPage() {
<Text style={[styles.textStrong, styles.textSupporting]}>{login}</Text>
{translate('mergeAccountsPage.mergeFailure2FA.oldAccount2FAEnabled.beforeSecondEmail')}
<Text style={[styles.textStrong, styles.textSupporting]}>{login}</Text>
{translate('mergeAccountsPage.mergeFailure2FA.oldAccount2FAEnabled.afterSecondEmail')}{' '}
<Text style={[styles.textSupporting]}>
<TextLink href={CONST.MERGE_ACCOUNT_HELP_URL}>{translate('mergeAccountsPage.mergeFailure2FA.learnMore')}</TextLink>
</Text>
{translate('mergeAccountsPage.mergeFailure2FA.oldAccount2FAEnabled.afterSecondEmail')}
</>
),
cta: <TextLink href={CONST.MERGE_ACCOUNT_HELP_URL}>{translate('mergeAccountsPage.mergeFailure2FA.learnMore')}</TextLink>,
ctaStyle: {...styles.mt2, ...styles.textSupporting},
onButtonPress: () => Navigation.goBack(ROUTES.SETTINGS_SECURITY),
buttonText: translate('common.buttonConfirm'),
illustration: Illustrations.LockClosedOrange,
Expand Down Expand Up @@ -242,6 +241,8 @@ function MergeResultPage() {
secondaryButtonText,
onSecondaryButtonPress,
shouldShowSecondaryButton,
cta,
ctaStyle,
} = results[result] || defaultResult;

return (
Expand Down Expand Up @@ -271,6 +272,8 @@ function MergeResultPage() {
descriptionStyle={{...descriptionStyle, ...styles.textSupporting}}
illustration={illustration}
illustrationStyle={illustrationStyle}
cta={cta}
ctaStyle={ctaStyle}
/>
</ScreenWrapper>
);
Expand Down
2 changes: 1 addition & 1 deletion src/types/onyx/Account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ type Account = {
isLoading?: boolean;

/** Whether the account was merged successfully */
accountMerged?: boolean;
isAccountMerged?: boolean;

/** Errors while merging the account */
errors: OnyxCommon.Errors;
Expand Down