From 981c6f0671981753998d2fb8341594b47f2c7778 Mon Sep 17 00:00:00 2001 From: Dmytro Klymenko Date: Sun, 18 Jul 2021 13:36:04 +0300 Subject: [PATCH 01/79] #3770 - persist selected locale --- src/libs/actions/SignInRedirect.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libs/actions/SignInRedirect.js b/src/libs/actions/SignInRedirect.js index 9e7b787afbe1..2284f504847b 100644 --- a/src/libs/actions/SignInRedirect.js +++ b/src/libs/actions/SignInRedirect.js @@ -19,6 +19,12 @@ Onyx.connect({ }, }); +let currentPreferredLocale; +Onyx.connect({ + key: ONYXKEYS.PREFERRED_LOCALE, + callback: val => currentPreferredLocale = val, +}); + /** * Clears the Onyx store and redirects to the sign in page. * Normally this method would live in Session.js, but that would cause a circular dependency with Network.js. @@ -36,12 +42,16 @@ function redirectToSignIn(errorMessage) { } const activeClients = currentActiveClients; + const preferredLocale = currentPreferredLocale; // We must set the authToken to null so we can navigate to "signin" it's not possible to navigate to the route as // it only exists when the authToken is null. Onyx.set(ONYXKEYS.SESSION, {authToken: null}) .then(() => { Onyx.clear().then(() => { + if (preferredLocale) { + Onyx.set(ONYXKEYS.PREFERRED_LOCALE, preferredLocale); + } if (errorMessage) { Onyx.set(ONYXKEYS.SESSION, {error: errorMessage}); } From 800fd63dde93871960a519dac0a52868e6773b01 Mon Sep 17 00:00:00 2001 From: Dmytro Klymenko Date: Sun, 18 Jul 2021 14:23:04 +0300 Subject: [PATCH 02/79] #3770 move LocalePicker to a separate component --- src/components/LocalePicker/index.js | 63 +++++++++++++++++++++++++++ src/pages/settings/PreferencesPage.js | 34 ++------------- 2 files changed, 66 insertions(+), 31 deletions(-) create mode 100644 src/components/LocalePicker/index.js diff --git a/src/components/LocalePicker/index.js b/src/components/LocalePicker/index.js new file mode 100644 index 000000000000..f3bda11b06fc --- /dev/null +++ b/src/components/LocalePicker/index.js @@ -0,0 +1,63 @@ +import React from 'react'; +import {View} from 'react-native'; +import {withOnyx} from 'react-native-onyx'; +import PropTypes from 'prop-types'; +import styles from '../../styles/styles'; +import Picker from '../Picker'; +import compose from '../../libs/compose'; +import {setLocale} from '../../libs/actions/App'; +import withLocalize, {withLocalizePropTypes} from '../withLocalize'; +import ONYXKEYS from '../../ONYXKEYS'; +import CONST from '../../CONST'; + +const propTypes = { + /** Indicates which locale the user currently has selected */ + preferredLocale: PropTypes.string, + + ...withLocalizePropTypes, +}; + +const defaultProps = { + preferredLocale: CONST.DEFAULT_LOCALE, +}; + +const LocalePicker = ({preferredLocale, translate}) => { + const localesToLanguages = { + default: { + value: 'en', + label: translate('preferencesPage.languages.english'), + }, + es: { + value: 'es', + label: translate('preferencesPage.languages.spanish'), + }, + }; + + return ( + + { + if (locale !== preferredLocale) { + setLocale(locale); + } + }} + items={Object.values(localesToLanguages)} + value={preferredLocale} + /> + + ); +}; + + +LocalePicker.defaultProps = defaultProps; +LocalePicker.propTypes = propTypes; +LocalePicker.displayName = 'LocalePicker'; + +export default compose( + withLocalize, + withOnyx({ + preferredLocale: { + key: ONYXKEYS.PREFERRED_LOCALE, + }, + }), +)(LocalePicker); diff --git a/src/pages/settings/PreferencesPage.js b/src/pages/settings/PreferencesPage.js index 3fd50a75a334..b1538f9c5b28 100755 --- a/src/pages/settings/PreferencesPage.js +++ b/src/pages/settings/PreferencesPage.js @@ -4,6 +4,7 @@ import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import HeaderWithCloseButton from '../../components/HeaderWithCloseButton'; +import LocalePicker from '../../components/LocalePicker'; import Navigation from '../../libs/Navigation/Navigation'; import ROUTES from '../../ROUTES'; import ONYXKEYS from '../../ONYXKEYS'; @@ -12,7 +13,6 @@ import Text from '../../components/Text'; import NameValuePair from '../../libs/actions/NameValuePair'; import CONST from '../../CONST'; import {setExpensifyNewsStatus} from '../../libs/actions/User'; -import {setLocale} from '../../libs/actions/App'; import ScreenWrapper from '../../components/ScreenWrapper'; import Switch from '../../components/Switch'; import Picker from '../../components/Picker'; @@ -29,20 +29,16 @@ const propTypes = { expensifyNewsStatus: PropTypes.bool, }), - /** Indicates which locale the user currently has selected */ - preferredLocale: PropTypes.string, - ...withLocalizePropTypes, }; const defaultProps = { priorityMode: CONST.PRIORITY_MODE.DEFAULT, user: {}, - preferredLocale: CONST.DEFAULT_LOCALE, }; const PreferencesPage = ({ - priorityMode, user, translate, preferredLocale, + priorityMode, user, translate, }) => { const priorityModes = { default: { @@ -57,17 +53,6 @@ const PreferencesPage = ({ }, }; - const localesToLanguages = { - default: { - value: 'en', - label: translate('preferencesPage.languages.english'), - }, - es: { - value: 'es', - label: translate('preferencesPage.languages.spanish'), - }, - }; - return ( {translate('preferencesPage.language')} - - { - if (locale !== preferredLocale) { - setLocale(locale); - } - }} - items={Object.values(localesToLanguages)} - value={preferredLocale} - /> - + @@ -142,8 +117,5 @@ export default compose( user: { key: ONYXKEYS.USER, }, - preferredLocale: { - key: ONYXKEYS.PREFERRED_LOCALE, - }, }), )(PreferencesPage); From b2d03e134c882c01955d4528798bc6fa49103cbb Mon Sep 17 00:00:00 2001 From: Dmytro Klymenko Date: Sun, 18 Jul 2021 14:46:20 +0300 Subject: [PATCH 03/79] #3770 add betas permission check + move picker label to new component --- src/CONST.js | 1 + src/components/LocalePicker/index.js | 41 +++++++++++++++++++-------- src/libs/Permissions.js | 9 ++++++ src/pages/settings/PreferencesPage.js | 3 -- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 511ba361a309..5858ca5859f6 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -83,6 +83,7 @@ const CONST = { PAY_WITH_EXPENSIFY: 'payWithExpensify', FREE_PLAN: 'freePlan', DEFAULT_ROOMS: 'defaultRooms', + INTERNATIONALIZATION: 'internationalization', }, BUTTON_STATES: { DEFAULT: 'default', diff --git a/src/components/LocalePicker/index.js b/src/components/LocalePicker/index.js index f3bda11b06fc..e90c70bd9acf 100644 --- a/src/components/LocalePicker/index.js +++ b/src/components/LocalePicker/index.js @@ -4,16 +4,21 @@ import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import styles from '../../styles/styles'; import Picker from '../Picker'; +import Text from '../Text'; import compose from '../../libs/compose'; import {setLocale} from '../../libs/actions/App'; import withLocalize, {withLocalizePropTypes} from '../withLocalize'; import ONYXKEYS from '../../ONYXKEYS'; import CONST from '../../CONST'; +import Permissions from '../../libs/Permissions'; const propTypes = { /** Indicates which locale the user currently has selected */ preferredLocale: PropTypes.string, + /** Beta features list */ + betas: PropTypes.arrayOf(PropTypes.string).isRequired, + ...withLocalizePropTypes, }; @@ -21,7 +26,11 @@ const defaultProps = { preferredLocale: CONST.DEFAULT_LOCALE, }; -const LocalePicker = ({preferredLocale, translate}) => { +const LocalePicker = ({preferredLocale, translate, betas}) => { + if (!Permissions.canUseInternationalization(betas)) { + return null; + } + const localesToLanguages = { default: { value: 'en', @@ -34,17 +43,22 @@ const LocalePicker = ({preferredLocale, translate}) => { }; return ( - - { - if (locale !== preferredLocale) { - setLocale(locale); - } - }} - items={Object.values(localesToLanguages)} - value={preferredLocale} - /> - + <> + + {translate('preferencesPage.language')} + + + { + if (locale !== preferredLocale) { + setLocale(locale); + } + }} + items={Object.values(localesToLanguages)} + value={preferredLocale} + /> + + ); }; @@ -59,5 +73,8 @@ export default compose( preferredLocale: { key: ONYXKEYS.PREFERRED_LOCALE, }, + betas: { + key: ONYXKEYS.BETAS, + }, }), )(LocalePicker); diff --git a/src/libs/Permissions.js b/src/libs/Permissions.js index 7063273b245c..1ca31ce88712 100644 --- a/src/libs/Permissions.js +++ b/src/libs/Permissions.js @@ -51,10 +51,19 @@ function canUseDefaultRooms(betas) { return _.contains(betas, CONST.BETAS.DEFAULT_ROOMS) || canUseAllBetas(betas); } +/** + * @param {Array} betas + * @returns {Boolean} + */ +function canUseInternationalization(betas) { + return _.contains(betas, CONST.BETAS.INTERNATIONALIZATION) || canUseAllBetas(betas); +} + export default { canUseChronos, canUseIOU, canUsePayWithExpensify, canUseFreePlan, canUseDefaultRooms, + canUseInternationalization, }; diff --git a/src/pages/settings/PreferencesPage.js b/src/pages/settings/PreferencesPage.js index b1538f9c5b28..39163cdc4215 100755 --- a/src/pages/settings/PreferencesPage.js +++ b/src/pages/settings/PreferencesPage.js @@ -94,9 +94,6 @@ const PreferencesPage = ({ {priorityModes[priorityMode].description} - - {translate('preferencesPage.language')} - From 86a95500faca895028dc2233923737a2191c0180 Mon Sep 17 00:00:00 2001 From: Dmytro Klymenko Date: Sun, 18 Jul 2021 14:57:05 +0300 Subject: [PATCH 04/79] #3770 add LocalePicker to SignInPageLayout --- src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js | 2 ++ src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js b/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js index 23b169f713b9..34f6bd3c0af9 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js +++ b/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js @@ -7,6 +7,7 @@ import ExpensifyCashLogo from '../../../components/ExpensifyCashLogo'; import Text from '../../../components/Text'; import TermsAndLicenses from '../TermsAndLicenses'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import LocalePicker from '../../../components/LocalePicker'; import compose from '../../../libs/compose'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; @@ -53,6 +54,7 @@ const SignInPageLayoutNarrow = props => ( + ); diff --git a/src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js b/src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js index ff878c4e8c4a..a8396282a09a 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js +++ b/src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js @@ -7,6 +7,7 @@ import Text from '../../../components/Text'; import welcomeScreenshot from '../../../../assets/images/welcome-screenshot.png'; import variables from '../../../styles/variables'; import TermsAndLicenses from '../TermsAndLicenses'; +import LocalePicker from '../../../components/LocalePicker'; import CONST from '../../../CONST'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import TextLink from '../../../components/TextLink'; @@ -48,6 +49,7 @@ const SignInPageLayoutWide = props => ( + Date: Tue, 20 Jul 2021 10:40:11 -0600 Subject: [PATCH 05/79] fix phone style --- src/pages/DetailsPage.js | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/pages/DetailsPage.js b/src/pages/DetailsPage.js index c36129e5d319..91af858f86ee 100755 --- a/src/pages/DetailsPage.js +++ b/src/pages/DetailsPage.js @@ -92,22 +92,11 @@ const DetailsPage = ({ imageStyles={[styles.avatarLarge]} source={details.avatar} /> - {details.displayName && isSMSLogin - ? ( - - - {toLocalPhone(details.displayName)} - - - ) : ( - - {details.displayName || null} - - )} + {details.displayName && ( + + {isSMSLogin ? toLocalPhone(details.displayName) : details.displayName || null} + + )} {details.login ? ( From 0be9de358a0162ef2d29e67dce9c9161d732e414 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 20 Jul 2021 10:47:48 -0600 Subject: [PATCH 06/79] simplify conditional --- src/pages/DetailsPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/DetailsPage.js b/src/pages/DetailsPage.js index 91af858f86ee..9a4966651a67 100755 --- a/src/pages/DetailsPage.js +++ b/src/pages/DetailsPage.js @@ -94,7 +94,7 @@ const DetailsPage = ({ /> {details.displayName && ( - {isSMSLogin ? toLocalPhone(details.displayName) : details.displayName || null} + {isSMSLogin ? toLocalPhone(details.displayName) : details.displayName} )} {details.login ? ( From fce7b22ccc4af341243cd68e2ee811b62c50b748 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Tue, 20 Jul 2021 07:36:23 -1000 Subject: [PATCH 07/79] Fix localize displayname --- .../InvertedFlatList/BaseInvertedFlatList.js | 5 +- src/components/withLocalize.js | 103 +++++++++++------- .../home/report/ReportActionContextMenu.js | 4 +- .../home/report/ReportActionItemSingle.js | 2 + src/pages/home/report/ReportView.js | 1 + 5 files changed, 70 insertions(+), 45 deletions(-) diff --git a/src/components/InvertedFlatList/BaseInvertedFlatList.js b/src/components/InvertedFlatList/BaseInvertedFlatList.js index 4e3c91ee0704..36bcd6c2e88f 100644 --- a/src/components/InvertedFlatList/BaseInvertedFlatList.js +++ b/src/components/InvertedFlatList/BaseInvertedFlatList.js @@ -150,10 +150,7 @@ class BaseInvertedFlatList extends Component { // Web requires that items be measured or else crazy things happen when scrolling. getItemLayout={this.props.shouldMeasureItems ? this.getItemLayout : undefined} bounces={false} - - // We keep this property very low so that chat switching remains fast - maxToRenderPerBatch={1} - windowSize={15} + windowSize={5} removeClippedSubviews={this.props.shouldRemoveClippedSubviews} /> ); diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index 28b9409796d3..69bc1667da35 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import getComponentDisplayName from '../libs/getComponentDisplayName'; -import compose from '../libs/compose'; import ONYXKEYS from '../ONYXKEYS'; import {translate} from '../libs/translate'; import DateUtils from '../libs/DateUtils'; @@ -30,35 +29,65 @@ const withLocalizePropTypes = { fromLocalPhone: PropTypes.func.isRequired, }; -function withLocalizeHOC(WrappedComponent) { - const WithLocalize = (props) => { - const translations = { - translate: (phrase, variables) => translate(props.preferredLocale, phrase, variables), - numberFormat: (number, options) => numberFormat(props.preferredLocale, number, options), - timestampToRelative: timestamp => DateUtils.timestampToRelative(props.preferredLocale, timestamp), - timestampToDateTime: (timestamp, includeTimezone) => DateUtils.timestampToDateTime( - props.preferredLocale, +const withLocalizeHOC = (WrappedComponent) => { + class WithLocalize extends React.Component { + constructor(props) { + super(props); + + this.translate = this.translate.bind(this); + this.numberFormat = this.numberFormat.bind(this); + this.timestampToRelative = this.timestampToRelative.bind(this); + this.timestampToDateTime = this.timestampToDateTime.bind(this); + this.fromLocalPhone = this.fromLocalPhone.bind(this); + this.toLocalPhone = this.toLocalPhone.bind(this); + this.preferredLocale = 'en'; + } + + translate(phrase, variables) { + return translate(this.preferredLocale, phrase, variables); + } + + numberFormat(number, options) { + return numberFormat(this.preferredLocale, number, options); + } + + timestampToRelative(timestamp) { + return DateUtils.timestampToRelative(this.preferredLocale, timestamp); + } + + timestampToDateTime(timestamp, includeTimezone) { + return DateUtils.timestampToDateTime( + this.preferredLocale, timestamp, includeTimezone, - ), - toLocalPhone: number => toLocalPhone(props.preferredLocale, number), - fromLocalPhone: number => fromLocalPhone(props.preferredLocale, number), - }; - return ( - - ); - }; - WithLocalize.displayName = `WithLocalize(${getComponentDisplayName(WrappedComponent)})`; + ); + } + + toLocalPhone(number) { + return toLocalPhone(this.preferredLocale, number); + } + + fromLocalPhone(number) { + return fromLocalPhone(this.preferredLocale, number); + } + + render() { + return ( + + ); + } + } + WithLocalize.propTypes = { preferredLocale: PropTypes.string, forwardedRef: PropTypes.oneOfType([ @@ -70,19 +99,17 @@ function withLocalizeHOC(WrappedComponent) { preferredLocale: CONST.DEFAULT_LOCALE, forwardedRef: undefined, }; - return React.forwardRef((props, ref) => ( + + const withForwardedRef = React.forwardRef((props, ref) => ( // eslint-disable-next-line react/jsx-props-no-spreading )); -} -export default compose( - withOnyx({ - preferredLocale: { - key: ONYXKEYS.PREFERRED_LOCALE, - }, - }), - withLocalizeHOC, -); + + withForwardedRef.displayName = `WithLocalize(${getComponentDisplayName(WrappedComponent)})`; + return withForwardedRef; +}; + +export default withLocalizeHOC; export { withLocalizePropTypes, diff --git a/src/pages/home/report/ReportActionContextMenu.js b/src/pages/home/report/ReportActionContextMenu.js index ca8fcc35b04f..7386c9cd9f62 100755 --- a/src/pages/home/report/ReportActionContextMenu.js +++ b/src/pages/home/report/ReportActionContextMenu.js @@ -197,6 +197,4 @@ class ReportActionContextMenu extends React.Component { ReportActionContextMenu.propTypes = propTypes; ReportActionContextMenu.defaultProps = defaultProps; -export default compose( - withLocalize, -)(ReportActionContextMenu); +export default withLocalize(ReportActionContextMenu); diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 1cf5bf99fce8..84befd28f4c8 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -95,6 +95,8 @@ const ReportActionItemSingle = ({ ReportActionItemSingle.propTypes = propTypes; ReportActionItemSingle.defaultProps = defaultProps; +ReportActionItemSingle.displayName = 'ReportActionItemSingle'; + export default compose( withLocalize, withOnyx({ diff --git a/src/pages/home/report/ReportView.js b/src/pages/home/report/ReportView.js index 8481be201ed8..1eb4ea57589a 100644 --- a/src/pages/home/report/ReportView.js +++ b/src/pages/home/report/ReportView.js @@ -47,6 +47,7 @@ const ReportView = ({reportID, session}) => ( ReportView.propTypes = propTypes; ReportView.defaultProps = defaultProps; +ReportView.displayName = 'ReportView'; export default withOnyx({ session: { From b00c34b91a1f36077a6104ee56fcf7119cc8561d Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Tue, 20 Jul 2021 07:40:30 -1000 Subject: [PATCH 08/79] add Onyx back in --- src/components/withLocalize.js | 53 +++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index 69bc1667da35..b0abd481162f 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -29,7 +29,20 @@ const withLocalizePropTypes = { fromLocalPhone: PropTypes.func.isRequired, }; -const withLocalizeHOC = (WrappedComponent) => { +export default (WrappedComponent) => { + const propTypes = { + preferredLocale: PropTypes.string, + forwardedRef: PropTypes.oneOfType([ + PropTypes.func, + PropTypes.shape({current: PropTypes.instanceOf(React.Component)}), + ]), + }; + + const defaultProps = { + preferredLocale: CONST.DEFAULT_LOCALE, + forwardedRef: undefined, + }; + class WithLocalize extends React.Component { constructor(props) { super(props); @@ -40,35 +53,34 @@ const withLocalizeHOC = (WrappedComponent) => { this.timestampToDateTime = this.timestampToDateTime.bind(this); this.fromLocalPhone = this.fromLocalPhone.bind(this); this.toLocalPhone = this.toLocalPhone.bind(this); - this.preferredLocale = 'en'; } translate(phrase, variables) { - return translate(this.preferredLocale, phrase, variables); + return translate(this.props.preferredLocale, phrase, variables); } numberFormat(number, options) { - return numberFormat(this.preferredLocale, number, options); + return numberFormat(this.props.preferredLocale, number, options); } timestampToRelative(timestamp) { - return DateUtils.timestampToRelative(this.preferredLocale, timestamp); + return DateUtils.timestampToRelative(this.props.preferredLocale, timestamp); } timestampToDateTime(timestamp, includeTimezone) { return DateUtils.timestampToDateTime( - this.preferredLocale, + this.props.preferredLocale, timestamp, includeTimezone, ); } toLocalPhone(number) { - return toLocalPhone(this.preferredLocale, number); + return toLocalPhone(this.props.preferredLocale, number); } fromLocalPhone(number) { - return fromLocalPhone(this.preferredLocale, number); + return fromLocalPhone(this.props.preferredLocale, number); } render() { @@ -88,28 +100,23 @@ const withLocalizeHOC = (WrappedComponent) => { } } - WithLocalize.propTypes = { - preferredLocale: PropTypes.string, - forwardedRef: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({current: PropTypes.instanceOf(React.Component)}), - ]), - }; - WithLocalize.defaultProps = { - preferredLocale: CONST.DEFAULT_LOCALE, - forwardedRef: undefined, - }; + WithLocalize.propTypes = propTypes; + + WithLocalize.defaultProps = defaultProps; const withForwardedRef = React.forwardRef((props, ref) => ( // eslint-disable-next-line react/jsx-props-no-spreading )); - withForwardedRef.displayName = `WithLocalize(${getComponentDisplayName(WrappedComponent)})`; - return withForwardedRef; -}; + withForwardedRef.displayName = `withLocalize(${getComponentDisplayName(WrappedComponent)})`; -export default withLocalizeHOC; + return withOnyx({ + preferredLocale: { + key: ONYXKEYS.PREFERRED_LOCALE, + }, + })(withForwardedRef); +}; export { withLocalizePropTypes, From 82bb5dd55e30e8132d089fb21abb0d30c5df0e3f Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Tue, 20 Jul 2021 07:47:40 -1000 Subject: [PATCH 09/79] remove bad change --- src/components/InvertedFlatList/BaseInvertedFlatList.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/InvertedFlatList/BaseInvertedFlatList.js b/src/components/InvertedFlatList/BaseInvertedFlatList.js index 36bcd6c2e88f..4e3c91ee0704 100644 --- a/src/components/InvertedFlatList/BaseInvertedFlatList.js +++ b/src/components/InvertedFlatList/BaseInvertedFlatList.js @@ -150,7 +150,10 @@ class BaseInvertedFlatList extends Component { // Web requires that items be measured or else crazy things happen when scrolling. getItemLayout={this.props.shouldMeasureItems ? this.getItemLayout : undefined} bounces={false} - windowSize={5} + + // We keep this property very low so that chat switching remains fast + maxToRenderPerBatch={1} + windowSize={15} removeClippedSubviews={this.props.shouldRemoveClippedSubviews} /> ); From b15b302b41927fd2b1e7bfc8e0c7af14e27e048e Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Tue, 20 Jul 2021 08:00:37 -1000 Subject: [PATCH 10/79] add docs --- src/components/withLocalize.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index b0abd481162f..5b2714be8c6c 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -55,18 +55,37 @@ export default (WrappedComponent) => { this.toLocalPhone = this.toLocalPhone.bind(this); } + /** + * @param {String} phrase + * @param {Object} [variables] + * @returns {String} + */ translate(phrase, variables) { return translate(this.props.preferredLocale, phrase, variables); } + /** + * @param {Number} number + * @param {Intl.NumberFormatOptions} options + * @returns {String} + */ numberFormat(number, options) { return numberFormat(this.props.preferredLocale, number, options); } + /** + * @param {Number} timestamp + * @returns {String} + */ timestampToRelative(timestamp) { return DateUtils.timestampToRelative(this.props.preferredLocale, timestamp); } + /** + * @param {Number} timestamp + * @param {Boolean} [includeTimezone] + * @returns {String} + */ timestampToDateTime(timestamp, includeTimezone) { return DateUtils.timestampToDateTime( this.props.preferredLocale, @@ -75,10 +94,18 @@ export default (WrappedComponent) => { ); } + /** + * @param {Number} number + * @returns {String} + */ toLocalPhone(number) { return toLocalPhone(this.props.preferredLocale, number); } + /** + * @param {Number} number + * @returns {String} + */ fromLocalPhone(number) { return fromLocalPhone(this.props.preferredLocale, number); } @@ -101,7 +128,6 @@ export default (WrappedComponent) => { } WithLocalize.propTypes = propTypes; - WithLocalize.defaultProps = defaultProps; const withForwardedRef = React.forwardRef((props, ref) => ( From 4fc6270e2095f05fa703909ffa6ad2aaa8d4c493 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Tue, 20 Jul 2021 08:03:59 -1000 Subject: [PATCH 11/79] fix style --- src/pages/home/report/ReportActionContextMenu.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/home/report/ReportActionContextMenu.js b/src/pages/home/report/ReportActionContextMenu.js index 7386c9cd9f62..f7e0b7f63d71 100755 --- a/src/pages/home/report/ReportActionContextMenu.js +++ b/src/pages/home/report/ReportActionContextMenu.js @@ -14,7 +14,6 @@ import { import ContextMenuItem from '../../../components/ContextMenuItem'; import ReportActionPropTypes from './ReportActionPropTypes'; import Clipboard from '../../../libs/Clipboard'; -import compose from '../../../libs/compose'; import {isReportMessageAttachment, canEditReportAction, canDeleteReportAction} from '../../../libs/reportUtils'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import ReportActionComposeFocusManager from '../../../libs/ReportActionComposeFocusManager'; From 79931f7ea412c44d02bafd66dc9a9b827a0dbb6f Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Tue, 20 Jul 2021 08:12:26 -1000 Subject: [PATCH 12/79] add missing docs to propTypes --- src/components/withLocalize.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index 5b2714be8c6c..1bf30d50e5db 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -31,7 +31,10 @@ const withLocalizePropTypes = { export default (WrappedComponent) => { const propTypes = { + /** The user's preferred locale e.g. en or es */ preferredLocale: PropTypes.string, + + /** Passed ref from whatever component is wrapped in the HOC */ forwardedRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({current: PropTypes.instanceOf(React.Component)}), From 67e0a87183f96c005ed7af7f05bcd0d13f549ddb Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Tue, 20 Jul 2021 08:13:15 -1000 Subject: [PATCH 13/79] fix docs --- src/components/withLocalize.js | 2 +- src/libs/LocalePhoneNumber.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js index 1bf30d50e5db..daa35a12c41d 100755 --- a/src/components/withLocalize.js +++ b/src/components/withLocalize.js @@ -31,7 +31,7 @@ const withLocalizePropTypes = { export default (WrappedComponent) => { const propTypes = { - /** The user's preferred locale e.g. en or es */ + /** The user's preferred locale e.g. 'en', 'es-ES' */ preferredLocale: PropTypes.string, /** Passed ref from whatever component is wrapped in the HOC */ diff --git a/src/libs/LocalePhoneNumber.js b/src/libs/LocalePhoneNumber.js index 4d51e711d705..3d47e7c6a5a9 100644 --- a/src/libs/LocalePhoneNumber.js +++ b/src/libs/LocalePhoneNumber.js @@ -10,7 +10,7 @@ import translations from '../languages/translations'; * * @param {String} locale eg 'en', 'es-ES' * @param {String} number - * @returns {string} + * @returns {String} */ function toLocalPhone(locale, number) { const numString = lodashTrim(number); @@ -31,7 +31,7 @@ function toLocalPhone(locale, number) { * * @param {String} locale eg 'en', 'es-ES' * @param {String} number - * @returns {string} + * @returns {String} */ function fromLocalPhone(locale, number) { const numString = lodashTrim(number); From e5974e6cae4faa17d8ac544f2d25dab1aff34b04 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 20 Jul 2021 12:57:31 -0600 Subject: [PATCH 14/79] fix style --- src/components/CommunicationsLink.js | 13 ++++++------- src/pages/DetailsPage.js | 2 +- src/styles/styles.js | 6 ++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/components/CommunicationsLink.js b/src/components/CommunicationsLink.js index c60ced905fc8..bbaa924ebc08 100644 --- a/src/components/CommunicationsLink.js +++ b/src/components/CommunicationsLink.js @@ -44,16 +44,15 @@ const CommunicationsLink = props => ( > {props.children} - ) - : props.children} - {!props.isSmallScreenWidth - && ( + ) : ( + {props.children} )} {details.login ? ( - + {translate(isSMSLogin ? 'common.phoneNumber' diff --git a/src/styles/styles.js b/src/styles/styles.js index 854cef4d0049..40cf62fd509d 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1793,10 +1793,8 @@ const styles = { ...whiteSpace.noWrap, }, - communicationsLinkIcon: { - right: -36, - top: 0, - bottom: 0, + communicationsLinkHeight: { + height: 20, }, }; From 84c6065bd6b38d76e4187d3cdd208c0eb2966276 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jul 2021 08:52:31 +0300 Subject: [PATCH 15/79] escape key dismiss modal instead of go back --- src/components/ScreenWrapper.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/ScreenWrapper.js b/src/components/ScreenWrapper.js index 094b8b597fdd..f3ac8a258d06 100644 --- a/src/components/ScreenWrapper.js +++ b/src/components/ScreenWrapper.js @@ -8,6 +8,7 @@ import styles, {getSafeAreaPadding} from '../styles/styles'; import HeaderGap from './HeaderGap'; import KeyboardShortcut from '../libs/KeyboardShortcut'; import onScreenTransitionEnd from '../libs/onScreenTransitionEnd'; +import Navigation from '../libs/Navigation/Navigation'; const propTypes = { /** Array of additional styles to add */ @@ -32,9 +33,6 @@ const propTypes = { navigation: PropTypes.shape({ // Method to attach listener to Navigation state. addListener: PropTypes.func.isRequired, - - // Returns to the previous navigation state e.g. if this is inside a Modal we will dismiss it - goBack: PropTypes.func, }), }; @@ -45,7 +43,6 @@ const defaultProps = { onTransitionEnd: () => {}, navigation: { addListener: () => {}, - goBack: () => {}, }, }; @@ -59,7 +56,7 @@ class ScreenWrapper extends React.Component { componentDidMount() { this.unsubscribeEscapeKey = KeyboardShortcut.subscribe('Escape', () => { - this.props.navigation.goBack(); + Navigation.dismissModal(); }, [], true); this.unsubscribeTransitionEnd = onScreenTransitionEnd(this.props.navigation, () => { From 19f6f4f0b5838ff1befd3150fb38a78405f4290c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jul 2021 09:22:14 +0300 Subject: [PATCH 16/79] pop keyboard event --- src/libs/KeyboardShortcut/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 3cc302801e99..00d39ceaf109 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -126,7 +126,7 @@ const KeyboardShortcut = { */ unsubscribe(key) { const keyCode = this.getKeyCode(key); - delete events[keyCode]; + events[keyCode].pop(); }, }; From 8823c72026959fdd5a7057f6a49aa27997dc9cd4 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jul 2021 09:36:07 +0300 Subject: [PATCH 17/79] loop eventCallbacks in reverese, and return early --- src/libs/KeyboardShortcut/index.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 00d39ceaf109..5e0dc2c6ec7c 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -12,9 +12,10 @@ function bindHandlerToKeyupEvent(event) { } const eventCallbacks = events[event.keyCode]; + const reversedEventCallbacks = [...eventCallbacks].reverse(); // Loop over all the callbacks - eventCallbacks.forEach((callback) => { + _.every(reversedEventCallbacks, (callback) => { const pressedModifiers = _.all(callback.modifiers, (modifier) => { if (modifier === 'shift' && !event.shiftKey) { return false; @@ -50,7 +51,7 @@ function bindHandlerToKeyupEvent(event) { return false; }); if (!pressedModifiers || pressedExtraModifiers) { - return; + return true; } // If configured to do so, prevent input text control to trigger this event @@ -59,13 +60,16 @@ function bindHandlerToKeyupEvent(event) { || event.target.nodeName === 'TEXTAREA' || event.target.contentEditable === 'true' )) { - return; + return true; } if (_.isFunction(callback.callback)) { callback.callback(event); } event.preventDefault(); + + // Short circuit the loop because the event is triggered + return false; }); } From 39b389a71d666172ac46671d2cb90ed0838cae1a Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jul 2021 09:54:13 +0300 Subject: [PATCH 18/79] make unsubscribe private, refactor --- src/libs/KeyboardShortcut/index.js | 91 ++++++++++++++++-------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 5e0dc2c6ec7c..1f82b4cab687 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -5,6 +5,7 @@ const events = {}; /** * Checks if an event for that key is configured and if so, runs it. * @param {Event} event + * @private */ function bindHandlerToKeyupEvent(event) { if (events[event.keyCode] === undefined) { @@ -77,6 +78,52 @@ function bindHandlerToKeyupEvent(event) { document.removeEventListener('keydown', bindHandlerToKeyupEvent, {capture: true}); document.addEventListener('keydown', bindHandlerToKeyupEvent, {capture: true}); +/** + * Returns keyCode for a given key + * @param {String} key The key to watch, i.e. 'K' or 'Escape' + * @returns {Number} The key's keyCode, i.e. 75 or 27 + * @private + */ +function getKeyCode(key) { + // For keys that have longer names we must catch and return the correct key key.charCodeAt(0) would return the + // key code for 'E' (the letter at index 0 in the string) not 'Escape' + switch (key) { + case 'Enter': + return 13; + case 'Escape': + return 27; + default: + return key.charCodeAt(0); + } +} + +/** + * Unsubscribes to a keyboard event. + * @param {Number} key The key to stop watching + * @private + */ +function unsubscribe(key) { + const keyCode = getKeyCode(key); + events[keyCode].pop(); +} + +/** + * Subscribes to a keyboard event. + * @param {String} key The key to watch, i.e. 'K' or 'Escape' + * @param {Function} callback The callback to call + * @param {String|Array} modifiers Can either be shift or control + * @param {Boolean} captureOnInputs Should we capture the event on inputs too? + * @returns {Function} clean up method + */ +function subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { + const keyCode = getKeyCode(key); + if (events[keyCode] === undefined) { + events[keyCode] = []; + } + events[keyCode].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); + return () => unsubscribe(key); +} + /** * Module storing the different keyboard shortcut * @@ -89,49 +136,7 @@ document.addEventListener('keydown', bindHandlerToKeyupEvent, {capture: true}); * The "subClass" is used by pages to bind /unbind with no worries */ const KeyboardShortcut = { - /** - * Returns keyCode for a given key - * @param {String} key The key to watch, i.e. 'K' or 'Escape' - * @returns {Number} The key's keyCode, i.e. 75 or 27 - */ - getKeyCode(key) { - // For keys that have longer names we must catch and return the correct key key.charCodeAt(0) would return the - // key code for 'E' (the letter at index 0 in the string) not 'Escape' - switch (key) { - case 'Enter': - return 13; - case 'Escape': - return 27; - default: - return key.charCodeAt(0); - } - }, - - /** - * Subscribes to a keyboard event. - * @param {String} key The key to watch, i.e. 'K' or 'Escape' - * @param {Function} callback The callback to call - * @param {String|Array} modifiers Can either be shift or control - * @param {Boolean} captureOnInputs Should we capture the event on inputs too? - * @returns {Function} clean up method - */ - subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { - const keyCode = this.getKeyCode(key); - if (events[keyCode] === undefined) { - events[keyCode] = []; - } - events[keyCode].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); - return () => this.unsubscribe(key); - }, - - /** - * Unsubscribes to a keyboard event. - * @param {Number} key The key to stop watching - */ - unsubscribe(key) { - const keyCode = this.getKeyCode(key); - events[keyCode].pop(); - }, + subscribe, }; export default KeyboardShortcut; From 4e0c12f3780f44b1668b9346a4ac3e68d6169b3a Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jul 2021 09:54:57 +0300 Subject: [PATCH 19/79] refactor AuthScreen KeyboardShortcut --- .../Navigation/AppNavigator/AuthScreens.js | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index ff370c7ef42e..9ed32a56da1e 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -174,24 +174,23 @@ class AuthScreens extends React.Component { Timing.end(CONST.TIMING.HOMEPAGE_INITIAL_RENDER); + let searchShortcutModifiers = ['control']; + let groupShortcutModifiers = ['control', 'shift']; + + if (getOperatingSystem() === CONST.OS.MAC_OS) { + searchShortcutModifiers = ['meta']; + groupShortcutModifiers = ['meta', 'shift']; + } + // Listen for the key K being pressed so that focus can be given to // the chat switcher, or new group chat // based on the key modifiers pressed and the operating system - if (getOperatingSystem() === CONST.OS.MAC_OS) { - KeyboardShortcut.subscribe('K', () => { - Navigation.navigate(ROUTES.SEARCH); - }, ['meta'], true); - KeyboardShortcut.subscribe('K', () => { - Navigation.navigate(ROUTES.NEW_GROUP); - }, ['meta', 'shift'], true); - } else { - KeyboardShortcut.subscribe('K', () => { - Navigation.navigate(ROUTES.SEARCH); - }, ['control'], true); - KeyboardShortcut.subscribe('K', () => { - Navigation.navigate(ROUTES.NEW_GROUP); - }, ['control', 'shift'], true); - } + this.unsubscribeSearchShortcut = KeyboardShortcut.subscribe('K', () => { + Navigation.navigate(ROUTES.SEARCH); + }, searchShortcutModifiers, true); + this.unsubscribeGroupShortcut = KeyboardShortcut.subscribe('K', () => { + Navigation.navigate(ROUTES.NEW_GROUP); + }, groupShortcutModifiers, true); } shouldComponentUpdate(nextProps) { @@ -211,7 +210,12 @@ class AuthScreens extends React.Component { } componentWillUnmount() { - KeyboardShortcut.unsubscribe('K'); + if (this.unsubscribeSearchShortcut) { + this.unsubscribeSearchShortcut(); + } + if (this.unsubscribeGroupShortcut) { + this.unsubscribeGroupShortcut(); + } NetworkConnection.stopListeningForReconnect(); clearInterval(this.interval); this.interval = null; From f6bd991a8a31a0dbc476ab246baad7c9bcc7d02e Mon Sep 17 00:00:00 2001 From: Dmytro Klymenko Date: Wed, 21 Jul 2021 11:47:40 +0300 Subject: [PATCH 20/79] #3770 create small picker for locale selector on sign in page --- src/components/LocalePicker/index.js | 33 ++++++----- src/components/Picker/PickerPropTypes.js | 4 ++ src/components/Picker/index.js | 36 +++++++----- src/pages/settings/PreferencesPage.js | 4 +- .../SignInPageLayoutNarrow.js | 2 - .../SignInPageLayout/SignInPageLayoutWide.js | 2 - .../TermsWithLicenses/index.android.js | 7 +++ .../TermsWithLicenses/index.ios.js | 7 +++ .../TermsWithLicenses/index.js | 8 ++- src/styles/styles.js | 56 +++++++++++++++++++ 10 files changed, 124 insertions(+), 35 deletions(-) diff --git a/src/components/LocalePicker/index.js b/src/components/LocalePicker/index.js index e90c70bd9acf..89c9c111cbb8 100644 --- a/src/components/LocalePicker/index.js +++ b/src/components/LocalePicker/index.js @@ -1,5 +1,4 @@ import React from 'react'; -import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import styles from '../../styles/styles'; @@ -16,6 +15,9 @@ const propTypes = { /** Indicates which locale the user currently has selected */ preferredLocale: PropTypes.string, + /** Indicates size of a picker component and whether to render the label or not */ + size: PropTypes.oneOf(['normal', 'small']), + /** Beta features list */ betas: PropTypes.arrayOf(PropTypes.string).isRequired, @@ -24,9 +26,12 @@ const propTypes = { const defaultProps = { preferredLocale: CONST.DEFAULT_LOCALE, + size: 'normal', }; -const LocalePicker = ({preferredLocale, translate, betas}) => { +const LocalePicker = ({ + preferredLocale, translate, betas, size, +}) => { if (!Permissions.canUseInternationalization(betas)) { return null; } @@ -44,25 +49,25 @@ const LocalePicker = ({preferredLocale, translate, betas}) => { return ( <> + {size === 'normal' && ( {translate('preferencesPage.language')} - - { - if (locale !== preferredLocale) { - setLocale(locale); - } - }} - items={Object.values(localesToLanguages)} - value={preferredLocale} - /> - + )} + { + if (locale !== preferredLocale) { + setLocale(locale); + } + }} + items={Object.values(localesToLanguages)} + size={size} + value={preferredLocale} + /> ); }; - LocalePicker.defaultProps = defaultProps; LocalePicker.propTypes = propTypes; LocalePicker.displayName = 'LocalePicker'; diff --git a/src/components/Picker/PickerPropTypes.js b/src/components/Picker/PickerPropTypes.js index 633966a2bef4..631194544414 100644 --- a/src/components/Picker/PickerPropTypes.js +++ b/src/components/Picker/PickerPropTypes.js @@ -36,6 +36,9 @@ const propTypes = { /** An icon to display with the picker */ icon: PropTypes.func, + + /** Size of a picker component */ + size: PropTypes.oneOf(['normal', 'small']), }; const defaultProps = { useDisabledStyles: false, @@ -43,6 +46,7 @@ const defaultProps = { placeholder: {}, value: null, icon: () => , + size: 'normal', }; export { diff --git a/src/components/Picker/index.js b/src/components/Picker/index.js index 427d38184ef3..dd0370c69999 100644 --- a/src/components/Picker/index.js +++ b/src/components/Picker/index.js @@ -13,19 +13,29 @@ const Picker = ({ value, icon, disabled, -}) => ( - -); + size, +}) => { + let pickerStyles; + if (size === 'small') { + pickerStyles = styles.pickerSmall; + } else { + pickerStyles = useDisabledStyles ? pickerDisabledStyles : styles.picker; + } + + return ( + + ); +}; Picker.propTypes = pickerPropTypes.propTypes; Picker.defaultProps = pickerPropTypes.defaultProps; diff --git a/src/pages/settings/PreferencesPage.js b/src/pages/settings/PreferencesPage.js index 39163cdc4215..03e8c23c017c 100755 --- a/src/pages/settings/PreferencesPage.js +++ b/src/pages/settings/PreferencesPage.js @@ -94,7 +94,9 @@ const PreferencesPage = ({ {priorityModes[priorityMode].description} - + + + diff --git a/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js b/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js index 34f6bd3c0af9..23b169f713b9 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js +++ b/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js @@ -7,7 +7,6 @@ import ExpensifyCashLogo from '../../../components/ExpensifyCashLogo'; import Text from '../../../components/Text'; import TermsAndLicenses from '../TermsAndLicenses'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; -import LocalePicker from '../../../components/LocalePicker'; import compose from '../../../libs/compose'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; @@ -54,7 +53,6 @@ const SignInPageLayoutNarrow = props => ( - ); diff --git a/src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js b/src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js index a8396282a09a..ff878c4e8c4a 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js +++ b/src/pages/signin/SignInPageLayout/SignInPageLayoutWide.js @@ -7,7 +7,6 @@ import Text from '../../../components/Text'; import welcomeScreenshot from '../../../../assets/images/welcome-screenshot.png'; import variables from '../../../styles/variables'; import TermsAndLicenses from '../TermsAndLicenses'; -import LocalePicker from '../../../components/LocalePicker'; import CONST from '../../../CONST'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import TextLink from '../../../components/TextLink'; @@ -49,7 +48,6 @@ const SignInPageLayoutWide = props => ( - ( @@ -61,6 +62,12 @@ const TermsWithLicenses = ({translate}) => ( . + + + + ); diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js index 720c89434bf3..7f8e6dd64218 100644 --- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js +++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js @@ -7,6 +7,7 @@ import withLocalize, { withLocalizePropTypes, } from '../../../../components/withLocalize'; import LogoWordmark from '../../../../../assets/images/expensify-wordmark.svg'; +import LocalePicker from '../../../../components/LocalePicker'; const TermsWithLicenses = ({translate}) => ( @@ -67,6 +68,12 @@ const TermsWithLicenses = ({translate}) => ( . + + + + ); diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js index 175bda985afc..6b332da1ec3c 100755 --- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js +++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js @@ -7,12 +7,10 @@ import withLocalize, { withLocalizePropTypes, } from '../../../../components/withLocalize'; import LogoWordmark from '../../../../../assets/images/expensify-wordmark.svg'; +import LocalePicker from '../../../../components/LocalePicker'; const TermsWithLicenses = ({translate}) => ( - - - {translate('termsOfUse.phrase1')} {' '} @@ -45,6 +43,10 @@ const TermsWithLicenses = ({translate}) => ( . + + + + ); diff --git a/src/styles/styles.js b/src/styles/styles.js index 854cef4d0049..9d533bd3c0ca 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -333,6 +333,62 @@ const styles = { }, }, + pickerSmall: { + inputIOS: { + fontFamily: fontFamily.GTA, + fontSize: variables.fontSizeSmall, + paddingLeft: 10, + paddingRight: 26, + paddingTop: 6, + paddingBottom: 6, + borderRadius: variables.componentBorderRadius, + borderWidth: 1, + borderColor: themeColors.border, + color: themeColors.text, + height: variables.componentSizeSmall, + opacity: 1, + backgroundColor: 'transparent', + }, + inputWeb: { + fontFamily: fontFamily.GTA, + fontSize: variables.fontSizeSmall, + paddingLeft: 10, + paddingRight: 26, + paddingTop: 6, + paddingBottom: 6, + borderWidth: 1, + borderRadius: variables.componentBorderRadius, + borderColor: themeColors.border, + color: themeColors.text, + appearance: 'none', + height: variables.componentSizeSmall, + opacity: 1, + cursor: 'pointer', + backgroundColor: 'transparent', + }, + inputAndroid: { + fontFamily: fontFamily.GTA, + fontSize: variables.fontSizeSmall, + paddingLeft: 10, + paddingRight: 26, + paddingTop: 6, + paddingBottom: 6, + borderWidth: 1, + borderRadius: variables.componentBorderRadius, + borderColor: themeColors.border, + color: themeColors.text, + height: variables.componentSizeSmall, + opacity: 1, + }, + iconContainer: { + top: 8, + right: 13, + width: variables.iconSizeExtraSmall, + height: variables.iconSizeExtraSmall, + pointerEvents: 'none', + }, + }, + badge: { backgroundColor: themeColors.badgeDefaultBG, borderRadius: 14, From b465606ef6a9be5ecdf7955e195c3dd5af5b7787 Mon Sep 17 00:00:00 2001 From: Dmytro Klymenko Date: Wed, 21 Jul 2021 14:34:32 +0300 Subject: [PATCH 21/79] #3770 fix arrow on native --- assets/images/down-small.svg | 3 +++ src/components/Icon/Expensicons.js | 2 ++ src/components/LocalePicker/index.js | 3 ++- src/components/Picker/PickerPropTypes.js | 21 ++++++++++++++++++--- src/components/Picker/index.js | 2 +- src/styles/styles.js | 18 ++++++++---------- 6 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 assets/images/down-small.svg diff --git a/assets/images/down-small.svg b/assets/images/down-small.svg new file mode 100644 index 000000000000..d0de7b1a4425 --- /dev/null +++ b/assets/images/down-small.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js index 42c8dc079b0f..84946a053e7b 100644 --- a/src/components/Icon/Expensicons.js +++ b/src/components/Icon/Expensicons.js @@ -13,6 +13,7 @@ import Clipboard from '../../../assets/images/clipboard.svg'; import Close from '../../../assets/images/close.svg'; import CreditCard from '../../../assets/images/creditcard.svg'; import DownArrow from '../../../assets/images/down.svg'; +import DownArrowSmall from '../../../assets/images/down-small.svg'; import Download from '../../../assets/images/download.svg'; import Emoji from '../../../assets/images/emoji.svg'; import Exclamation from '../../../assets/images/exclamation.svg'; @@ -68,6 +69,7 @@ export { Close, CreditCard, DownArrow, + DownArrowSmall, Download, Emoji, Exclamation, diff --git a/src/components/LocalePicker/index.js b/src/components/LocalePicker/index.js index 89c9c111cbb8..604f5a0cd136 100644 --- a/src/components/LocalePicker/index.js +++ b/src/components/LocalePicker/index.js @@ -19,7 +19,7 @@ const propTypes = { size: PropTypes.oneOf(['normal', 'small']), /** Beta features list */ - betas: PropTypes.arrayOf(PropTypes.string).isRequired, + betas: PropTypes.arrayOf(PropTypes.string), ...withLocalizePropTypes, }; @@ -27,6 +27,7 @@ const propTypes = { const defaultProps = { preferredLocale: CONST.DEFAULT_LOCALE, size: 'normal', + betas: [], }; const LocalePicker = ({ diff --git a/src/components/Picker/PickerPropTypes.js b/src/components/Picker/PickerPropTypes.js index 631194544414..4cb8f063b682 100644 --- a/src/components/Picker/PickerPropTypes.js +++ b/src/components/Picker/PickerPropTypes.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import Icon from '../Icon'; -import {DownArrow} from '../Icon/Expensicons'; +import {DownArrow, DownArrowSmall} from '../Icon/Expensicons'; const propTypes = { /** A callback method that is called when the value changes and it received the selected value as an argument */ @@ -45,8 +45,23 @@ const defaultProps = { disabled: false, placeholder: {}, value: null, - icon: () => , - size: 'normal', + icon: size => ( + <> + {size === 'small' + ? ( + + ) + : ( + + )} + + ), }; export { diff --git a/src/components/Picker/index.js b/src/components/Picker/index.js index dd0370c69999..b963c81601b8 100644 --- a/src/components/Picker/index.js +++ b/src/components/Picker/index.js @@ -30,7 +30,7 @@ const Picker = ({ useNativeAndroidPickerStyle={false} placeholder={placeholder} value={value} - Icon={icon} + Icon={() => icon(size)} disabled={disabled} fixAndroidTouchableBug /> diff --git a/src/styles/styles.js b/src/styles/styles.js index 9d533bd3c0ca..acf4e8f3d83d 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -337,8 +337,8 @@ const styles = { inputIOS: { fontFamily: fontFamily.GTA, fontSize: variables.fontSizeSmall, - paddingLeft: 10, - paddingRight: 26, + paddingLeft: 9, + paddingRight: 25, paddingTop: 6, paddingBottom: 6, borderRadius: variables.componentBorderRadius, @@ -352,8 +352,8 @@ const styles = { inputWeb: { fontFamily: fontFamily.GTA, fontSize: variables.fontSizeSmall, - paddingLeft: 10, - paddingRight: 26, + paddingLeft: 9, + paddingRight: 25, paddingTop: 6, paddingBottom: 6, borderWidth: 1, @@ -369,8 +369,8 @@ const styles = { inputAndroid: { fontFamily: fontFamily.GTA, fontSize: variables.fontSizeSmall, - paddingLeft: 10, - paddingRight: 26, + paddingLeft: 9, + paddingRight: 25, paddingTop: 6, paddingBottom: 6, borderWidth: 1, @@ -381,10 +381,8 @@ const styles = { opacity: 1, }, iconContainer: { - top: 8, - right: 13, - width: variables.iconSizeExtraSmall, - height: variables.iconSizeExtraSmall, + top: 7, + right: 9, pointerEvents: 'none', }, }, From c59ac05a1a7cf9669b281e972f7369e15803ef51 Mon Sep 17 00:00:00 2001 From: Dmytro Klymenko Date: Wed, 21 Jul 2021 14:55:38 +0300 Subject: [PATCH 22/79] #3770 remove duplicate logo watermark on native --- .../signin/TermsAndLicenses/TermsWithLicenses/index.android.js | 3 --- .../signin/TermsAndLicenses/TermsWithLicenses/index.ios.js | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js index 617ace48ab9c..c7e34d7143de 100644 --- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js +++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js @@ -11,9 +11,6 @@ import LocalePicker from '../../../../components/LocalePicker'; const TermsWithLicenses = ({translate}) => ( - - - ( - - - Date: Wed, 21 Jul 2021 18:42:21 +0300 Subject: [PATCH 23/79] #3770 make legal text aligned to the left --- .../signin/TermsAndLicenses/TermsWithLicenses/index.android.js | 1 - .../signin/TermsAndLicenses/TermsWithLicenses/index.ios.js | 1 - src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js index c7e34d7143de..4ef064130e71 100644 --- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js +++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js @@ -18,7 +18,6 @@ const TermsWithLicenses = ({translate}) => ( styles.flexWrap, styles.textAlignCenter, styles.alignItemsCenter, - styles.justifyContentCenter, ]} > diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js index 3f7abd8d12d6..4851ec32cb30 100644 --- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js +++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js @@ -18,7 +18,6 @@ const TermsWithLicenses = ({translate}) => ( styles.flexWrap, styles.textAlignCenter, styles.alignItemsCenter, - styles.justifyContentCenter, ]} > diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js index 6b332da1ec3c..a022e771f31b 100755 --- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js +++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js @@ -11,7 +11,7 @@ import LocalePicker from '../../../../components/LocalePicker'; const TermsWithLicenses = ({translate}) => ( - + {translate('termsOfUse.phrase1')} {' '} Date: Wed, 21 Jul 2021 18:59:13 +0300 Subject: [PATCH 24/79] #3770 fix left align for legal text on ios --- .../signin/TermsAndLicenses/TermsWithLicenses/index.ios.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js index 4851ec32cb30..f884c94d7d8e 100644 --- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js +++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js @@ -17,7 +17,7 @@ const TermsWithLicenses = ({translate}) => ( styles.flexColumn, styles.flexWrap, styles.textAlignCenter, - styles.alignItemsCenter, + styles.justifyContentCenter, ]} > From ed94eb9ac15993bd87d84826fcf9b864f15c87a9 Mon Sep 17 00:00:00 2001 From: Dmytro Klymenko Date: Wed, 21 Jul 2021 19:39:36 +0300 Subject: [PATCH 25/79] #3770 reuse existing down arrow asset --- assets/images/down-small.svg | 3 --- src/components/Icon/Expensicons.js | 2 -- src/components/Picker/PickerPropTypes.js | 4 ++-- 3 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 assets/images/down-small.svg diff --git a/assets/images/down-small.svg b/assets/images/down-small.svg deleted file mode 100644 index d0de7b1a4425..000000000000 --- a/assets/images/down-small.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js index 84946a053e7b..42c8dc079b0f 100644 --- a/src/components/Icon/Expensicons.js +++ b/src/components/Icon/Expensicons.js @@ -13,7 +13,6 @@ import Clipboard from '../../../assets/images/clipboard.svg'; import Close from '../../../assets/images/close.svg'; import CreditCard from '../../../assets/images/creditcard.svg'; import DownArrow from '../../../assets/images/down.svg'; -import DownArrowSmall from '../../../assets/images/down-small.svg'; import Download from '../../../assets/images/download.svg'; import Emoji from '../../../assets/images/emoji.svg'; import Exclamation from '../../../assets/images/exclamation.svg'; @@ -69,7 +68,6 @@ export { Close, CreditCard, DownArrow, - DownArrowSmall, Download, Emoji, Exclamation, diff --git a/src/components/Picker/PickerPropTypes.js b/src/components/Picker/PickerPropTypes.js index 4cb8f063b682..e7140b0bef5a 100644 --- a/src/components/Picker/PickerPropTypes.js +++ b/src/components/Picker/PickerPropTypes.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import Icon from '../Icon'; -import {DownArrow, DownArrowSmall} from '../Icon/Expensicons'; +import {DownArrow} from '../Icon/Expensicons'; const propTypes = { /** A callback method that is called when the value changes and it received the selected value as an argument */ @@ -52,7 +52,7 @@ const defaultProps = { ) : ( From 62e3786d4085218bc6a92dd866864ab157b89a75 Mon Sep 17 00:00:00 2001 From: Rafael Date: Wed, 21 Jul 2021 23:21:39 -0300 Subject: [PATCH 26/79] avoid keyboard, moves error message --- src/pages/signin/LoginForm.js | 18 +++---- src/pages/signin/PasswordForm.js | 18 +++++-- src/pages/signin/ResendValidationForm.js | 11 ++-- src/pages/signin/SignInPage.js | 15 +----- .../SignInPageLayoutNarrow.js | 53 ++++++++++--------- 5 files changed, 55 insertions(+), 60 deletions(-) diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js index 547c43760fe9..d6f7d8463830 100755 --- a/src/pages/signin/LoginForm.js +++ b/src/pages/signin/LoginForm.js @@ -88,15 +88,6 @@ class LoginForm extends React.Component { autoFocus={canFocusInputOnScreenFocus()} /> - -