Open lanitochka17 opened 1 week ago
Triggered auto assignment to @strepanier03 (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.
Email for the magic code received only if the process steps from start "New contact method"
sendValidateCode()
one time:resetFirstRenderRef
in: const resetFirstRenderRef = () => {
firstRenderRef.current = true;
};
useImperativeHandle(ref, () => ({resetFirstRenderRef}), []);
we can pass the ref prop like:
<ValidateCodeActionModal
ref={validateModalRef}
then can use the ref in:
const handleValidateMagicCode = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.NEW_CONTACT_METHOD_FORM>) => {
if (values.phoneOrEmail !== pendingContactAction?.contactMethod) {
validateModalRef.current?.resetFirstRenderRef?.();
}
or
<InputWrapper
onValueChange={()=>{
validateModalRef.current?.resetFirstRenderRef?.();
}}
When a user goes back and again click on the Add, the magic code is not being sent.
firstRenderRef.curren
t which was added to solve the double-sending problem because the ValidateCodeActionModal component renders multiple times when it first mountssendValidateCode()
callsnew problem created by the fix
firstRenderRef.current
solution only allows the code to be sent on the very first render of the
componentWe should replace firstRenderRef
with hasCodeBeenSentRef
that resets when the modal closes:
const hasCodeBeenSentRef = useRef(false);
const hide = useCallback(() => {
clearError();
onClose();
hasCodeBeenSentRef.current = false; // Reset when modal closes
}, [onClose, clearError]);
useEffect(() => {
if (!isVisible || hasMagicCodeBeenSent || hasCodeBeenSentRef.current) {
return;
}
hasCodeBeenSentRef.current = true;
sendValidateCode();
}, [isVisible, sendValidateCode, hasMagicCodeBeenSent]);
we can just add this on the hide function(which is also called when user go back), so when the this page closes, we are setting it back to true: firstRenderRef.current = true;
it is same as my main approach, the difference is just the naming of variable, in the first approach i think the naming of variable is more readable
Edited by proposal-police: This proposal was edited at 2024-11-16 06:39:01 UTC.
Secondary account can't be added unless start over after an error
As per the current logic, we check if it’s not the first render, and if it’s not the first render, we don’t send the validate code. This is to prevent sending the validate code multiple times. https://github.com/Expensify/App/blob/29d054cea0d6e84ec44f522c0d31590a973bfb87/src/components/ValidateCodeActionModal/index.tsx#L52-L59
But when we input the wrong validate code, go back, and change to a new email, firstRenderRef
still exists as false
because we didn't update it when the email changed. As a result, the function to send the validate code will not execute because it returns early due to firstRenderRef
, and this issue occurs.
To resolve this issue, we should check if the email has changed, and if so, we must reset firstRenderRef. The code should be modified like this:
1 We need to store the previous phone number or email to compare when the 'Add' button is clicked. We must check this in the add function because the user is able to re-enter the email after it has been changed.
// src/pages/settings/Profile/Contacts/NewContactMethodPage.tsx#L51
+ const previousPhoneOrEmail = useRef('');
+ const [isChangedPhoneOrEmail, setIsChangedPhoneOrEmail] = useState(false);
// src/pages/settings/Profile/Contacts/NewContactMethodPage.tsx#L52
const handleValidateMagicCode = useCallback((values: FormOnyxValues<typeof ONYXKEYS.FORMS.NEW_CONTACT_METHOD_FORM>) => {
const phoneLogin = LoginUtils.getPhoneLogin(values.phoneOrEmail);
const validateIfnumber = LoginUtils.validateNumber(phoneLogin);
const submitDetail = (validateIfnumber || values.phoneOrEmail).trim().toLowerCase();
+ setIsChangedPhoneOrEmail(previousPhoneOrEmail?.current !== submitDetail);
+ previousPhoneOrEmail.current = submitDetail;
User.addPendingContactMethod(submitDetail);
setIsValidateCodeActionModalVisible(true);
}, []);
// src/pages/settings/Profile/Contacts/NewContactMethodPage.tsx#L159
<ValidateCodeActionModal
...
+ isChangedPhoneOrEmail={isChangedPhoneOrEmail}
/>
2 In ValidateCodeActionModal, we need check if isChangedPhoneOrEmail
is then we need reset firstRenderRef
// src/components/ValidateCodeActionModal/index.tsx#L45
+ useEffect(() => {
+ if (!isChangedPhoneOrEmail) {
+ return;
+ }
+ firstRenderRef.current = true;
+ }, [isChangedPhoneOrEmail]);
isChangedPhoneOrEmail
after sending the validation code to ensure the email validation works correctly.// src/pages/settings/Profile/Contacts/NewContactMethodPage.tsx#L172
<ValidateCodeActionModal
...
sendValidateCode={() => {
+ setIsChangedPhoneOrEmail(false);
User.requestValidateCodeAction();
}}
descriptionPrimary={translate('contacts.enterMagicCode', {contactMethod})}
isChangedPhoneOrEmail={isChangedPhoneOrEmail}
/>
Alternatively, if we want to send the validate code only once, we can add the email that the code was sent to into a list and compare it when the 'Add' button is clicked. This list will reset when the modal is closed.
// src/pages/settings/Profile/Contacts/NewContactMethodPage.tsx#L51
+ const previousPhoneOrEmailList = useRef<string[]>([]);
+ const [isChangedPhoneOrEmail, setIsChangedPhoneOrEmail] = useState(false);
setIsChangedPhoneOrEmail
to true
to send the validation code; otherwise, set it to false
to not send the code.// src/pages/settings/Profile/Contacts/NewContactMethodPage.tsx#L52
const handleValidateMagicCode = useCallback((values: FormOnyxValues<typeof ONYXKEYS.FORMS.NEW_CONTACT_METHOD_FORM>) => {
const phoneLogin = LoginUtils.getPhoneLogin(values.phoneOrEmail);
const validateIfnumber = LoginUtils.validateNumber(phoneLogin);
const submitDetail = (validateIfnumber || values.phoneOrEmail).trim().toLowerCase();
+ if (!previousPhoneOrEmailList.current.includes(submitDetail)) {
+ setIsChangedPhoneOrEmail(true);
+ previousPhoneOrEmailList.current.push(submitDetail);
+ } else {
+ setIsChangedPhoneOrEmail(false);
+ }
User.addPendingContactMethod(submitDetail);
setIsValidateCodeActionModalVisible(true);
}, []);
// src/pages/settings/Profile/Contacts/NewContactMethodPage.tsx#L159
<ValidateCodeActionModal
...
+ isChangedPhoneOrEmail={isChangedPhoneOrEmail}
/>
isChangedPhoneOrEmail
is then we need reset firstRenderRef
// src/components/ValidateCodeActionModal/index.tsx#L45
+ useEffect(() => {
+ if (!isChangedPhoneOrEmail) {
+ return;
+ }
+ firstRenderRef.current = true;
+ }, [isChangedPhoneOrEmail]);
isChangedPhoneOrEmail
after sending the validation code to ensure the email validation works correctly.// src/pages/settings/Profile/Contacts/NewContactMethodPage.tsx#L172
<ValidateCodeActionModal
...
sendValidateCode={() => {
+ setIsChangedPhoneOrEmail(false);
User.requestValidateCodeAction();
}}
descriptionPrimary={translate('contacts.enterMagicCode', {contactMethod})}
isChangedPhoneOrEmail={isChangedPhoneOrEmail}
/>
@strepanier03 Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
Working on testing this one now.
Repro'd with steps as described.
Job added to Upwork: https://www.upwork.com/jobs/~021858738599400775577
Triggered auto assignment to Contributor-plus team member for initial proposal review - @thesahindia (External
)
@Shahidullah-Muffakir's proposal looks good to me!
🎀 👀 🎀 C+ reviewed
Triggered auto assignment to @yuwenmemon, see https://stackoverflow.com/c/expensify/questions/7972 for more details.
📣 @Shahidullah-Muffakir You have been assigned to this job! Please apply to the Upwork job and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑💻 Once you apply to this job, your Upwork ID will be stored and you will be automatically hired for future jobs! Keep in mind: Code of Conduct | Contributing 📖
@yuwenmemon @thesahindia The selected proposal does not match the expected behavior in the OP, it always call ResendValidateCode
when opening the ValidateCodeActionModal, but the expected behavior is that, we only call "ResendValidateCode" if user enter new email.
@yuwenmemon @thesahindia The selected proposal does not match the expected behavior in the OP, it always call
ResendValidateCode
when opening the ValidateCodeActionModal, but the expected behavior is that, we only call "ResendValidateCode" if user enter new email.
I don't think it is the expected behavior, as a user if i click on the Add button, i want to receive a majic code, even if the email did not change.
I think we need the confirmation from internal team here
I think it should send a magic link only once per email added, similar to the alternative solution in the video. This is useful to avoid spamming by sending too many verification codes
@yuwenmemon, could we please confirm the expected result here?
@yuwenmemon, @strepanier03, @thesahindia, @Shahidullah-Muffakir Huh... This is 4 days overdue. Who can take care of this?
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Version Number: 9.0.62-2 Reproducible in staging?: Y Reproducible in production?: Y If this was caught on HybridApp, is this reproducible on New Expensify Standalone?: N/A If this was caught during regression testing, add the test name, ID and link from TestRail: N/A Issue reported by: Applause - Internal Team
Action Performed:
Prerequisite User A start a chat with User B All steps are done as User A
Expected Result:Prerequisite
Email of magic code received in step 6 as the magic code is already sent
Actual Result:
Email for the magic code received only if the process steps from start "New contact method"
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Screenshots/Videos
Add any screenshot/video evidence
https://github.com/user-attachments/assets/d57adf0e-a6ec-41a0-a009-fe5d739d1434
View all open jobs on GitHub
Upwork Automation - Do Not Edit
Issue Owner
Current Issue Owner: @thesahindia