From 51af936c63a545ae0379ce2d3ba23074816b391e Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 5 Feb 2024 14:11:47 +0700 Subject: [PATCH 01/14] disable locale picker while signing in --- src/components/LocalePicker.tsx | 14 ++++++++++++-- src/components/Picker/BasePicker.tsx | 14 +++++++++++--- src/components/Picker/types.ts | 6 ++++++ src/styles/index.ts | 4 ++-- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/components/LocalePicker.tsx b/src/components/LocalePicker.tsx index 3a2d9a0fd7b9..d6b8a6ccd40a 100644 --- a/src/components/LocalePicker.tsx +++ b/src/components/LocalePicker.tsx @@ -7,11 +7,14 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as App from '@userActions/App'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Locale} from '@src/types/onyx'; +import type {Account, Locale} from '@src/types/onyx'; import Picker from './Picker'; import type {PickerSize} from './Picker/types'; type LocalePickerOnyxProps = { + /** The details about the account that the user is signing in with */ + account: OnyxEntry; + /** Indicates which locale the user currently has selected */ preferredLocale: OnyxEntry; }; @@ -21,7 +24,7 @@ type LocalePickerProps = LocalePickerOnyxProps & { size?: PickerSize; }; -function LocalePicker({preferredLocale = CONST.LOCALES.DEFAULT, size = 'normal'}: LocalePickerProps) { +function LocalePicker({account, preferredLocale = CONST.LOCALES.DEFAULT, size = 'normal'}: LocalePickerProps) { const theme = useTheme(); const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -31,6 +34,7 @@ function LocalePicker({preferredLocale = CONST.LOCALES.DEFAULT, size = 'normal'} keyForList: language, isSelected: preferredLocale === language, })); + const shouldDisablePicker = account?.isLoading && account.loadingForm === (account.requiresTwoFactorAuth ? CONST.FORMS.VALIDATE_TFA_CODE_FORM : CONST.FORMS.VALIDATE_CODE_FORM); return ( ({ + account: { + key: ONYXKEYS.ACCOUNT, + }, preferredLocale: { key: ONYXKEYS.NVP_PREFERRED_LOCALE, }, diff --git a/src/components/Picker/BasePicker.tsx b/src/components/Picker/BasePicker.tsx index 1bee95532104..720540182452 100644 --- a/src/components/Picker/BasePicker.tsx +++ b/src/components/Picker/BasePicker.tsx @@ -32,7 +32,9 @@ function BasePicker( containerStyles, placeholder = {}, size = 'normal', + shouldAllowDisabledStyle = true, shouldFocusPicker = false, + shouldShowOnlyTextWhenDisabled = true, onBlur = () => {}, additionalPickerEvents = () => {}, }: BasePickerProps, @@ -154,7 +156,7 @@ function BasePicker( const hasError = !!errorText; - if (isDisabled) { + if (isDisabled && shouldShowOnlyTextWhenDisabled) { return ( {!!label && ( @@ -175,14 +177,20 @@ function BasePicker( <> {label && {label}} ({...item, color: itemColor}))} - style={size === 'normal' ? styles.picker(isDisabled, backgroundColor) : styles.pickerSmall(backgroundColor)} + style={size === 'normal' ? styles.picker(isDisabled, backgroundColor) : styles.pickerSmall(isDisabled, backgroundColor)} useNativeAndroidPickerStyle={false} placeholder={pickerPlaceholder} value={value} diff --git a/src/components/Picker/types.ts b/src/components/Picker/types.ts index edf39a59c9d8..d4a0eb0c392b 100644 --- a/src/components/Picker/types.ts +++ b/src/components/Picker/types.ts @@ -69,9 +69,15 @@ type BasePickerProps = { /** The ID used to uniquely identify the input in a Form */ inputID?: string; + /** Show disabled style when disabled */ + shouldAllowDisabledStyle?: boolean; + /** Saves a draft of the input value when used in a form */ shouldSaveDraft?: boolean; + /** Show only picker's label and value when disabled */ + shouldShowOnlyTextWhenDisabled?: boolean; + /** A callback method that is called when the value changes and it receives the selected value as an argument */ onInputChange: (value: TPickerValue, index?: number) => void; diff --git a/src/styles/index.ts b/src/styles/index.ts index 0d4b420c00e4..8d28e80b490f 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -695,7 +695,7 @@ const styles = (theme: ThemeColors) => width: '100%', }, - pickerSmall: (backgroundColor = theme.highlightBG) => + pickerSmall: (disabled = false, backgroundColor = theme.highlightBG) => ({ inputIOS: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE, @@ -737,7 +737,7 @@ const styles = (theme: ThemeColors) => height: 26, opacity: 1, backgroundColor, - ...cursor.cursorPointer, + ...(disabled ? cursor.cursorDisabled : cursor.cursorPointer), }, inputAndroid: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE, From d31d5dc82536a2b7aeb76d19834912fa1f43f4b9 Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 5 Feb 2024 14:13:04 +0700 Subject: [PATCH 02/14] set isDisabled --- src/components/LocalePicker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/LocalePicker.tsx b/src/components/LocalePicker.tsx index d6b8a6ccd40a..8022efd211b0 100644 --- a/src/components/LocalePicker.tsx +++ b/src/components/LocalePicker.tsx @@ -46,7 +46,7 @@ function LocalePicker({account, preferredLocale = CONST.LOCALES.DEFAULT, size = App.setLocale(locale); }} - isDisabled={true} + isDisabled={shouldDisablePicker} items={localesToLanguages} shouldAllowDisabledStyle={false} shouldShowOnlyTextWhenDisabled={false} From 76a2811093232bb11402d650b96bb473f805be01 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 6 Feb 2024 23:24:41 +0700 Subject: [PATCH 03/14] create util function --- src/components/LocalePicker.tsx | 3 ++- src/libs/FormUtils.ts | 7 ++++++- src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/components/LocalePicker.tsx b/src/components/LocalePicker.tsx index 8022efd211b0..17520a467d3c 100644 --- a/src/components/LocalePicker.tsx +++ b/src/components/LocalePicker.tsx @@ -4,6 +4,7 @@ import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import FormUtils from '@libs/FormUtils'; import * as App from '@userActions/App'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -34,7 +35,7 @@ function LocalePicker({account, preferredLocale = CONST.LOCALES.DEFAULT, size = keyForList: language, isSelected: preferredLocale === language, })); - const shouldDisablePicker = account?.isLoading && account.loadingForm === (account.requiresTwoFactorAuth ? CONST.FORMS.VALIDATE_TFA_CODE_FORM : CONST.FORMS.VALIDATE_CODE_FORM); + const shouldDisablePicker = FormUtils.isValidateCodeFormSubmitting(account ?? {}); return ( + account.isLoading && account.loadingForm === (account.requiresTwoFactorAuth ? CONST.FORMS.VALIDATE_TFA_CODE_FORM : CONST.FORMS.VALIDATE_CODE_FORM); function getDraftKey(formID: OnyxFormKeyWithoutDraft): `${OnyxFormKeyWithoutDraft}Draft` { return `${formID}Draft`; } -export default {getDraftKey}; +export default {getDraftKey, isValidateCodeFormSubmitting}; diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js index fd5e9b952612..b1423555ee7d 100755 --- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js @@ -22,6 +22,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; +import FormUtils from '@libs/FormUtils'; import * as ValidationUtils from '@libs/ValidationUtils'; import ChangeExpensifyLoginLink from '@pages/signin/ChangeExpensifyLoginLink'; import Terms from '@pages/signin/Terms'; @@ -105,8 +106,7 @@ function BaseValidateCodeForm(props) { const hasError = Boolean(props.account) && !_.isEmpty(props.account.errors) && !needToClearError; const isLoadingResendValidationForm = props.account.loadingForm === CONST.FORMS.RESEND_VALIDATE_CODE_FORM; const shouldDisableResendValidateCode = props.network.isOffline || props.account.isLoading; - const isValidateCodeFormSubmitting = - props.account.isLoading && props.account.loadingForm === (props.account.requiresTwoFactorAuth ? CONST.FORMS.VALIDATE_TFA_CODE_FORM : CONST.FORMS.VALIDATE_CODE_FORM); + const isValidateCodeFormSubmitting = FormUtils.isValidateCodeFormSubmitting(props.account); useEffect(() => { if (!(inputValidateCodeRef.current && hasError && (props.session.autoAuthState === CONST.AUTO_AUTH_STATE.FAILED || props.account.isLoading))) { From b0ff3ca7e87574ba72dbcf5d32796bff1c86ad71 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 14 Feb 2024 22:14:31 +0700 Subject: [PATCH 04/14] Move to AccountUtils --- src/components/LocalePicker.tsx | 4 ++-- src/libs/AccountUtils.ts | 7 +++++++ src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 src/libs/AccountUtils.ts diff --git a/src/components/LocalePicker.tsx b/src/components/LocalePicker.tsx index 17520a467d3c..5753af9a2a5d 100644 --- a/src/components/LocalePicker.tsx +++ b/src/components/LocalePicker.tsx @@ -4,7 +4,7 @@ import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import FormUtils from '@libs/FormUtils'; +import * as AccountUtils from '@libs/AccountUtils'; import * as App from '@userActions/App'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -35,7 +35,7 @@ function LocalePicker({account, preferredLocale = CONST.LOCALES.DEFAULT, size = keyForList: language, isSelected: preferredLocale === language, })); - const shouldDisablePicker = FormUtils.isValidateCodeFormSubmitting(account ?? {}); + const shouldDisablePicker = AccountUtils.isValidateCodeFormSubmitting(account ?? {}); return ( + account.isLoading && account.loadingForm === (account.requiresTwoFactorAuth ? CONST.FORMS.VALIDATE_TFA_CODE_FORM : CONST.FORMS.VALIDATE_CODE_FORM); + +export {isValidateCodeFormSubmitting}; diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js index f36720a68fe8..a2252f339ca7 100755 --- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js @@ -19,10 +19,10 @@ import usePrevious from '@hooks/usePrevious'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as AccountUtils from '@libs/AccountUtils'; import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; -import FormUtils from '@libs/FormUtils'; import * as ValidationUtils from '@libs/ValidationUtils'; import ChangeExpensifyLoginLink from '@pages/signin/ChangeExpensifyLoginLink'; import Terms from '@pages/signin/Terms'; @@ -106,7 +106,7 @@ function BaseValidateCodeForm(props) { const hasError = Boolean(props.account) && !_.isEmpty(props.account.errors) && !needToClearError; const isLoadingResendValidationForm = props.account.loadingForm === CONST.FORMS.RESEND_VALIDATE_CODE_FORM; const shouldDisableResendValidateCode = props.network.isOffline || props.account.isLoading; - const isValidateCodeFormSubmitting = FormUtils.isValidateCodeFormSubmitting(props.account); + const isValidateCodeFormSubmitting = AccountUtils.isValidateCodeFormSubmitting(props.account); useEffect(() => { if (!(inputValidateCodeRef.current && hasError && (props.session.autoAuthState === CONST.AUTO_AUTH_STATE.FAILED || props.account.isLoading))) { From 27f4dd0fd7f4969084a39d86c8467bdaa5d75130 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 14 Feb 2024 22:21:02 +0700 Subject: [PATCH 05/14] fix lint --- src/components/LocalePicker.tsx | 2 +- src/libs/AccountUtils.ts | 2 +- src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/LocalePicker.tsx b/src/components/LocalePicker.tsx index 5753af9a2a5d..c411ac7a02c9 100644 --- a/src/components/LocalePicker.tsx +++ b/src/components/LocalePicker.tsx @@ -4,7 +4,7 @@ import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as AccountUtils from '@libs/AccountUtils'; +import AccountUtils from '@libs/AccountUtils'; import * as App from '@userActions/App'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/libs/AccountUtils.ts b/src/libs/AccountUtils.ts index 97ddf13f1ad5..96fb634e92d1 100644 --- a/src/libs/AccountUtils.ts +++ b/src/libs/AccountUtils.ts @@ -4,4 +4,4 @@ import type {Account} from '@src/types/onyx'; const isValidateCodeFormSubmitting = (account: Account) => account.isLoading && account.loadingForm === (account.requiresTwoFactorAuth ? CONST.FORMS.VALIDATE_TFA_CODE_FORM : CONST.FORMS.VALIDATE_CODE_FORM); -export {isValidateCodeFormSubmitting}; +export default {isValidateCodeFormSubmitting}; diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js index a2252f339ca7..e88ce68049ba 100755 --- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js @@ -19,7 +19,7 @@ import usePrevious from '@hooks/usePrevious'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as AccountUtils from '@libs/AccountUtils'; +import AccountUtils from '@libs/AccountUtils'; import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; From 36b43f1e7dcc798227b20b606087de29205040df Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 24 Feb 2024 16:28:39 +0700 Subject: [PATCH 06/14] fix perf-test --- src/components/LocalePicker.tsx | 11 ++++------- src/pages/signin/Licenses.tsx | 13 +++++++++++-- src/pages/signin/SignInPage.tsx | 1 + src/pages/signin/SignInPageLayout/Footer.tsx | 10 +++++++--- src/pages/signin/SignInPageLayout/index.tsx | 11 +++++++++-- src/pages/signin/SignInPageLayout/types.ts | 4 ++++ 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/components/LocalePicker.tsx b/src/components/LocalePicker.tsx index c411ac7a02c9..0080213785f2 100644 --- a/src/components/LocalePicker.tsx +++ b/src/components/LocalePicker.tsx @@ -13,14 +13,14 @@ import Picker from './Picker'; import type {PickerSize} from './Picker/types'; type LocalePickerOnyxProps = { - /** The details about the account that the user is signing in with */ - account: OnyxEntry; - /** Indicates which locale the user currently has selected */ preferredLocale: OnyxEntry; }; type LocalePickerProps = LocalePickerOnyxProps & { + /** The details about the account that the user is signing in with */ + account: Account; + /** Indicates size of a picker component and whether to render the label or not */ size?: PickerSize; }; @@ -35,7 +35,7 @@ function LocalePicker({account, preferredLocale = CONST.LOCALES.DEFAULT, size = keyForList: language, isSelected: preferredLocale === language, })); - const shouldDisablePicker = AccountUtils.isValidateCodeFormSubmitting(account ?? {}); + const shouldDisablePicker = AccountUtils.isValidateCodeFormSubmitting(account); return ( ({ - account: { - key: ONYXKEYS.ACCOUNT, - }, preferredLocale: { key: ONYXKEYS.NVP_PREFERRED_LOCALE, }, diff --git a/src/pages/signin/Licenses.tsx b/src/pages/signin/Licenses.tsx index 87271e3df6b2..d705cae197ba 100644 --- a/src/pages/signin/Licenses.tsx +++ b/src/pages/signin/Licenses.tsx @@ -6,10 +6,16 @@ import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; +import {Account} from '@src/types/onyx'; const currentYear = new Date().getFullYear(); -function Licenses() { +type LicensesProps = { + /** The details about the account that the user is signing in with */ + account: Account; +}; + +function Licenses({account}: LicensesProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); return ( @@ -27,7 +33,10 @@ function Licenses() { . - + ); diff --git a/src/pages/signin/SignInPage.tsx b/src/pages/signin/SignInPage.tsx index 6672ccbd0ebc..9519ee763784 100644 --- a/src/pages/signin/SignInPage.tsx +++ b/src/pages/signin/SignInPage.tsx @@ -250,6 +250,7 @@ function SignInPageInner({credentials, account, activeClients = [], preferredLoc testID={SignInPageInner.displayName} > ; +type FooterProps = Pick & { + /** The details about the account that the user is signing in with */ + account: Account; +}; type FooterColumnRow = (LinkProps | PressProps) & { translationPath: TranslationPaths; @@ -143,7 +147,7 @@ const columns = ({navigateFocus = () => {}}: Pick) }, ]; -function Footer({navigateFocus}: FooterProps) { +function Footer({account, navigateFocus}: FooterProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -209,7 +213,7 @@ function Footer({navigateFocus}: FooterProps) { )} {i === 3 && ( - + )} diff --git a/src/pages/signin/SignInPageLayout/index.tsx b/src/pages/signin/SignInPageLayout/index.tsx index b65da7eba0a5..527d4fd3b594 100644 --- a/src/pages/signin/SignInPageLayout/index.tsx +++ b/src/pages/signin/SignInPageLayout/index.tsx @@ -22,6 +22,7 @@ import type {SignInPageLayoutProps, SignInPageLayoutRef} from './types'; function SignInPageLayout( { + account, customHeadline, customHeroBody, shouldShowWelcomeHeader = false, @@ -129,7 +130,10 @@ function SignInPageLayout( customHeadline={customHeadline} customHeroBody={customHeroBody} /> -