From 26de0b829e70be097cd9f68e548eb74773229998 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 27 Aug 2024 09:38:23 +0700 Subject: [PATCH 1/5] Send magic code when validate contact page navigated --- src/components/ValidateAccountMessage.tsx | 8 +++++++- .../settings/Profile/Contacts/ContactMethodsPage.tsx | 10 +++++++++- .../Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx | 4 +++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/components/ValidateAccountMessage.tsx b/src/components/ValidateAccountMessage.tsx index be43c2985961..51b13dab4237 100644 --- a/src/components/ValidateAccountMessage.tsx +++ b/src/components/ValidateAccountMessage.tsx @@ -13,6 +13,7 @@ import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import Text from './Text'; import TextLink from './TextLink'; +import * as User from '@userActions/User'; type ValidateAccountMessageProps = {backTo?: string | undefined}; function ValidateAccountMessage({backTo}: ValidateAccountMessageProps) { @@ -41,7 +42,12 @@ function ValidateAccountMessage({backTo}: ValidateAccountMessageProps) { { - const login = loginList?.[loginNames?.[0]] ?? {}; + const loginName = loginNames?.[0] + const login = loginList?.[loginName] ?? {}; + if (!login?.validatedDate && !login?.validateCodeSent) { + User.requestContactMethodValidateCode(loginName); + } + Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHOD_DETAILS.getRoute(login?.partnerUserID ?? loginNames?.[0], backTo)); }} > diff --git a/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx b/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx index e38f1a029d51..4e425f752e2a 100644 --- a/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx +++ b/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx @@ -23,6 +23,7 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {LoginList, Session} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import * as User from '@userActions/User'; type ContactMethodsPageOnyxProps = { /** Login list for the user that is signed in */ @@ -80,7 +81,14 @@ function ContactMethodsPage({loginList, session, route}: ContactMethodsPageProps Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHOD_DETAILS.getRoute(partnerUserID))} + onPress={() => { + const login = loginList?.[loginName] ?? {}; + if (!login?.validatedDate && !login?.validateCodeSent) { + User.requestContactMethodValidateCode(loginName); + } + + Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHOD_DETAILS.getRoute(partnerUserID)) + }} brickRoadIndicator={indicator} shouldShowBasicTitle shouldShowRightIcon diff --git a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx index e0b7a23d5df3..c0ea1f5f3aff 100644 --- a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx +++ b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx @@ -73,6 +73,7 @@ function BaseValidateCodeForm({account = {}, contactMethod, hasMagicCodeBeenSent // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- nullish coalescing doesn't achieve the same result in this case const shouldDisableResendValidateCode = !!isOffline || account?.isLoading; const focusTimeoutRef = useRef(null); + const [validateCodeSentIsPressed, setValidateCodeSentIsPressed] = useState(false); useImperativeHandle(innerRef, () => ({ focus() { @@ -134,6 +135,7 @@ function BaseValidateCodeForm({account = {}, contactMethod, hasMagicCodeBeenSent const resendValidateCode = () => { User.requestContactMethodValidateCode(contactMethod); inputValidateCodeRef.current?.clear(); + setValidateCodeSentIsPressed(true); }; /** @@ -201,7 +203,7 @@ function BaseValidateCodeForm({account = {}, contactMethod, hasMagicCodeBeenSent > {translate('validateCodeForm.magicCodeNotReceived')} - {hasMagicCodeBeenSent && ( + {hasMagicCodeBeenSent && validateCodeSentIsPressed && ( Date: Tue, 27 Aug 2024 09:55:54 +0700 Subject: [PATCH 2/5] validateCodeSent when adding new contact method --- src/libs/actions/User.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 74e5e5d869f9..d5015fbcddbe 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -301,6 +301,7 @@ function addNewContactMethodAndNavigate(contactMethod: string) { [contactMethod]: { partnerUserID: contactMethod, validatedDate: '', + validateCodeSent: true, errorFields: { addedLogin: null, }, From 5eb7081c917d1d4e12368b952e319cf7fc90ec0d Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 27 Aug 2024 10:01:53 +0700 Subject: [PATCH 3/5] Lint and prettier fix --- src/components/ValidateAccountMessage.tsx | 6 +++--- src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/ValidateAccountMessage.tsx b/src/components/ValidateAccountMessage.tsx index 51b13dab4237..277b113b2351 100644 --- a/src/components/ValidateAccountMessage.tsx +++ b/src/components/ValidateAccountMessage.tsx @@ -7,13 +7,13 @@ import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; +import * as User from '@userActions/User'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import Text from './Text'; import TextLink from './TextLink'; -import * as User from '@userActions/User'; type ValidateAccountMessageProps = {backTo?: string | undefined}; function ValidateAccountMessage({backTo}: ValidateAccountMessageProps) { @@ -42,12 +42,12 @@ function ValidateAccountMessage({backTo}: ValidateAccountMessageProps) { { - const loginName = loginNames?.[0] + const loginName = loginNames?.[0]; const login = loginList?.[loginName] ?? {}; if (!login?.validatedDate && !login?.validateCodeSent) { User.requestContactMethodValidateCode(loginName); } - + Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHOD_DETAILS.getRoute(login?.partnerUserID ?? loginNames?.[0], backTo)); }} > diff --git a/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx b/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx index 4e425f752e2a..0220311c692a 100644 --- a/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx +++ b/src/pages/settings/Profile/Contacts/ContactMethodsPage.tsx @@ -17,13 +17,13 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; +import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {LoginList, Session} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import * as User from '@userActions/User'; type ContactMethodsPageOnyxProps = { /** Login list for the user that is signed in */ @@ -82,12 +82,11 @@ function ContactMethodsPage({loginList, session, route}: ContactMethodsPageProps title={menuItemTitle} description={description} onPress={() => { - const login = loginList?.[loginName] ?? {}; if (!login?.validatedDate && !login?.validateCodeSent) { User.requestContactMethodValidateCode(loginName); } - Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHOD_DETAILS.getRoute(partnerUserID)) + Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHOD_DETAILS.getRoute(partnerUserID)); }} brickRoadIndicator={indicator} shouldShowBasicTitle From 09a8b0fa81bac5264aa7caadc9f00ba785eea329 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 2 Sep 2024 19:02:34 +0700 Subject: [PATCH 4/5] Remove unnecessary reset validateCodeSent --- .../Profile/Contacts/ContactMethodDetailsPage.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx b/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx index 21321f5e6740..f5979f11949e 100644 --- a/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx +++ b/src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx @@ -132,14 +132,6 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) { User.deleteContactMethod(contactMethod, loginList ?? {}, backTo); }, [contactMethod, loginList, toggleDeleteModal, backTo]); - useEffect(() => { - if (isEmptyObject(loginData)) { - return; - } - User.resetContactMethodValidateCodeSentState(contactMethod); - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, []); - const prevValidatedDate = usePrevious(loginData?.validatedDate); useEffect(() => { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing From 158274bd8a15f09685a91a85128eeb583cf7d477 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 5 Sep 2024 11:00:16 +0700 Subject: [PATCH 5/5] Fix re-sent message flicker --- .../ValidateCodeForm/BaseValidateCodeForm.tsx | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx index 087800232e08..6ec1dbc5d67e 100644 --- a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx +++ b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.tsx @@ -88,7 +88,8 @@ function BaseValidateCodeForm({ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- nullish coalescing doesn't achieve the same result in this case const shouldDisableResendValidateCode = !!isOffline || account?.isLoading; const focusTimeoutRef = useRef(null); - const [validateCodeSentIsPressed, setValidateCodeSentIsPressed] = useState(false); + const validateCodeSentIsPressedRef = useRef(false); + const [showDotIndicator, setShowDotIndicator] = useState(false); useImperativeHandle(innerRef, () => ({ focus() { @@ -144,6 +145,18 @@ function BaseValidateCodeForm({ inputValidateCodeRef.current?.clear(); }, [hasMagicCodeBeenSent]); + useEffect(() => { + // `validateCodeSent` is updated asynchronously, + // and `validateCodeSentIsPressedRef.current` is updated faster than `hasMagicCodeBeenSent`. + // This can cause the component to hide and show the `DotIndicatorMessage` multiple times + // in quick succession, leading to a flickering effect. + if ((hasMagicCodeBeenSent ?? !!pendingContact?.validateCodeSent) && validateCodeSentIsPressedRef.current) { + setShowDotIndicator(true); + } else { + setShowDotIndicator(false); + } + }, [hasMagicCodeBeenSent, pendingContact, validateCodeSentIsPressedRef]); + /** * Request a validate code / magic code be sent to verify this contact method */ @@ -155,9 +168,8 @@ function BaseValidateCodeForm({ } inputValidateCodeRef.current?.clear(); - setValidateCodeSentIsPressed(true); + validateCodeSentIsPressedRef.current = true; }; - /** * Handle text input and clear formError upon text change */ @@ -229,7 +241,7 @@ function BaseValidateCodeForm({ > {translate('validateCodeForm.magicCodeNotReceived')} - {(hasMagicCodeBeenSent ?? !!pendingContact?.validateCodeSent) && validateCodeSentIsPressed && ( + {showDotIndicator && (