Skip to content
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

fix:blank page appears in validate code form page #55588

Open
wants to merge 50 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
6373c37
fix:blank page appears in validate code form page
jacobkim9881 Jan 22, 2025
172c7b0
lint: fixed ! assertion error
jacobkim9881 Jan 22, 2025
c4e944f
pulled original/main
jacobkim9881 Jan 22, 2025
6232476
lint assertion err fixed
jacobkim9881 Jan 23, 2025
d216e60
lint disabled prop spreading
jacobkim9881 Jan 23, 2025
217ac60
Revert "pulled original/main"
jacobkim9881 Jan 23, 2025
622df4f
comment type for ref
jacobkim9881 Jan 23, 2025
9f1f207
should resolve() if container is undefined
jacobkim9881 Jan 23, 2025
5493c6b
comment about focus trap for animation
jacobkim9881 Jan 23, 2025
dd436e9
fix: clicking header back err occurs
jacobkim9881 Jan 23, 2025
a404826
clear error only after closing the modal
jacobkim9881 Jan 24, 2025
6640264
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Jan 24, 2025
6a12518
lint fixed
jacobkim9881 Jan 24, 2025
3f12bb5
Revert "lint fixed"
jacobkim9881 Jan 24, 2025
433778f
lint fixed
jacobkim9881 Jan 24, 2025
c001758
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Jan 28, 2025
72e88b7
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Jan 29, 2025
0afd14a
moved isVisible in the validate code form
jacobkim9881 Jan 30, 2025
9b7b20d
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Jan 30, 2025
c19c2af
hide menu items while sliding out of validate page
jacobkim9881 Jan 31, 2025
0c12b86
Revert "hide menu items while sliding out of validate page"
jacobkim9881 Jan 31, 2025
b6e0138
fix: trashcan shows as navigating out on mWeb
jacobkim9881 Feb 2, 2025
5cce05c
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Feb 2, 2025
426d8be
delete this becuase transition anim works w/o it
jacobkim9881 Feb 3, 2025
00d7c51
renamed and deleted ValidateCodeActionWithoutModal
jacobkim9881 Feb 3, 2025
8d37911
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Feb 3, 2025
23498e9
lint fixed
jacobkim9881 Feb 3, 2025
0d1f9fe
focusTrap not needed in mSafari
jacobkim9881 Feb 3, 2025
a317155
fix: keyboard not show on Android app, iOS app
jacobkim9881 Feb 4, 2025
5b3af3c
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Feb 4, 2025
e37d564
fix: show remove contact method modal
jacobkim9881 Feb 4, 2025
589f444
focusTrap not needed in mSafari
jacobkim9881 Feb 4, 2025
0e4b20f
show/hide code form
jacobkim9881 Feb 5, 2025
bc83a7b
fix: clear error runs on default contact method too
jacobkim9881 Feb 6, 2025
1c0cced
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Feb 7, 2025
91e940d
fix: has 2 isVisible
jacobkim9881 Feb 7, 2025
943ce63
not use setState for isValidated
jacobkim9881 Feb 7, 2025
a2c3878
created type for ValidateCodeActionForm
jacobkim9881 Feb 7, 2025
600d0d5
check isValidated not needed for sendValidateCode
jacobkim9881 Feb 7, 2025
3fc7ee4
commeted for cleanup function
jacobkim9881 Feb 7, 2025
c715494
not use firstRenderRef
jacobkim9881 Feb 11, 2025
ef17df1
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Feb 11, 2025
9b73217
showing button on number pad poped up on iOS mWeb
jacobkim9881 Feb 11, 2025
08b8d76
fix: keyboard not show on Android app, iOS app
jacobkim9881 Feb 12, 2025
aac99d3
deleted unneeded condition
jacobkim9881 Feb 12, 2025
bc398e4
Merge branch 'main' of https://github.com/Expensify/App into m53884
jacobkim9881 Feb 12, 2025
3a7ebdf
Merge branch 'd53884-5' of github.com:jacobkim9881/Expensify-App into…
jacobkim9881 Feb 12, 2025
35ab2c8
lint
jacobkim9881 Feb 12, 2025
f415985
runs clearError() as call back when unmounted
jacobkim9881 Feb 12, 2025
09e4bc1
fix: when clicking contact method 2nd time, numpad not showing on And…
jacobkim9881 Feb 14, 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
2 changes: 1 addition & 1 deletion src/components/ValidateCodeActionModal/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type ValidateCodeActionModalProps = {
isVisible: boolean;

/** Title of the modal */
title: string;
title?: string;

/** Primary description of the modal */
descriptionPrimary: string;
Expand Down
82 changes: 82 additions & 0 deletions src/components/ValidateCodeActionWithoutModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, {forwardRef, useEffect, useRef} from 'react';
import type {ForwardedRef} from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import useThemeStyles from '@hooks/useThemeStyles';
import ONYXKEYS from '@src/ONYXKEYS';
import Text from './Text';
import type {ValidateCodeActionModalProps} from './ValidateCodeActionModal/type';
import ValidateCodeForm from './ValidateCodeActionModal/ValidateCodeForm';
import type {ValidateCodeFormHandle} from './ValidateCodeActionModal/ValidateCodeForm/BaseValidateCodeForm';

type ValidateCodeActionWithoutModalProps = {
/** Ref for validate code form */
forwardedRef: ForwardedRef<ValidateCodeFormHandle>;
};

type ValidateCodeActionProps = ValidateCodeActionModalProps & ValidateCodeActionWithoutModalProps;

function ValidateCodeActionWithoutModal({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any other names for this component? It seems is not a good name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated it to ValidateCodeActionForm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it shares ValidateCodeActionModalProps, I think ValidateCodeAction should be included. It has the form element and has props to run actions. I think ValidateCodeActionForm can be properly used. Please to tell me if you have any idea though.

isVisible,
descriptionPrimary,
descriptionSecondary,
validatePendingAction,
validateError,
handleSubmitForm,
clearError,
sendValidateCode,
hasMagicCodeBeenSent,
isLoading,
forwardedRef,
}: ValidateCodeActionProps) {
const themeStyles = useThemeStyles();
const firstRenderRef = useRef(true);

const [validateCodeAction] = useOnyx(ONYXKEYS.VALIDATE_ACTION_CODE);

useEffect(
() => () => {
firstRenderRef.current = true;
},
[],
);

useEffect(() => {
if (!firstRenderRef.current || !isVisible || hasMagicCodeBeenSent) {
return () => {
clearError();
};
}
firstRenderRef.current = false;
sendValidateCode();
}, [isVisible, sendValidateCode, hasMagicCodeBeenSent, clearError]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not a modal. Do we need firstRenderRef or isVisible anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

W/o it, it will send validate code in validated contact method or default method. It only sends validate code in validate code page only.


return (
<View style={[themeStyles.ph5, themeStyles.mt3, themeStyles.mb5, themeStyles.flex1]}>
<Text style={[themeStyles.mb3]}>{descriptionPrimary}</Text>
{!!descriptionSecondary && <Text style={[themeStyles.mb3]}>{descriptionSecondary}</Text>}
<ValidateCodeForm
isLoading={isLoading}
validateCodeAction={validateCodeAction}
validatePendingAction={validatePendingAction}
validateError={validateError}
handleSubmitForm={handleSubmitForm}
sendValidateCode={sendValidateCode}
clearError={clearError}
buttonStyles={[themeStyles.justifyContentEnd, themeStyles.flex1]}
ref={forwardedRef}
hasMagicCodeBeenSent={hasMagicCodeBeenSent}
/>
</View>
);
}

ValidateCodeActionWithoutModal.displayName = 'ValidateCodeActionWithoutModal';

export default forwardRef<ValidateCodeFormHandle, ValidateCodeActionProps>((props, ref) => (
<ValidateCodeActionWithoutModal
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
forwardedRef={ref}
/>
));
76 changes: 48 additions & 28 deletions src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import ValidateCodeActionModal from '@components/ValidateCodeActionModal';
import ValidateCodeActionWithoutModal from '@components/ValidateCodeActionWithoutModal';
import useBeforeRemove from '@hooks/useBeforeRemove';
import useLocalize from '@hooks/useLocalize';
import usePrevious from '@hooks/usePrevious';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import blurActiveElement from '@libs/Accessibility/blurActiveElement';
import {
clearContactMethod,
Expand Down Expand Up @@ -61,6 +62,7 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) {
const {formatPhoneNumber, translate} = useLocalize();
const theme = useTheme();
const themeStyles = useThemeStyles();
const {windowWidth} = useWindowDimensions();

const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const validateCodeFormRef = useRef<ValidateCodeFormHandle>(null);
Expand Down Expand Up @@ -270,12 +272,41 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) {
<ScreenWrapper
onEntryTransitionEnd={() => validateCodeFormRef.current?.focus?.()}
testID={ContactMethodDetailsPage.displayName}
focusTrapSettings={{
focusTrapOptions: {
// It is added because input form's focusing bothers transition animation:
// https://github.com/Expensify/App/issues/53884#issuecomment-2594568960
checkCanFocusTrap: (trapContainers: Array<HTMLElement | SVGElement>) => {
return new Promise((resolve) => {
const interval = setInterval(() => {
const trapContainer = trapContainers.at(0);
if (!trapContainer || (trapContainer && getComputedStyle(trapContainer).visibility !== 'hidden')) {
resolve();
clearInterval(interval);
}
}, 5);
});
},
},
}}
>
<HeaderWithBackButton
title={formattedContactMethod}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_CONTACT_METHODS.getRoute(backTo))}
threeDotsMenuItems={getThreeDotsMenuItems()}
shouldShowThreeDotsButton={getThreeDotsMenuItems().length > 0}
shouldOverlayDots
threeDotsAnchorPosition={themeStyles.threeDotsPopoverOffset(windowWidth)}
onThreeDotsButtonPress={() => {
// Hide the keyboard when the user clicks the three-dot menu.
// Use blurActiveElement() for mWeb and KeyboardUtils.dismiss() for native apps.
blurActiveElement();
KeyboardUtils.dismiss();
}}
/>
<ScrollView keyboardShouldPersistTaps="handled">
<ScrollView
keyboardShouldPersistTaps="handled"
contentContainerStyle={themeStyles.flex1}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you elaborate why do we need this style?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This style makes put "Verify" button to bottom. W/o the style the button will be placed beneath validate code form.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @jacobkim9881 again ^

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The elements can fit the necessary space. The explain, form and button elements are placed in its position with this style.

>
{isFailedAddContactMethod && (
<ErrorMessageRow
errors={getLatestErrorField(loginData, 'addedLogin')}
Expand All @@ -289,32 +320,21 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) {
/>
)}

<ValidateCodeActionModal
title={formattedContactMethod}
onModalHide={() => {}}
hasMagicCodeBeenSent={hasMagicCodeBeenSent}
isVisible={isValidateCodeActionModalVisible && !loginData.validatedDate && !!loginData}
validatePendingAction={loginData.pendingFields?.validateCodeSent}
handleSubmitForm={(validateCode) => validateSecondaryLogin(loginList, contactMethod, validateCode)}
validateError={!isEmptyObject(validateLoginError) ? validateLoginError : getLatestErrorField(loginData, 'validateCodeSent')}
clearError={() => clearContactMethodErrors(contactMethod, !isEmptyObject(validateLoginError) ? 'validateLogin' : 'validateCodeSent')}
onClose={() => {
Navigation.goBack(ROUTES.SETTINGS_CONTACT_METHODS.getRoute(backTo));
setIsValidateCodeActionModalVisible(false);
}}
sendValidateCode={() => requestContactMethodValidateCode(contactMethod)}
descriptionPrimary={translate('contacts.enterMagicCode', {contactMethod: formattedContactMethod})}
onThreeDotsButtonPress={() => {
// Hide the keyboard when the user clicks the three-dot menu.
// Use blurActiveElement() for mWeb and KeyboardUtils.dismiss() for native apps.
blurActiveElement();
KeyboardUtils.dismiss();
}}
threeDotsMenuItems={getThreeDotsMenuItems()}
footer={getDeleteConfirmationModal}
/>
{!loginData?.validatedDate && (
<ValidateCodeActionWithoutModal
hasMagicCodeBeenSent={hasMagicCodeBeenSent}
isVisible={isValidateCodeActionModalVisible && !loginData.validatedDate && !!loginData}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should control the visibility of this component in line 323 instead of a prop. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before it is controled with isVisible in <ValidateCodeActionModal>. I think it should be controlled in <ValidateCodeActionWithoutModal>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before it is controled with isVisible in

validatePendingAction={loginData.pendingFields?.validateCodeSent}
handleSubmitForm={(validateCode) => validateSecondaryLogin(loginList, contactMethod, validateCode)}
validateError={!isEmptyObject(validateLoginError) ? validateLoginError : getLatestErrorField(loginData, 'validateCodeSent')}
clearError={() => clearContactMethodErrors(contactMethod, !isEmptyObject(validateLoginError) ? 'validateLogin' : 'validateCodeSent')}
sendValidateCode={() => requestContactMethodValidateCode(contactMethod)}
descriptionPrimary={translate('contacts.enterMagicCode', {contactMethod: formattedContactMethod})}
forwardedRef={validateCodeFormRef}
/>
)}

{!isValidateCodeActionModalVisible && getMenuItems()}
{!isValidateCodeActionModalVisible && !!loginData?.validatedDate && getMenuItems()}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate why do we need add an extra condition here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

W/o it, trash can will show when navigating out on Android mWeb.

expensify-test19-2025-02-02_12.45.08.mp4

</ScrollView>
</ScreenWrapper>
);
Expand Down
Loading