From e7598f7392ca887b93ed897dc5613c2d5a95d79e Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Tue, 22 Mar 2022 00:31:15 -0700 Subject: [PATCH 001/287] Remove unused onyx prop --- src/pages/iou/IOUModal.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 8e1d973df99d..024ec14f5257 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -459,9 +459,6 @@ export default compose( report: { key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${lodashGet(route, 'params.reportID', '')}`, }, - iousReport: { - key: ONYXKEYS.COLLECTION.REPORT_IOUS, - }, iou: { key: ONYXKEYS.IOU, }, From 3e48b231ec44775684ea4176795923eea3f6f81a Mon Sep 17 00:00:00 2001 From: Tushu17 Date: Mon, 11 Apr 2022 02:50:05 +0530 Subject: [PATCH 002/287] make user and room name pressable --- src/components/ReportWelcomeText.js | 24 +++++++++----- .../home/report/ReportActionItemCreated.js | 31 ++++++++++++++++--- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/components/ReportWelcomeText.js b/src/components/ReportWelcomeText.js index 0d86d1071018..e0974bdad071 100644 --- a/src/components/ReportWelcomeText.js +++ b/src/components/ReportWelcomeText.js @@ -4,6 +4,7 @@ import lodashGet from 'lodash/get'; import Str from 'expensify-common/lib/str'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; +import {Pressable} from 'react-native'; import styles from '../styles/styles'; import Text from './Text'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; @@ -12,6 +13,8 @@ import * as ReportUtils from '../libs/reportUtils'; import * as OptionsListUtils from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import CONST from '../CONST'; +import Navigation from '../libs/Navigation/Navigation'; +import ROUTES from '../ROUTES'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -70,6 +73,7 @@ const ReportWelcomeText = (props) => { displayName: isMultipleParticipant ? shortName : longNameLocalized, tooltip: Str.removeSMSDomain(login), pronouns: finalPronouns, + login, }; }, ); @@ -103,9 +107,13 @@ const ReportWelcomeText = (props) => { {roomWelcomeMessage.phrase1} - - {props.report.reportName} - + Navigation.navigate(ROUTES.getReportDetailsRoute(props.report.reportID))} + > + + {props.report.reportName} + + {roomWelcomeMessage.phrase2} @@ -117,11 +125,13 @@ const ReportWelcomeText = (props) => { {props.translate('reportActionsView.beginningOfChatHistory')} - {_.map(displayNamesWithTooltips, ({displayName, pronouns}, index) => ( + {_.map(displayNamesWithTooltips, ({displayName, pronouns, login}, index) => ( - - {displayName} - + Navigation.navigate(ROUTES.getDetailsRoute(login))}> + + {displayName} + + {!_.isEmpty(pronouns) && {` (${pronouns})`}} {(index === displayNamesWithTooltips.length - 1) && .} {(index === displayNamesWithTooltips.length - 2) && {` ${props.translate('common.and')} `}} diff --git a/src/pages/home/report/ReportActionItemCreated.js b/src/pages/home/report/ReportActionItemCreated.js index 670539b9d026..1bdca0cf3df3 100644 --- a/src/pages/home/report/ReportActionItemCreated.js +++ b/src/pages/home/report/ReportActionItemCreated.js @@ -1,13 +1,16 @@ import React from 'react'; -import {View} from 'react-native'; +import {Pressable, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; +import lodashGet from 'lodash/get'; import ONYXKEYS from '../../../ONYXKEYS'; import RoomHeaderAvatars from '../../../components/RoomHeaderAvatars'; import ReportWelcomeText from '../../../components/ReportWelcomeText'; import * as ReportUtils from '../../../libs/reportUtils'; import styles from '../../../styles/styles'; import * as OptionsListUtils from '../../../libs/OptionsListUtils'; +import Navigation from '../../../libs/Navigation/Navigation'; +import ROUTES from '../../../ROUTES'; const propTypes = { /** The report currently being looked at */ @@ -17,6 +20,9 @@ const propTypes = { /** Whether the user is not an admin of policyExpenseChat chat */ isOwnPolicyExpenseChat: PropTypes.bool, + + /** ID of the report */ + reportID: PropTypes.number, }), }; const defaultProps = { @@ -24,8 +30,21 @@ const defaultProps = { }; const ReportActionItemCreated = (props) => { + const participants = lodashGet(props.report, 'participants', []); + const isChatRoom = ReportUtils.isChatRoom(props.report); const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(props.report); const avatarIcons = OptionsListUtils.getAvatarSources(props.report); + + function navigateToDetails() { + if (isChatRoom || isPolicyExpenseChat) { + return Navigation.navigate(ROUTES.getReportDetailsRoute(props.report.reportID)); + } + if (participants.length === 1) { + return Navigation.navigate(ROUTES.getDetailsRoute(participants[0])); + } + Navigation.navigate(ROUTES.getReportParticipantsRoute(props.report.reportID)); + } + return ( { ]} > - + + + From 1877d03907d85337453fa53c9a380a1f93f3746c Mon Sep 17 00:00:00 2001 From: Tushu17 Date: Tue, 19 Apr 2022 21:47:04 +0530 Subject: [PATCH 003/287] add tooltip --- src/components/ReportWelcomeText.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/components/ReportWelcomeText.js b/src/components/ReportWelcomeText.js index e0974bdad071..f767b18a0bae 100644 --- a/src/components/ReportWelcomeText.js +++ b/src/components/ReportWelcomeText.js @@ -15,6 +15,7 @@ import ONYXKEYS from '../ONYXKEYS'; import CONST from '../CONST'; import Navigation from '../libs/Navigation/Navigation'; import ROUTES from '../ROUTES'; +import Tooltip from './Tooltip'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -125,13 +126,17 @@ const ReportWelcomeText = (props) => { {props.translate('reportActionsView.beginningOfChatHistory')} - {_.map(displayNamesWithTooltips, ({displayName, pronouns, login}, index) => ( + {_.map(displayNamesWithTooltips, ({ + displayName, pronouns, login, tooltip, + }, index) => ( - Navigation.navigate(ROUTES.getDetailsRoute(login))}> - - {displayName} - - + + Navigation.navigate(ROUTES.getDetailsRoute(login))}> + + {displayName} + + + {!_.isEmpty(pronouns) && {` (${pronouns})`}} {(index === displayNamesWithTooltips.length - 1) && .} {(index === displayNamesWithTooltips.length - 2) && {` ${props.translate('common.and')} `}} From b59a9ef8178c13ab6dc21a4c46a1ef2aab1ee5f2 Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Fri, 22 Apr 2022 23:30:20 +0500 Subject: [PATCH 004/287] login form layout for ipad --- src/pages/signin/SignInPageLayout/index.js | 52 ++++++++++++++-------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index f9bca16bdc72..e30278d10c49 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -35,34 +35,48 @@ const SignInPageLayout = (props) => { ); + const hasRedirect = !_.isEmpty(backgroundStyle.redirectUri); + + const graphicLayout = () => ( + { + Link.openExternalLink(backgroundStyle.redirectUri); + }} + disabled={!hasRedirect} + > + + + ); + if (props.isSmallScreenWidth) { return content; } - const hasRedirect = !_.isEmpty(backgroundStyle.redirectUri); + if (props.isMediumScreenWidth) { + return ( + + {graphicLayout(props.isMediumScreenWidth)} + + {content} + + + ); + } return ( {content} - { - Link.openExternalLink(backgroundStyle.redirectUri); - }} - disabled={!hasRedirect} - > - - + {graphicLayout(props.isMediumScreenWidth)} ); From 615130ce8e02cc233e06906d55f9afa199b6cd5c Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Sat, 23 Apr 2022 00:23:28 +0500 Subject: [PATCH 005/287] review changes --- src/pages/signin/SignInPageLayout/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index e30278d10c49..35df9dfa9254 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -37,7 +37,7 @@ const SignInPageLayout = (props) => { const hasRedirect = !_.isEmpty(backgroundStyle.redirectUri); - const graphicLayout = () => ( + const graphicLayout = ( { if (props.isMediumScreenWidth) { return ( - {graphicLayout(props.isMediumScreenWidth)} + {graphicLayout} {content} @@ -76,7 +76,7 @@ const SignInPageLayout = (props) => { {content} - {graphicLayout(props.isMediumScreenWidth)} + {graphicLayout} ); From ef587f01af3fb6468b335a09d581ee3ac4f63732 Mon Sep 17 00:00:00 2001 From: mateusbra Date: Fri, 22 Apr 2022 17:47:18 -0300 Subject: [PATCH 006/287] remove fill property from Svg icons --- assets/images/offline.svg | 2 +- assets/images/workspace-default-avatar.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/images/offline.svg b/assets/images/offline.svg index a4d539125f31..f3b58e11221f 100644 --- a/assets/images/offline.svg +++ b/assets/images/offline.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/images/workspace-default-avatar.svg b/assets/images/workspace-default-avatar.svg index 96fd0832bfc5..c081606cb2b1 100644 --- a/assets/images/workspace-default-avatar.svg +++ b/assets/images/workspace-default-avatar.svg @@ -1 +1 @@ - + From c89a2a4347c0dd6a2128f9ca1b0c6a1a0d9b7464 Mon Sep 17 00:00:00 2001 From: mateusbra Date: Fri, 22 Apr 2022 18:18:19 -0300 Subject: [PATCH 007/287] revert changes from workspace-default-avatar.svg --- assets/images/workspace-default-avatar.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/images/workspace-default-avatar.svg b/assets/images/workspace-default-avatar.svg index c081606cb2b1..96fd0832bfc5 100644 --- a/assets/images/workspace-default-avatar.svg +++ b/assets/images/workspace-default-avatar.svg @@ -1 +1 @@ - + From d7536758964774a18c31123b5c71aed893dc34e5 Mon Sep 17 00:00:00 2001 From: Santhoshkumar Sellavel Date: Sun, 24 Apr 2022 00:38:49 +0530 Subject: [PATCH 008/287] IOU Contact Preview clickable cursor issue fixed --- src/components/IOUConfirmationList.js | 7 ++++--- src/pages/iou/IOUModal.js | 2 +- src/pages/iou/steps/IOUConfirmPage.js | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index a02a75595805..05ed4139520b 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -60,8 +60,8 @@ const propTypes = { phoneNumber: PropTypes.string, })).isRequired, - /** Whether this is an IOU split and belongs to a group report */ - isGroupSplit: PropTypes.bool.isRequired, + /** Is this IOU associated with existing report */ + isIOUAttachedToExistingChatReport: PropTypes.bool.isRequired, ...windowDimensionsPropTypes, @@ -352,6 +352,7 @@ class IOUConfirmationList extends Component { const shouldDisableButton = selectedParticipants.length === 0 || this.props.network.isOffline; const isLoading = this.props.iou.loading && !this.props.network.isOffline; const recipient = this.state.participants[0]; + const canModifyParticipants = this.props.isIOUAttachedToExistingChatReport && this.props.hasMultipleParticipants; return ( <> @@ -364,7 +365,7 @@ class IOUConfirmationList extends Component { canSelectMultipleOptions={this.props.hasMultipleParticipants} selectedOptions={this.getSelectedOptions()} onSelectRow={toggleOption} - isDisabled={!this.props.isGroupSplit} + isDisabled={!canModifyParticipants} optionHoveredStyle={hoverStyle} /> diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index a75b7f990cfe..72819565b4e9 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -434,7 +434,7 @@ class IOUModal extends Component { comment={this.state.comment} onUpdateComment={this.updateComment} iouType={this.props.iouType} - isGroupSplit={this.steps.length === 2} + isIOUAttachedToExistingChatReport={!_.isEmpty(reportID)} /> )} diff --git a/src/pages/iou/steps/IOUConfirmPage.js b/src/pages/iou/steps/IOUConfirmPage.js index 6d59ed01c7ce..5352ccfdcf83 100644 --- a/src/pages/iou/steps/IOUConfirmPage.js +++ b/src/pages/iou/steps/IOUConfirmPage.js @@ -42,8 +42,8 @@ const propTypes = { /** IOU type */ iouType: PropTypes.string, - /** Whether this is an IOU split and belongs to a group report */ - isGroupSplit: PropTypes.bool.isRequired, + /** Is this IOU associated with existing report */ + isIOUAttachedToExistingChatReport: PropTypes.bool.isRequired, }; const defaultProps = { @@ -62,7 +62,7 @@ const IOUConfirmPage = props => ( onConfirm={props.onConfirm} onSendMoney={props.onSendMoney} iouType={props.iouType} - isGroupSplit={props.isGroupSplit} + isIOUAttachedToExistingChatReport={props.isIOUAttachedToExistingChatReport} /> ); From 6daa73cec2a20a10b739a851822cb21b39f58417 Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Mon, 25 Apr 2022 17:27:54 +0200 Subject: [PATCH 009/287] fix not removing focus style on blur --- src/components/Picker/BasePicker/index.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/Picker/BasePicker/index.js b/src/components/Picker/BasePicker/index.js index 07af4b36d0b1..5368d565cfe8 100644 --- a/src/components/Picker/BasePicker/index.js +++ b/src/components/Picker/BasePicker/index.js @@ -15,6 +15,7 @@ class BasePicker extends React.Component { }; this.updateSelectedValueAndExecuteOnChange = this.updateSelectedValueAndExecuteOnChange.bind(this); + this.executeOnCloseAndOnBlur = this.executeOnCloseAndOnBlur.bind(this); } updateSelectedValueAndExecuteOnChange(value) { @@ -22,6 +23,14 @@ class BasePicker extends React.Component { this.setState({selectedValue: value}); } + executeOnCloseAndOnBlur() { + this.props.onClose(); + + if (this.props.onBlur) { + this.props.onBlur(); + } + } + render() { const hasError = !_.isEmpty(this.props.errorText); return ( @@ -39,7 +48,7 @@ class BasePicker extends React.Component { onClose={this.props.onClose} pickerProps={{ onFocus: this.props.onOpen, - onBlur: this.props.onBlur, + onBlur: this.executeOnCloseAndOnBlur, ref: this.props.innerRef, }} /> From 178b8fac1c52e26d45ac9ae2cdb98287e4c9715a Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Mon, 25 Apr 2022 18:48:32 +0200 Subject: [PATCH 010/287] add comment --- src/components/Picker/BasePicker/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Picker/BasePicker/index.js b/src/components/Picker/BasePicker/index.js index 5368d565cfe8..0fade3e32f05 100644 --- a/src/components/Picker/BasePicker/index.js +++ b/src/components/Picker/BasePicker/index.js @@ -24,6 +24,7 @@ class BasePicker extends React.Component { } executeOnCloseAndOnBlur() { + // Picker's onClose is not executed on Web and Desktop, so props.onClose has to be called with onBlur callback. this.props.onClose(); if (this.props.onBlur) { From 0dbb44dbf9673d85cc03ad0185cedde611af04a5 Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Tue, 26 Apr 2022 03:04:26 +0200 Subject: [PATCH 011/287] refactor onFocus onBlur event --- src/CONST.js | 4 +++ .../Picker/BasePicker/basePickerPropTypes.js | 6 ++++ src/components/Picker/BasePicker/index.js | 18 +++------- src/components/Picker/index.js | 35 +++++++++++++++++-- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index c60a5d15b06e..fabfb4457779 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -182,6 +182,10 @@ const CONST = { META: 'CMD', SHIFT: 'Shift', }, + PICKER_EVENT: { + FOCUS: 'onFocus', + BLUR: 'onBlur', + }, CURRENCY: { USD: 'USD', }, diff --git a/src/components/Picker/BasePicker/basePickerPropTypes.js b/src/components/Picker/BasePicker/basePickerPropTypes.js index 7af66b59bdf6..3cc99dcc5579 100644 --- a/src/components/Picker/BasePicker/basePickerPropTypes.js +++ b/src/components/Picker/BasePicker/basePickerPropTypes.js @@ -43,6 +43,12 @@ const propTypes = { /** Size of a picker component */ size: PropTypes.oneOf(['normal', 'small']), + + /** Callback executed when on click or tap on Picker */ + onFocus: PropTypes.func.isRequired, + + /** Callback executed when close Picker's menu options or click outside of Picker */ + onBlur: PropTypes.func.isRequired, }; const defaultProps = { disabled: false, diff --git a/src/components/Picker/BasePicker/index.js b/src/components/Picker/BasePicker/index.js index 0fade3e32f05..fc10dec8385c 100644 --- a/src/components/Picker/BasePicker/index.js +++ b/src/components/Picker/BasePicker/index.js @@ -15,7 +15,6 @@ class BasePicker extends React.Component { }; this.updateSelectedValueAndExecuteOnChange = this.updateSelectedValueAndExecuteOnChange.bind(this); - this.executeOnCloseAndOnBlur = this.executeOnCloseAndOnBlur.bind(this); } updateSelectedValueAndExecuteOnChange(value) { @@ -23,15 +22,6 @@ class BasePicker extends React.Component { this.setState({selectedValue: value}); } - executeOnCloseAndOnBlur() { - // Picker's onClose is not executed on Web and Desktop, so props.onClose has to be called with onBlur callback. - this.props.onClose(); - - if (this.props.onBlur) { - this.props.onBlur(); - } - } - render() { const hasError = !_.isEmpty(this.props.errorText); return ( @@ -45,11 +35,11 @@ class BasePicker extends React.Component { Icon={() => this.props.icon(this.props.size)} disabled={this.props.disabled} fixAndroidTouchableBug - onOpen={this.props.onOpen} - onClose={this.props.onClose} + onOpen={this.props.onFocus} + onClose={this.props.onBlur} pickerProps={{ - onFocus: this.props.onOpen, - onBlur: this.executeOnCloseAndOnBlur, + onFocus: this.props.onFocus, + onBlur: this.props.onBlur, ref: this.props.innerRef, }} /> diff --git a/src/components/Picker/index.js b/src/components/Picker/index.js index 5f2f86374854..bdb5586e099a 100644 --- a/src/components/Picker/index.js +++ b/src/components/Picker/index.js @@ -7,6 +7,7 @@ import Text from '../Text'; import styles from '../../styles/styles'; import InlineErrorText from '../InlineErrorText'; import * as FormUtils from '../../libs/FormUtils'; +import CONST from '../../CONST'; const propTypes = { /** Picker label */ @@ -37,6 +38,12 @@ const propTypes = { /** Saves a draft of the input value when used in a form */ shouldSaveDraft: PropTypes.bool, + + /** Callback executed when on click or tap on Picker */ + onFocus: PropTypes.func, + + /** Callback executed when close options menu or click outside of Picker */ + onBlur: PropTypes.func, }; const defaultProps = { @@ -48,6 +55,8 @@ const defaultProps = { inputID: undefined, shouldSaveDraft: false, value: undefined, + onFocus: undefined, + onBlur: undefined, }; class Picker extends PureComponent { @@ -56,6 +65,28 @@ class Picker extends PureComponent { this.state = { isOpen: false, }; + + this.defaultEvent = { + onFocus: () => { + this.setState({isOpen: true}); + }, + onBlur: () => { + this.setState({isOpen: false}); + }, + }; + + this.pickerEvent = this.pickerEvent.bind(this); + } + + pickerEvent(event) { + if (this.props[event]) { + return () => { + this.defaultEvent[event](); + this.props[event](); + }; + } + + return this.defaultEvent[event]; } render() { @@ -73,8 +104,8 @@ class Picker extends PureComponent { {this.props.label} )} this.setState({isOpen: true})} - onClose={() => this.setState({isOpen: false})} + onFocus={this.pickerEvent(CONST.PICKER_EVENT.FOCUS)} + onBlur={this.pickerEvent(CONST.PICKER_EVENT.BLUR)} disabled={this.props.isDisabled} focused={this.state.isOpen} errorText={this.props.errorText} From c75689d4d931638025163cc796b66cd6c029a79d Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Wed, 27 Apr 2022 04:52:11 +0500 Subject: [PATCH 012/287] Feedback change floating window and split window(On Desktop) --- config/webpack/webpack.dev.js | 1 + src/pages/signin/SignInPageLayout/SignInPageContent.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/webpack/webpack.dev.js b/config/webpack/webpack.dev.js index 482d4a08fbe5..de4d73558f47 100644 --- a/config/webpack/webpack.dev.js +++ b/config/webpack/webpack.dev.js @@ -27,6 +27,7 @@ module.exports = (env = {}) => { devServer: { contentBase: path.join(__dirname, '../../dist'), hot: true, + host: '0.0.0.0', ...proxySettings, historyApiFallback: true, }, diff --git a/src/pages/signin/SignInPageLayout/SignInPageContent.js b/src/pages/signin/SignInPageLayout/SignInPageContent.js index f787d197fe7d..1a02c11c9f91 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageContent.js +++ b/src/pages/signin/SignInPageLayout/SignInPageContent.js @@ -55,7 +55,8 @@ const SignInPageContent = props => ( Date: Thu, 28 Apr 2022 00:37:20 +0700 Subject: [PATCH 013/287] fix not proper image height on native --- src/components/ImageView/index.native.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/ImageView/index.native.js b/src/components/ImageView/index.native.js index f851246e56ef..4a364bdd3583 100644 --- a/src/components/ImageView/index.native.js +++ b/src/components/ImageView/index.native.js @@ -34,6 +34,7 @@ class ImageView extends PureComponent { imageWidth: undefined, imageHeight: undefined, interactionPromise: undefined, + containerHeight: undefined, }; // Use the default double click interval from the ImageZoom library @@ -72,7 +73,7 @@ class ImageView extends PureComponent { let imageWidth = width; let imageHeight = height; const containerWidth = Math.round(this.props.windowWidth); - const containerHeight = Math.round(this.props.windowHeight - variables.contentHeaderHeight); + const containerHeight = Math.round(this.state.containerHeight); const aspectRatio = Math.min(containerHeight / imageHeight, containerWidth / imageWidth); @@ -134,6 +135,12 @@ class ImageView extends PureComponent { styles.overflowHidden, styles.errorOutline, ]} + onLayout={(event) => { + const layout = event.nativeEvent.layout; + this.setState({ + containerHeight: layout.height, + }); + }} > Date: Thu, 28 Apr 2022 00:37:38 +0700 Subject: [PATCH 014/287] remove the exceed space on android when using attachment modal --- src/styles/getModalStyles.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/styles/getModalStyles.js b/src/styles/getModalStyles.js index 32ca24fa9c84..9269cf8ab2d0 100644 --- a/src/styles/getModalStyles.js +++ b/src/styles/getModalStyles.js @@ -1,3 +1,4 @@ +import {Platform} from 'react-native'; import CONST from '../CONST'; import colors from './colors'; import variables from './variables'; @@ -83,7 +84,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty swipeDirection = ['down', 'right']; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - shouldAddTopSafeAreaPadding = true; + shouldAddTopSafeAreaPadding = Platform.OS === 'ios'; break; case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: // A centered modal that cannot be dismissed with a swipe. @@ -114,7 +115,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty swipeDirection = undefined; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - shouldAddTopSafeAreaPadding = true; + shouldAddTopSafeAreaPadding = Platform.OS === 'ios'; break; case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED: modalStyle = { From 53cbcf690e06addc91dd318f266884d220678216 Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Thu, 28 Apr 2022 00:49:58 +0700 Subject: [PATCH 015/287] add comment to give some explanation --- src/styles/getModalStyles.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/styles/getModalStyles.js b/src/styles/getModalStyles.js index 9269cf8ab2d0..9b95d9d06815 100644 --- a/src/styles/getModalStyles.js +++ b/src/styles/getModalStyles.js @@ -84,6 +84,8 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty swipeDirection = ['down', 'right']; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; + + // Only apply top padding on iOS since only iOS using SafeAreaView and the top insets is not apply shouldAddTopSafeAreaPadding = Platform.OS === 'ios'; break; case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: @@ -115,6 +117,8 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty swipeDirection = undefined; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; + + // Only apply top padding on iOS since only iOS using SafeAreaView and the top insets is not apply shouldAddTopSafeAreaPadding = Platform.OS === 'ios'; break; case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED: From d30e03eb8e61dbaf5d9efb545baa06a692e84180 Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Wed, 27 Apr 2022 20:05:29 +0200 Subject: [PATCH 016/287] Revert "refactor onFocus onBlur event" This reverts commit 0dbb44dbf9673d85cc03ad0185cedde611af04a5. Signed-off-by: LucioChavezFuentes --- src/CONST.js | 4 --- .../Picker/BasePicker/basePickerPropTypes.js | 6 ---- src/components/Picker/BasePicker/index.js | 18 +++++++--- src/components/Picker/index.js | 35 ++----------------- 4 files changed, 16 insertions(+), 47 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index fabfb4457779..c60a5d15b06e 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -182,10 +182,6 @@ const CONST = { META: 'CMD', SHIFT: 'Shift', }, - PICKER_EVENT: { - FOCUS: 'onFocus', - BLUR: 'onBlur', - }, CURRENCY: { USD: 'USD', }, diff --git a/src/components/Picker/BasePicker/basePickerPropTypes.js b/src/components/Picker/BasePicker/basePickerPropTypes.js index 3cc99dcc5579..7af66b59bdf6 100644 --- a/src/components/Picker/BasePicker/basePickerPropTypes.js +++ b/src/components/Picker/BasePicker/basePickerPropTypes.js @@ -43,12 +43,6 @@ const propTypes = { /** Size of a picker component */ size: PropTypes.oneOf(['normal', 'small']), - - /** Callback executed when on click or tap on Picker */ - onFocus: PropTypes.func.isRequired, - - /** Callback executed when close Picker's menu options or click outside of Picker */ - onBlur: PropTypes.func.isRequired, }; const defaultProps = { disabled: false, diff --git a/src/components/Picker/BasePicker/index.js b/src/components/Picker/BasePicker/index.js index fc10dec8385c..0fade3e32f05 100644 --- a/src/components/Picker/BasePicker/index.js +++ b/src/components/Picker/BasePicker/index.js @@ -15,6 +15,7 @@ class BasePicker extends React.Component { }; this.updateSelectedValueAndExecuteOnChange = this.updateSelectedValueAndExecuteOnChange.bind(this); + this.executeOnCloseAndOnBlur = this.executeOnCloseAndOnBlur.bind(this); } updateSelectedValueAndExecuteOnChange(value) { @@ -22,6 +23,15 @@ class BasePicker extends React.Component { this.setState({selectedValue: value}); } + executeOnCloseAndOnBlur() { + // Picker's onClose is not executed on Web and Desktop, so props.onClose has to be called with onBlur callback. + this.props.onClose(); + + if (this.props.onBlur) { + this.props.onBlur(); + } + } + render() { const hasError = !_.isEmpty(this.props.errorText); return ( @@ -35,11 +45,11 @@ class BasePicker extends React.Component { Icon={() => this.props.icon(this.props.size)} disabled={this.props.disabled} fixAndroidTouchableBug - onOpen={this.props.onFocus} - onClose={this.props.onBlur} + onOpen={this.props.onOpen} + onClose={this.props.onClose} pickerProps={{ - onFocus: this.props.onFocus, - onBlur: this.props.onBlur, + onFocus: this.props.onOpen, + onBlur: this.executeOnCloseAndOnBlur, ref: this.props.innerRef, }} /> diff --git a/src/components/Picker/index.js b/src/components/Picker/index.js index bdb5586e099a..5f2f86374854 100644 --- a/src/components/Picker/index.js +++ b/src/components/Picker/index.js @@ -7,7 +7,6 @@ import Text from '../Text'; import styles from '../../styles/styles'; import InlineErrorText from '../InlineErrorText'; import * as FormUtils from '../../libs/FormUtils'; -import CONST from '../../CONST'; const propTypes = { /** Picker label */ @@ -38,12 +37,6 @@ const propTypes = { /** Saves a draft of the input value when used in a form */ shouldSaveDraft: PropTypes.bool, - - /** Callback executed when on click or tap on Picker */ - onFocus: PropTypes.func, - - /** Callback executed when close options menu or click outside of Picker */ - onBlur: PropTypes.func, }; const defaultProps = { @@ -55,8 +48,6 @@ const defaultProps = { inputID: undefined, shouldSaveDraft: false, value: undefined, - onFocus: undefined, - onBlur: undefined, }; class Picker extends PureComponent { @@ -65,28 +56,6 @@ class Picker extends PureComponent { this.state = { isOpen: false, }; - - this.defaultEvent = { - onFocus: () => { - this.setState({isOpen: true}); - }, - onBlur: () => { - this.setState({isOpen: false}); - }, - }; - - this.pickerEvent = this.pickerEvent.bind(this); - } - - pickerEvent(event) { - if (this.props[event]) { - return () => { - this.defaultEvent[event](); - this.props[event](); - }; - } - - return this.defaultEvent[event]; } render() { @@ -104,8 +73,8 @@ class Picker extends PureComponent { {this.props.label} )} this.setState({isOpen: true})} + onClose={() => this.setState({isOpen: false})} disabled={this.props.isDisabled} focused={this.state.isOpen} errorText={this.props.errorText} From 80321ec89f9b65004000885cdc956dedbcab9193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Thu, 28 Apr 2022 00:53:37 +0300 Subject: [PATCH 017/287] fixed: Image does not zoom where you click for desktop and web --- src/components/ImageView/index.js | 121 +++++++++++------------------- 1 file changed, 43 insertions(+), 78 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 2017962b5e83..cad5d47c6bb5 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -40,10 +40,6 @@ class ImageView extends PureComponent { imgWidth: 0, imgHeight: 0, zoomScale: 0, - imageLeft: 0, - imageTop: 0, - imageRight: 0, - imageBottom: 0, }; } @@ -98,17 +94,22 @@ class ImageView extends PureComponent { * @param {SyntheticEvent} e */ onContainerPress(e) { - if (this.state.isZoomed && !this.state.isDragging) { + let sX; + let sY; + if (this.isZoomed && !this.state.isDragging) { const {offsetX, offsetY} = e.nativeEvent; - const delta = this.getScrollOffset(offsetX, offsetY); - const sX = delta.offsetX; - const sY = delta.offsetY; - this.scrollableRef.scrollTop = sY * this.state.zoomScale; - this.scrollableRef.scrollLeft = sX * this.state.zoomScale; + const delta = this.getScrollOffset(offsetX / this.state.zoomScale, offsetY / this.state.zoomScale); + sX = delta.offsetX; + sY = delta.offsetY; } - if (this.state.isZoomed && this.state.isDragging && this.state.isMouseDown) { + if (this.isZoomed && this.state.isDragging && this.state.isMouseDown) { this.setState({isDragging: false, isMouseDown: false}); + } else if (this.isZoomed) { + this.setState({isZoomed: this.isZoomed}, () => { + this.scrollableRef.scrollTop = sY; + this.scrollableRef.scrollLeft = sX; + }); } } @@ -117,10 +118,17 @@ class ImageView extends PureComponent { return; } - this.setState(prevState => ({ - isZoomed: !prevState.isZoomed, - isMouseDown: false, - })); + this.isZoomed = !this.state.isZoomed; + if (this.isZoomed === false) { + this.setState(prevState => ({ + isMouseDown: false, + isZoomed: !prevState.isZoomed, + })); + } else { + this.setState({ + isMouseDown: false, + }); + } } /** @@ -129,55 +137,20 @@ class ImageView extends PureComponent { * @param {Number} imageHeight */ setImageRegion(imageWidth, imageHeight) { - let width = imageWidth; - let height = imageHeight; - const containerHeight = this.state.containerHeight; - const containerWidth = this.state.containerWidth; - - // return if image not loaded yet - if (imageHeight <= 0 || containerHeight <= 0) { + if (imageHeight <= 0) { return; } - - // Fit the image to container size if image small than container. - const aspectRatio = Math.min(containerHeight / imageHeight, containerWidth / imageWidth); - if (aspectRatio > 1) { - width *= (aspectRatio); - height *= (aspectRatio); - } - let imgLeft = (this.props.windowWidth - width) / 2; - let imgRight = ((this.props.windowWidth - width) / 2) + width; - let imgTop = (this.props.windowHeight - height) / 2; - let imgBottom = ((this.props.windowHeight - height) / 2) + height; - const isScreenWiderThanImage = (this.props.windowWidth / width) > 1; - const isScreenTallerThanImage = (this.props.windowHeight / height) > 1; - const aspect = width / height; - if (aspect > 1 && !isScreenWiderThanImage) { - // In case Width fit Screen width and Height not fit the Screen height - const fitRate = this.props.windowWidth / width; - imgLeft = 0; - imgRight = this.props.windowWidth; - imgTop = (this.props.windowHeight - (fitRate * height)) / 2; - imgBottom = imgTop + (fitRate * height); - } else if (aspect <= 1 && !isScreenTallerThanImage) { - // In case Height fit Screen height and Width not fit the Screen width - const fitRate = this.props.windowHeight / height; - imgTop = 0; - imgBottom = this.props.windowHeight; - imgLeft = (this.props.windowWidth - (fitRate * width)) / 2; - imgRight = imgLeft + (fitRate * width); - } - + const containerHeight = this.state.containerHeight; + const containerWidth = this.state.containerWidth; + const width = imageWidth; + const height = imageHeight; const newZoomScale = Math.min(containerWidth / width, containerHeight / height); - this.setState({ + + this.setState(prevState => ({ imgWidth: width, - zoomScale: newZoomScale, imgHeight: height, - imageLeft: imgLeft, - imageTop: imgTop, - imageRight: imgRight, - imageBottom: imgBottom, - }); + zoomScale: containerHeight ? newZoomScale : prevState.zoomScale, + })); } /** @@ -187,29 +160,21 @@ class ImageView extends PureComponent { * @returns {Object} converted touch point */ getScrollOffset(x, y) { - let fitRatio = 1; - if (this.state.imageTop === 0) { - // Fit Height - fitRatio = this.props.windowHeight / this.state.imgHeight; - } else if (this.state.imageLeft === 0) { - // Fit Width - fitRatio = this.props.windowWidth / this.state.imgWidth; - } - let sx = (x - this.state.imageLeft) / fitRatio; - let sy = (y - this.state.imageTop) / fitRatio; + let sx; + let sy; - // White blank touch - if (x < this.state.imageLeft) { + // container size bigger than clicked position offset + if (x <= (this.state.containerWidth / 2)) { sx = 0; + } else if (x > this.state.containerWidth / 2) { + // minus half of container size because we want to be center clicked position + sx = x - (this.state.containerWidth / 2); } - if (x > this.state.imageRight) { - sx = this.state.imgWidth; - } - if (y < this.state.imageTop) { + if (y <= this.state.containerHeight / 2) { sy = 0; - } - if (y > this.state.imageBottom) { - sy = this.state.imgHeight; + } else if (y > this.state.containerHeight / 2) { + // minus half of container size because we want to be center clicked position + sy = y - (this.state.containerHeight / 2); } return {offsetX: sx, offsetY: sy}; } From 6a8d056df8212426624871743bac491d2d7b8ed6 Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Thu, 28 Apr 2022 16:40:32 +0000 Subject: [PATCH 018/287] refetch actions for Payments Page with an HOC --- src/components/withRefetchActions.js | 37 +++++++++++++++++++ .../Payments/PaymentsPage/BasePaymentsPage.js | 9 ++++- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/components/withRefetchActions.js diff --git a/src/components/withRefetchActions.js b/src/components/withRefetchActions.js new file mode 100644 index 000000000000..8b4b1b45983e --- /dev/null +++ b/src/components/withRefetchActions.js @@ -0,0 +1,37 @@ +import React from 'react'; +import compose from '../libs/compose'; +import networkPropTypes from './networkPropTypes'; +import {withNetwork} from './OnyxProvider'; + +export default fetchData => (WrappedComponent) => { + const propTypes = { + /** Information about the network */ + network: networkPropTypes.isRequired, + }; + + class WithRefetchActions extends React.Component { + componentDidUpdate(prevProps) { + if (prevProps.network.isOffline === this.props.network.isOffline) { + return; + } + + fetchData(); + } + + render() { + return ( + + ); + } + } + + WithRefetchActions.propTypes = propTypes; + + // eslint-disable-next-line rulesdir/no-useless-compose + return compose( + withNetwork(), + )(WithRefetchActions); +}; diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js index f04d34ba6caf..0c37da606803 100644 --- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js +++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js @@ -30,6 +30,7 @@ import * as Expensicons from '../../../../components/Icon/Expensicons'; import ConfirmModal from '../../../../components/ConfirmModal'; import KYCWall from '../../../../components/KYCWall'; import {propTypes, defaultProps} from './paymentsPagePropTypes'; +import withRefetchActions from '../../../../components/withRefetchActions'; class BasePaymentsPage extends React.Component { constructor(props) { @@ -57,10 +58,11 @@ class BasePaymentsPage extends React.Component { this.hidePasswordPrompt = this.hidePasswordPrompt.bind(this); this.navigateToTransferBalancePage = this.navigateToTransferBalancePage.bind(this); this.setMenuPosition = this.setMenuPosition.bind(this); + this.fetchData = this.fetchData.bind(this); } componentDidMount() { - PaymentMethods.getPaymentMethods(); + this.fetchData(); if (this.props.shouldListenForResize) { this.dimensionsSubscription = Dimensions.addEventListener('change', this.setMenuPosition); } @@ -186,6 +188,10 @@ class BasePaymentsPage extends React.Component { throw new Error('Invalid payment method type selected'); } + fetchData() { + PaymentMethods.getPaymentMethods(); + } + /** * Hide the add payment modal */ @@ -432,6 +438,7 @@ BasePaymentsPage.defaultProps = defaultProps; export default compose( withWindowDimensions, withLocalize, + withRefetchActions(BasePaymentsPage.prototype.fetchData), withOnyx({ betas: { key: ONYXKEYS.BETAS, From c773bc85693a5681e884e9d8b5dacd9fc284ccd1 Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Thu, 28 Apr 2022 17:21:48 +0000 Subject: [PATCH 019/287] remove HOC and applied updates --- src/components/withRefetchActions.js | 37 ------------------- .../Payments/PaymentsPage/BasePaymentsPage.js | 11 +++++- .../PaymentsPage/paymentsPagePropTypes.js | 4 ++ 3 files changed, 14 insertions(+), 38 deletions(-) delete mode 100644 src/components/withRefetchActions.js diff --git a/src/components/withRefetchActions.js b/src/components/withRefetchActions.js deleted file mode 100644 index 8b4b1b45983e..000000000000 --- a/src/components/withRefetchActions.js +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import compose from '../libs/compose'; -import networkPropTypes from './networkPropTypes'; -import {withNetwork} from './OnyxProvider'; - -export default fetchData => (WrappedComponent) => { - const propTypes = { - /** Information about the network */ - network: networkPropTypes.isRequired, - }; - - class WithRefetchActions extends React.Component { - componentDidUpdate(prevProps) { - if (prevProps.network.isOffline === this.props.network.isOffline) { - return; - } - - fetchData(); - } - - render() { - return ( - - ); - } - } - - WithRefetchActions.propTypes = propTypes; - - // eslint-disable-next-line rulesdir/no-useless-compose - return compose( - withNetwork(), - )(WithRefetchActions); -}; diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js index 0c37da606803..40852004277f 100644 --- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js +++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js @@ -31,6 +31,7 @@ import ConfirmModal from '../../../../components/ConfirmModal'; import KYCWall from '../../../../components/KYCWall'; import {propTypes, defaultProps} from './paymentsPagePropTypes'; import withRefetchActions from '../../../../components/withRefetchActions'; +import {withNetwork} from '../../../../components/OnyxProvider'; class BasePaymentsPage extends React.Component { constructor(props) { @@ -68,6 +69,14 @@ class BasePaymentsPage extends React.Component { } } + componentDidUpdate(prevProps) { + if (prevProps.network.isOffline === this.props.network.isOffline) { + return; + } + + this.fetchData(); + } + componentWillUnmount() { if (!this.props.shouldListenForResize || !this.dimensionsSubscription) { return; @@ -438,7 +447,7 @@ BasePaymentsPage.defaultProps = defaultProps; export default compose( withWindowDimensions, withLocalize, - withRefetchActions(BasePaymentsPage.prototype.fetchData), + withNetwork(), withOnyx({ betas: { key: ONYXKEYS.BETAS, diff --git a/src/pages/settings/Payments/PaymentsPage/paymentsPagePropTypes.js b/src/pages/settings/Payments/PaymentsPage/paymentsPagePropTypes.js index 5e9da7e3e19a..92158d06204c 100644 --- a/src/pages/settings/Payments/PaymentsPage/paymentsPagePropTypes.js +++ b/src/pages/settings/Payments/PaymentsPage/paymentsPagePropTypes.js @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import walletTransferPropTypes from '../walletTransferPropTypes'; import {withLocalizePropTypes} from '../../../../components/withLocalize'; import {windowDimensionsPropTypes} from '../../../../components/withWindowDimensions'; +import networkPropTypes from '../../../../components/networkPropTypes'; const propTypes = { /** Wallet balance transfer props */ @@ -22,6 +23,9 @@ const propTypes = { currentBalance: PropTypes.number, }), + /** Information about the network */ + network: networkPropTypes.isRequired, + ...withLocalizePropTypes, ...windowDimensionsPropTypes, From 202b62e35da3b5096e8abd22eaeeb306b8369d43 Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Thu, 28 Apr 2022 17:23:29 +0000 Subject: [PATCH 020/287] remove useless use statement --- src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js index 40852004277f..a8c3164a085c 100644 --- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js +++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js @@ -30,7 +30,6 @@ import * as Expensicons from '../../../../components/Icon/Expensicons'; import ConfirmModal from '../../../../components/ConfirmModal'; import KYCWall from '../../../../components/KYCWall'; import {propTypes, defaultProps} from './paymentsPagePropTypes'; -import withRefetchActions from '../../../../components/withRefetchActions'; import {withNetwork} from '../../../../components/OnyxProvider'; class BasePaymentsPage extends React.Component { From 2bed1638aa0b10f352489821d8315d40fc8abb73 Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Fri, 29 Apr 2022 03:08:57 +0500 Subject: [PATCH 021/287] Remove host:0.0.0.0 from webpack --- config/webpack/webpack.dev.js | 1 - 1 file changed, 1 deletion(-) diff --git a/config/webpack/webpack.dev.js b/config/webpack/webpack.dev.js index de4d73558f47..482d4a08fbe5 100644 --- a/config/webpack/webpack.dev.js +++ b/config/webpack/webpack.dev.js @@ -27,7 +27,6 @@ module.exports = (env = {}) => { devServer: { contentBase: path.join(__dirname, '../../dist'), hot: true, - host: '0.0.0.0', ...proxySettings, historyApiFallback: true, }, From c9d791853248ac21b29cd0943c59743ee2c8cb05 Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Fri, 29 Apr 2022 09:05:34 +0000 Subject: [PATCH 022/287] add re-fetch actions to ReimbursementAccountPage.js --- .../ReimbursementAccountPage.js | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index b5ef196ff100..98b055ae0d2f 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -19,6 +19,8 @@ import styles from '../../styles/styles'; import KeyboardAvoidingView from '../../components/KeyboardAvoidingView'; import getPlaidOAuthReceivedRedirectURI from '../../libs/getPlaidOAuthReceivedRedirectURI'; import Text from '../../components/Text'; +import {withNetwork} from '../../components/OnyxProvider'; +import networkPropTypes from '../../components/networkPropTypes'; // Steps import BankAccountStep from './BankAccountStep'; @@ -39,6 +41,9 @@ const propTypes = { /** ACH data for the withdrawal account actively being set up */ reimbursementAccount: reimbursementAccountPropTypes, + /** Information about the network */ + network: networkPropTypes.isRequired, + /** Current session for the user */ session: PropTypes.shape({ /** User login */ @@ -70,14 +75,13 @@ const defaultProps = { class ReimbursementAccountPage extends React.Component { componentDidMount() { - // We can specify a step to navigate to by using route params when the component mounts. - const stepToOpen = this.getStepToOpenFromRouteParams(); - - // If we are trying to navigate to `/bank-account/new` and we already have a bank account then don't allow returning to `/new` - BankAccounts.fetchFreePlanVerifiedBankAccount(stepToOpen !== CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT ? stepToOpen : ''); + this.fetchData(); } componentDidUpdate(prevProps) { + if (prevProps.network.isOffline && !this.props.network.isOffline) { + this.fetchData(); + } const currentStep = lodashGet( this.props, 'reimbursementAccount.achData.currentStep', @@ -144,6 +148,14 @@ class ReimbursementAccountPage extends React.Component { } } + fetchData() { + // We can specify a step to navigate to by using route params when the component mounts. + const stepToOpen = this.getStepToOpenFromRouteParams(); + + // If we are trying to navigate to `/bank-account/new` and we already have a bank account then don't allow returning to `/new` + BankAccounts.fetchFreePlanVerifiedBankAccount(stepToOpen !== CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT ? stepToOpen : ''); + } + render() { if (!Permissions.canUseFreePlan(this.props.betas)) { Log.info('Not showing new bank account page because user is not on free plan beta'); @@ -243,6 +255,7 @@ ReimbursementAccountPage.propTypes = propTypes; ReimbursementAccountPage.defaultProps = defaultProps; export default compose( + withNetwork(), withOnyx({ reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, From fc5dfe25b89dff8ad092de0d1e5632a80b372a7a Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Fri, 29 Apr 2022 09:41:40 +0000 Subject: [PATCH 023/287] add refetch actions --- src/pages/ReimbursementAccount/EnableStep.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/pages/ReimbursementAccount/EnableStep.js b/src/pages/ReimbursementAccount/EnableStep.js index a96e495cf8d4..ee910a27ff22 100644 --- a/src/pages/ReimbursementAccount/EnableStep.js +++ b/src/pages/ReimbursementAccount/EnableStep.js @@ -24,11 +24,16 @@ import * as Illustrations from '../../components/Icon/Illustrations'; import * as BankAccounts from '../../libs/actions/BankAccounts'; import * as Link from '../../libs/actions/Link'; import * as User from '../../libs/actions/User'; +import {withNetwork} from '../../components/OnyxProvider'; +import networkPropTypes from '../../components/networkPropTypes'; const propTypes = { /** Are we loading payment methods? */ isLoadingPaymentMethods: PropTypes.bool, + /** Information about the network */ + network: networkPropTypes.isRequired, + /** List of bank accounts */ bankAccountList: PropTypes.objectOf(bankAccountPropTypes), @@ -42,6 +47,18 @@ const defaultProps = { class EnableStep extends React.Component { componentDidMount() { + this.fetchData(); + } + + componentDidUpdate(prevProps) { + if (prevProps.network.isOffline === this.props.network.isOffline) { + return; + } + + this.fetchData(); + } + + fetchData() { PaymentMethods.getPaymentMethods(); } @@ -133,6 +150,7 @@ EnableStep.defaultProps = defaultProps; export default compose( withLocalize, + withNetwork(), withOnyx({ isLoadingPaymentMethods: { key: ONYXKEYS.IS_LOADING_PAYMENT_METHODS, From ac4511e0eebef89f67374b9e8d787c7c934ee144 Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Fri, 29 Apr 2022 19:23:04 +0700 Subject: [PATCH 024/287] using getPlatform() instead rn Platform --- src/styles/getModalStyles.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/styles/getModalStyles.js b/src/styles/getModalStyles.js index 9b95d9d06815..e08390a06015 100644 --- a/src/styles/getModalStyles.js +++ b/src/styles/getModalStyles.js @@ -1,8 +1,8 @@ -import {Platform} from 'react-native'; import CONST from '../CONST'; import colors from './colors'; import variables from './variables'; import themeColors from './themes/default'; +import getPlatform from '../libs/getPlatform'; export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => { const {isSmallScreenWidth, windowWidth} = windowDimensions; @@ -86,7 +86,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; // Only apply top padding on iOS since only iOS using SafeAreaView and the top insets is not apply - shouldAddTopSafeAreaPadding = Platform.OS === 'ios'; + shouldAddTopSafeAreaPadding = getPlatform() === CONST.PLATFORM.IOS; break; case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: // A centered modal that cannot be dismissed with a swipe. @@ -119,7 +119,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; // Only apply top padding on iOS since only iOS using SafeAreaView and the top insets is not apply - shouldAddTopSafeAreaPadding = Platform.OS === 'ios'; + shouldAddTopSafeAreaPadding = getPlatform() === CONST.PLATFORM.IOS; break; case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED: modalStyle = { From 56871fa615cb3b22d0dd4ce9e2e340c56dd01bd6 Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Fri, 29 Apr 2022 18:48:10 +0000 Subject: [PATCH 025/287] apply PR requested changes --- src/pages/ReimbursementAccount/EnableStep.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/ReimbursementAccount/EnableStep.js b/src/pages/ReimbursementAccount/EnableStep.js index ee910a27ff22..8c2ae53cd87e 100644 --- a/src/pages/ReimbursementAccount/EnableStep.js +++ b/src/pages/ReimbursementAccount/EnableStep.js @@ -31,7 +31,7 @@ const propTypes = { /** Are we loading payment methods? */ isLoadingPaymentMethods: PropTypes.bool, - /** Information about the network */ + /** Information about the network */ network: networkPropTypes.isRequired, /** List of bank accounts */ @@ -51,7 +51,7 @@ class EnableStep extends React.Component { } componentDidUpdate(prevProps) { - if (prevProps.network.isOffline === this.props.network.isOffline) { + if (prevProps.network.isOffline && !this.props.network.isOffline) { return; } From 5f7f138d631aaadb13ab108ce5b7dec212f08147 Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Mon, 2 May 2022 13:23:50 +0530 Subject: [PATCH 026/287] Added a fallback icon when getting error on loading image --- assets/images/avatars/fallback-avatar.svg | 25 +++++++++++++++++++++++ src/components/Avatar.js | 25 ++++++++++++++++++----- src/components/Icon/Expensicons.js | 2 ++ 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 assets/images/avatars/fallback-avatar.svg diff --git a/assets/images/avatars/fallback-avatar.svg b/assets/images/avatars/fallback-avatar.svg new file mode 100644 index 000000000000..dc1a1497cfe5 --- /dev/null +++ b/assets/images/avatars/fallback-avatar.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 71ecd130ed9d..6e51400230e1 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -7,6 +7,7 @@ import Icon from './Icon'; import themeColors from '../styles/themes/default'; import CONST from '../CONST'; import * as StyleUtils from '../styles/StyleUtils'; +import * as Expensicons from './Icon/Expensicons'; const propTypes = { /** Source for the avatar. Can be a URL or an icon. */ @@ -34,6 +35,13 @@ const defaultProps = { }; class Avatar extends PureComponent { + constructor(props) { + super(props); + this.state = { + isErrorFetchingImage: false, + }; + } + render() { if (!this.props.source) { return null; @@ -47,11 +55,18 @@ class Avatar extends PureComponent { const iconSize = StyleUtils.getAvatarSize(this.props.size); return ( - { - _.isFunction(this.props.source) - ? - : - } + {_.isFunction(this.props.source) || this.state.isErrorFetchingImage + ? ( + + ) + : ( + this.setState({isErrorFetchingImage: true})} /> + )} ); } diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js index 4d98f1146930..34a38b209a69 100644 --- a/src/components/Icon/Expensicons.js +++ b/src/components/Icon/Expensicons.js @@ -74,6 +74,7 @@ import ActiveRoomAvatar from '../../../assets/images/avatars/room.svg'; import DeletedRoomAvatar from '../../../assets/images/avatars/deleted-room.svg'; import AdminRoomAvatar from '../../../assets/images/avatars/admin-room.svg'; import AnnounceRoomAvatar from '../../../assets/images/avatars/announce-room.svg'; +import FallbackAvatar from '../../../assets/images/avatars/fallback-avatar.svg'; import Connect from '../../../assets/images/connect.svg'; export { @@ -81,6 +82,7 @@ export { AdminRoomAvatar, Android, AnnounceRoomAvatar, + FallbackAvatar, Apple, ArrowRight, BackArrow, From b78ecd25aba025da3c2e0ddd9671b1d717de27a6 Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Mon, 2 May 2022 23:25:30 +0530 Subject: [PATCH 027/287] changed alphabetic order for import and added default background color to avatar --- src/components/Avatar.js | 10 +++++----- src/components/Icon/Expensicons.js | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 6e51400230e1..8d47ef043507 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -38,7 +38,7 @@ class Avatar extends PureComponent { constructor(props) { super(props); this.state = { - isErrorFetchingImage: false, + imageError: false, }; } @@ -55,17 +55,17 @@ class Avatar extends PureComponent { const iconSize = StyleUtils.getAvatarSize(this.props.size); return ( - {_.isFunction(this.props.source) || this.state.isErrorFetchingImage + {_.isFunction(this.props.source) || this.state.imageError ? ( ) : ( - this.setState({isErrorFetchingImage: true})} /> + this.setState({imageError: true})} /> )} ); diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js index 34a38b209a69..dcb9107525dd 100644 --- a/src/components/Icon/Expensicons.js +++ b/src/components/Icon/Expensicons.js @@ -1,3 +1,6 @@ +import ActiveRoomAvatar from '../../../assets/images/avatars/room.svg'; +import AdminRoomAvatar from '../../../assets/images/avatars/admin-room.svg'; +import AnnounceRoomAvatar from '../../../assets/images/avatars/announce-room.svg'; import Android from '../../../assets/images/android.svg'; import Apple from '../../../assets/images/apple.svg'; import ArrowRight from '../../../assets/images/arrow-right.svg'; @@ -17,7 +20,9 @@ import Clipboard from '../../../assets/images/clipboard.svg'; import Close from '../../../assets/images/close.svg'; import ClosedSign from '../../../assets/images/closed-sign.svg'; import Concierge from '../../../assets/images/concierge.svg'; +import Connect from '../../../assets/images/connect.svg'; import CreditCard from '../../../assets/images/creditcard.svg'; +import DeletedRoomAvatar from '../../../assets/images/avatars/deleted-room.svg'; import DownArrow from '../../../assets/images/down.svg'; import Download from '../../../assets/images/download.svg'; import Emoji from '../../../assets/images/emoji.svg'; @@ -26,6 +31,7 @@ import Exit from '../../../assets/images/exit.svg'; import Eye from '../../../assets/images/eye.svg'; import EyeDisabled from '../../../assets/images/eye-disabled.svg'; import ExpensifyCard from '../../../assets/images/expensifycard.svg'; +import FallbackAvatar from '../../../assets/images/avatars/fallback-avatar.svg'; import Gallery from '../../../assets/images/gallery.svg'; import Gear from '../../../assets/images/gear.svg'; import Hashtag from '../../../assets/images/hashtag.svg'; @@ -70,19 +76,12 @@ import Users from '../../../assets/images/users.svg'; import Venmo from '../../../assets/images/venmo.svg'; import Wallet from '../../../assets/images/wallet.svg'; import Workspace from '../../../assets/images/workspace-default-avatar.svg'; -import ActiveRoomAvatar from '../../../assets/images/avatars/room.svg'; -import DeletedRoomAvatar from '../../../assets/images/avatars/deleted-room.svg'; -import AdminRoomAvatar from '../../../assets/images/avatars/admin-room.svg'; -import AnnounceRoomAvatar from '../../../assets/images/avatars/announce-room.svg'; -import FallbackAvatar from '../../../assets/images/avatars/fallback-avatar.svg'; -import Connect from '../../../assets/images/connect.svg'; export { ActiveRoomAvatar, AdminRoomAvatar, Android, AnnounceRoomAvatar, - FallbackAvatar, Apple, ArrowRight, BackArrow, @@ -112,6 +111,7 @@ export { Eye, EyeDisabled, ExpensifyCard, + FallbackAvatar, Gallery, Gear, Hashtag, From d1db63fed9a8e7eac551fb9ab9291f6195fa421a Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Mon, 2 May 2022 21:19:42 +0200 Subject: [PATCH 028/287] declare onOpen onClose onBlur propTypes, fix errorText --- .../Picker/BasePicker/basePickerPropTypes.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/components/Picker/BasePicker/basePickerPropTypes.js b/src/components/Picker/BasePicker/basePickerPropTypes.js index 7af66b59bdf6..20cf8f0ec213 100644 --- a/src/components/Picker/BasePicker/basePickerPropTypes.js +++ b/src/components/Picker/BasePicker/basePickerPropTypes.js @@ -11,8 +11,8 @@ const propTypes = { /** Whether or not to show the disabled styles */ disabled: PropTypes.bool, - /** Should the picker be styled for errors */ - hasError: PropTypes.bool, + /** Error text to display */ + errorText: PropTypes.string, /** Should the picker be styled for focus state */ focused: PropTypes.bool, @@ -43,10 +43,19 @@ const propTypes = { /** Size of a picker component */ size: PropTypes.oneOf(['normal', 'small']), + + /** Callback called when Picker options menu is closed */ + onClose: PropTypes.func.isRequired, + + /** Callback called when Picker options menu is open */ + onOpen: PropTypes.func.isRequired, + + /** Callback called when click or tap out of Picker */ + onBlur: PropTypes.func, }; const defaultProps = { disabled: false, - hasError: false, + errorText: '', focused: false, placeholder: {}, value: null, @@ -68,6 +77,7 @@ const defaultProps = { ), size: 'normal', + onBlur: undefined, }; export { From 7373904e5bddc2974a5e1f0a1ef5f598fecd4481 Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Mon, 2 May 2022 22:32:19 +0200 Subject: [PATCH 029/287] keep hasError prop --- src/components/Picker/BasePicker/basePickerPropTypes.js | 4 ++++ src/components/Picker/BasePicker/index.js | 2 +- src/components/Picker/index.js | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/Picker/BasePicker/basePickerPropTypes.js b/src/components/Picker/BasePicker/basePickerPropTypes.js index 20cf8f0ec213..635c4cfc6c18 100644 --- a/src/components/Picker/BasePicker/basePickerPropTypes.js +++ b/src/components/Picker/BasePicker/basePickerPropTypes.js @@ -11,6 +11,9 @@ const propTypes = { /** Whether or not to show the disabled styles */ disabled: PropTypes.bool, + /** Should the picker be styled for errors */ + hasError: PropTypes.bool, + /** Error text to display */ errorText: PropTypes.string, @@ -55,6 +58,7 @@ const propTypes = { }; const defaultProps = { disabled: false, + hasError: false, errorText: '', focused: false, placeholder: {}, diff --git a/src/components/Picker/BasePicker/index.js b/src/components/Picker/BasePicker/index.js index 0fade3e32f05..1319cd8bfa6f 100644 --- a/src/components/Picker/BasePicker/index.js +++ b/src/components/Picker/BasePicker/index.js @@ -33,7 +33,7 @@ class BasePicker extends React.Component { } render() { - const hasError = !_.isEmpty(this.props.errorText); + const hasError = !_.isEmpty(this.props.errorText) || this.props.hasError; return ( Date: Mon, 2 May 2022 23:49:37 +0200 Subject: [PATCH 030/287] remove hasError propType on Picker --- src/components/Picker/index.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/Picker/index.js b/src/components/Picker/index.js index 0ebfe737d78f..5f2f86374854 100644 --- a/src/components/Picker/index.js +++ b/src/components/Picker/index.js @@ -21,9 +21,6 @@ const propTypes = { /** Error text to display */ errorText: PropTypes.string, - /** Should the picker be styled for errors */ - hasError: PropTypes.bool, - /** Customize the Picker container */ containerStyles: PropTypes.arrayOf(PropTypes.object), @@ -46,7 +43,6 @@ const defaultProps = { label: '', isDisabled: false, errorText: '', - hasError: false, containerStyles: [], isFormInput: false, inputID: undefined, @@ -82,7 +78,6 @@ class Picker extends PureComponent { disabled={this.props.isDisabled} focused={this.state.isOpen} errorText={this.props.errorText} - hasError={this.props.hasError} value={this.props.value} // eslint-disable-next-line react/jsx-props-no-spreading {...pickerProps} From 167764a67c4c25eb4708cbaba12e258e90d811ef Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Mon, 2 May 2022 14:24:40 -1000 Subject: [PATCH 031/287] remove shouldRetry and general retryability of non persistable requests - stop queueing read requests. watch many tests fail --- src/CONST.js | 1 + src/libs/API.js | 4 +-- src/libs/Authentication.js | 5 +++- src/libs/Log.js | 1 - src/libs/Middleware/Reauthentication.js | 14 --------- src/libs/Middleware/Retry.js | 40 +------------------------ src/libs/Network/MainQueue.js | 11 ++----- src/libs/Network/index.js | 13 ++++++-- src/libs/actions/Session/index.js | 4 --- tests/unit/NetworkTest.js | 14 ++++----- 10 files changed, 26 insertions(+), 81 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 8b63cbf28fe8..f291e9120284 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -314,6 +314,7 @@ const CONST = { SUCCESS: 200, NOT_AUTHENTICATED: 407, EXP_ERROR: 666, + OFFLINE: 0, }, ERROR: { XHR_FAILED: 'xhrFailed', diff --git a/src/libs/API.js b/src/libs/API.js index beb567a5b799..14455aad1627 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -76,7 +76,6 @@ function User_SignUp(parameters) { * @param {String} parameters.partnerPassword * @param {String} parameters.partnerUserID * @param {String} parameters.partnerUserSecret - * @param {Boolean} [parameters.shouldRetry] * @param {String} [parameters.email] * @returns {Promise} */ @@ -108,12 +107,11 @@ function DeleteFund(parameters) { * @param {String} parameters.partnerUserID * @param {String} parameters.partnerName * @param {String} parameters.partnerPassword - * @param {Boolean} parameters.shouldRetry * @returns {Promise} */ function DeleteLogin(parameters) { const commandName = 'DeleteLogin'; - requireParameters(['partnerUserID', 'partnerName', 'partnerPassword', 'shouldRetry'], + requireParameters(['partnerUserID', 'partnerName', 'partnerPassword'], parameters, commandName); // Non-cancellable request: during logout, when requests are cancelled, we don't want to cancel the actual logout request diff --git a/src/libs/Authentication.js b/src/libs/Authentication.js index f0139ac7e17e..4fadbef30b04 100644 --- a/src/libs/Authentication.js +++ b/src/libs/Authentication.js @@ -40,7 +40,6 @@ function Authenticate(parameters) { partnerUserSecret: parameters.partnerUserSecret, twoFactorAuthCode: parameters.twoFactorAuthCode, authToken: parameters.authToken, - shouldRetry: false, // Force this request to be made because the network queue is paused when re-authentication is happening forceNetworkRequest: true, @@ -101,6 +100,10 @@ function reauthenticate(command = '') { partnerUserSecret: credentials.autoGeneratedPassword, }) .then((response) => { + if (response.jsonCode === CONST.JSON_CODE.OFFLINE) { + throw new Error(CONST.ERROR.API_OFFLINE); + } + // If authentication fails throw so that we hit // the catch below and redirect to sign in if (response.jsonCode !== 200) { diff --git a/src/libs/Log.js b/src/libs/Log.js index b0f82656a32a..6a0ccc41f899 100644 --- a/src/libs/Log.js +++ b/src/libs/Log.js @@ -37,7 +37,6 @@ function LogCommand(parameters) { function serverLoggingCallback(logger, params) { const requestParams = params; requestParams.shouldProcessImmediately = false; - requestParams.shouldRetry = false; requestParams.expensifyCashAppVersion = `expensifyCash[${getPlatform()}]${version}`; if (requestParams.parameters) { requestParams.parameters = JSON.stringify(params.parameters); diff --git a/src/libs/Middleware/Reauthentication.js b/src/libs/Middleware/Reauthentication.js index d75b3bde86e0..a9419e5b63d4 100644 --- a/src/libs/Middleware/Reauthentication.js +++ b/src/libs/Middleware/Reauthentication.js @@ -1,4 +1,3 @@ -import lodashGet from 'lodash/get'; import CONST from '../../CONST'; import * as NetworkStore from '../Network/NetworkStore'; import * as MainQueue from '../Network/MainQueue'; @@ -24,19 +23,6 @@ function Reauthentication(response, request, isFromSequentialQueue) { } if (data.jsonCode === CONST.JSON_CODE.NOT_AUTHENTICATED) { - // There are some API requests that should not be retried when there is an auth failure like - // creating and deleting logins. In those cases, they should handle the original response instead - // of the new response created by handleExpiredAuthToken. - const shouldRetry = lodashGet(request, 'data.shouldRetry'); - if (!shouldRetry) { - if (isFromSequentialQueue) { - return data; - } - - request.resolve(data); - return; - } - // We are already authenticating if (NetworkStore.isAuthenticating()) { if (isFromSequentialQueue) { diff --git a/src/libs/Middleware/Retry.js b/src/libs/Middleware/Retry.js index 03f62bef0bd7..b28490ba7f20 100644 --- a/src/libs/Middleware/Retry.js +++ b/src/libs/Middleware/Retry.js @@ -1,41 +1,7 @@ -import lodashGet from 'lodash/get'; -import RetryCounter from '../RetryCounter'; import * as PersistedRequests from '../actions/PersistedRequests'; -import * as MainQueue from '../Network/MainQueue'; import Log from '../Log'; import CONST from '../../CONST'; -// Keep track of retries for any non-persisted requests -const mainQueueRetryCounter = new RetryCounter(); - -/** - * @param {Object} queuedRequest - * @param {*} error - * @returns {Boolean} true if we were able to retry - */ -function retryFailedRequest(queuedRequest, error) { - // When the request did not reach its destination add it back the queue to be retried if we can - const shouldRetry = lodashGet(queuedRequest, 'data.shouldRetry'); - if (!shouldRetry) { - return false; - } - - const retryCount = mainQueueRetryCounter.incrementRetries(queuedRequest); - Log.info('[Network] A retryable request failed', false, { - retryCount, - command: queuedRequest.command, - error: error.message, - }); - - if (retryCount < CONST.NETWORK.MAX_REQUEST_RETRIES) { - MainQueue.push(queuedRequest); - return true; - } - - Log.info('[Network] Request was retried too many times with no success. No more retries left'); - return false; -} - /** * @param {Promise} response * @param {Object} request @@ -55,17 +21,13 @@ function Retry(response, request, isFromSequentialQueue) { return; } - if (retryFailedRequest(request, error)) { - return; - } - if (request.command !== 'Log') { Log.hmmm('[Network] Handled error when making request', error); } else { console.debug('[Network] There was an error in the Log API command, unable to log to server!', error); } - request.reject(new Error(CONST.ERROR.API_OFFLINE)); + request.resolve({jsonCode: CONST.JSON_CODE.OFFLINE}); }); } diff --git a/src/libs/Network/MainQueue.js b/src/libs/Network/MainQueue.js index 2070959668ce..9741d284f6fe 100644 --- a/src/libs/Network/MainQueue.js +++ b/src/libs/Network/MainQueue.js @@ -1,5 +1,4 @@ import _ from 'underscore'; -import lodashGet from 'lodash/get'; import * as NetworkStore from './NetworkStore'; import * as SequentialQueue from './SequentialQueue'; import HttpUtils from '../HttpUtils'; @@ -57,18 +56,12 @@ function process() { // Some requests should be retried and will end up here if the following conditions are met: // - we are in the process of authenticating and the request is retryable (most are) // - the request does not have forceNetworkRequest === true (this will trigger it to process immediately) - // - the request does not have shouldRetry === false (specified when we do not want to retry, defaults to true) const requestsToProcessOnNextRun = []; _.each(networkRequestQueue, (queuedRequest) => { - // Check if we can make this request at all and if we can't see if we should save it for the next run or chuck it into the ether + // Save request for the next run if we can't make it yet if (!canMakeRequest(queuedRequest)) { - const shouldRetry = lodashGet(queuedRequest, 'data.shouldRetry'); - if (shouldRetry) { - requestsToProcessOnNextRun.push(queuedRequest); - } else { - console.debug('Skipping request that should not be re-tried: ', {command: queuedRequest.command}); - } + requestsToProcessOnNextRun.push(queuedRequest); return; } diff --git a/src/libs/Network/index.js b/src/libs/Network/index.js index b4d6dab94f36..6cc267d1538f 100644 --- a/src/libs/Network/index.js +++ b/src/libs/Network/index.js @@ -4,6 +4,7 @@ import CONST from '../../CONST'; import * as MainQueue from './MainQueue'; import * as SequentialQueue from './SequentialQueue'; import {version} from '../../../package.json'; +import * as NetworkStore from './NetworkStore'; // We must wait until the ActiveClientManager is ready so that we ensure only the "leader" tab processes any persisted requests ActiveClientManager.isReady().then(() => { @@ -31,11 +32,10 @@ function post(command, data = {}, type = CONST.NETWORK.METHOD.POST, shouldUseSec shouldUseSecure, }; - // By default, request are retry-able and cancellable - // (e.g. any requests currently happening when the user logs out are cancelled) request.data = { ...data, - shouldRetry: lodashGet(data, 'shouldRetry', true), + + // By default, requests are cancellable and any requests currently happening when the user logs out are cancelled. canCancel: lodashGet(data, 'canCancel', true), appversion: version, }; @@ -46,6 +46,13 @@ function post(command, data = {}, type = CONST.NETWORK.METHOD.POST, shouldUseSec return; } + // If we are offline and attempting to make a read request then we will resolve this promise with a non-200 jsonCode that implies it + // could not succeed. We do this any so any requests that block the UI will be able to handle this case (e.g. reset loading flag) + if (NetworkStore.isOffline()) { + request.resolve({jsonCode: CONST.JSON_CODE.OFFLINE}); + return; + } + // Add promise handlers to any request that we are not persisting request.resolve = resolve; request.reject = reject; diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index 8d21d8ff73d5..a9eab65ba3f8 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -76,7 +76,6 @@ function signOut() { partnerUserID: credentials.autoGeneratedLogin, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, - shouldRetry: false, }) .catch(error => Onyx.merge(ONYXKEYS.SESSION, {error: error.message})); } @@ -183,7 +182,6 @@ function createTemporaryLogin(authToken, email) { partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, partnerUserID: autoGeneratedLogin, partnerUserSecret: autoGeneratedPassword, - shouldRetry: false, forceNetworkRequest: true, email, includeEncryptedAuthToken: true, @@ -202,7 +200,6 @@ function createTemporaryLogin(authToken, email) { partnerUserID: credentials.autoGeneratedLogin, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, - shouldRetry: false, }) .catch(Log.info); } @@ -444,7 +441,6 @@ function authenticatePusher(socketID, channelName, callback) { API.Push_Authenticate({ socket_id: socketID, channel_name: channelName, - shouldRetry: false, forceNetworkRequest: true, }) .then((response) => { diff --git a/tests/unit/NetworkTest.js b/tests/unit/NetworkTest.js index 4e3666725903..b8f4e5323546 100644 --- a/tests/unit/NetworkTest.js +++ b/tests/unit/NetworkTest.js @@ -466,25 +466,25 @@ test('test bad response will log alert', () => { }); }); -test('test Failed to fetch error for requests not flagged with shouldRetry will throw API OFFLINE error', () => { +test('test Failed to fetch error for requests will resolve with jsonCode: 0', () => { // Setup xhr handler that rejects once with a 502 Bad Gateway global.fetch = jest.fn().mockRejectedValue(new Error(CONST.ERROR.FAILED_TO_FETCH)); - const onRejected = jest.fn(); + const onResolved = jest.fn(); // Given we have a request made while online return Onyx.set(ONYXKEYS.NETWORK, {isOffline: false}) .then(() => { // When network calls with are made - Network.post('mock command', {param1: 'value1', shouldRetry: false}) - .catch(onRejected); + Network.post('mock command', {param1: 'value1'}) + .resolve(onResolved); return waitForPromisesToResolve(); }) .then(() => { - const error = onRejected.mock.calls[0][0]; - expect(onRejected).toHaveBeenCalled(); - expect(error.message).toBe(CONST.ERROR.API_OFFLINE); + const response = onResolved.mock.calls[0][0]; + expect(onResolved).toHaveBeenCalled(); + expect(response.jsonCode).toBe(CONST.JSON_CODE.OFFLINE); }); }); From cee6581798a128ea58a53bf530f45235a189edcc Mon Sep 17 00:00:00 2001 From: mollfpr Date: Tue, 3 May 2022 10:31:31 +0800 Subject: [PATCH 032/287] Update src/styles/getModalStyles.js Co-authored-by: Santhoshkumar Sellavel <85645967+Santhosh-Sellavel@users.noreply.github.com> --- src/styles/getModalStyles.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/getModalStyles.js b/src/styles/getModalStyles.js index e08390a06015..40cd19ad48dc 100644 --- a/src/styles/getModalStyles.js +++ b/src/styles/getModalStyles.js @@ -85,7 +85,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - // Only apply top padding on iOS since only iOS using SafeAreaView and the top insets is not apply + // Only apply top padding on iOS since it's the only platform using SafeAreaView shouldAddTopSafeAreaPadding = getPlatform() === CONST.PLATFORM.IOS; break; case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: From 126598b531501bad90bc8dd9d62c46552b5e57b7 Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Tue, 3 May 2022 19:29:25 +0530 Subject: [PATCH 033/287] added conditional fill --- src/components/Avatar.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 8d47ef043507..706d4cddf637 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -59,7 +59,8 @@ class Avatar extends PureComponent { ? ( From 5ace2ad79b57b26e9a0bd39965788a508dbcafa4 Mon Sep 17 00:00:00 2001 From: Tushu17 Date: Wed, 4 May 2022 01:07:38 +0530 Subject: [PATCH 034/287] remove pressable --- src/components/ReportWelcomeText.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/components/ReportWelcomeText.js b/src/components/ReportWelcomeText.js index f767b18a0bae..ae11faff0e24 100644 --- a/src/components/ReportWelcomeText.js +++ b/src/components/ReportWelcomeText.js @@ -4,7 +4,6 @@ import lodashGet from 'lodash/get'; import Str from 'expensify-common/lib/str'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; -import {Pressable} from 'react-native'; import styles from '../styles/styles'; import Text from './Text'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; @@ -108,13 +107,9 @@ const ReportWelcomeText = (props) => { {roomWelcomeMessage.phrase1} - Navigation.navigate(ROUTES.getReportDetailsRoute(props.report.reportID))} - > - - {props.report.reportName} - - + Navigation.navigate(ROUTES.getReportDetailsRoute(props.report.reportID))}> + {props.report.reportName} + {roomWelcomeMessage.phrase2} @@ -131,11 +126,9 @@ const ReportWelcomeText = (props) => { }, index) => ( - Navigation.navigate(ROUTES.getDetailsRoute(login))}> - - {displayName} - - + Navigation.navigate(ROUTES.getDetailsRoute(login))}> + {displayName} + {!_.isEmpty(pronouns) && {` (${pronouns})`}} {(index === displayNamesWithTooltips.length - 1) && .} From 0a1f26f69957d81758f2d5c28ba58d2d3803a301 Mon Sep 17 00:00:00 2001 From: Tushu17 Date: Wed, 4 May 2022 01:10:43 +0530 Subject: [PATCH 035/287] remove view --- src/components/Tooltip/index.native.js | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/components/Tooltip/index.native.js b/src/components/Tooltip/index.native.js index ea7556928c77..89fb88bd8a39 100644 --- a/src/components/Tooltip/index.native.js +++ b/src/components/Tooltip/index.native.js @@ -1,32 +1,21 @@ -import React from 'react'; -import {View} from 'react-native'; import PropTypes from 'prop-types'; // We can't use the common component for the Tooltip as Web implementation uses DOM specific method to // render the View which is not present on the Mobile. const propTypes = { - /** Styles to be assigned to the Tooltip wrapper views */ - containerStyles: PropTypes.arrayOf(PropTypes.object), - /** Children to wrap with Tooltip. */ children: PropTypes.node.isRequired, }; -const defaultProps = { - containerStyles: [], -}; - /** * @param {propTypes} props * @returns {ReactNodeLike} */ const Tooltip = props => ( - - {props.children} - + props.children ); Tooltip.propTypes = propTypes; -Tooltip.defaultProps = defaultProps; Tooltip.displayName = 'Tooltip'; + export default Tooltip; From 39240a99ec2c9afeb681f5d36fc2e160bbb37f15 Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Tue, 3 May 2022 23:35:31 +0200 Subject: [PATCH 036/287] change or remove hasError on Pickers --- src/components/AddPlaidBankAccount.js | 2 +- src/components/Picker/BasePicker/basePickerPropTypes.js | 4 ---- src/components/Picker/BasePicker/index.js | 2 +- src/components/StatePicker.js | 1 - src/pages/ReimbursementAccount/AddressForm.js | 1 - src/pages/ReimbursementAccount/CompanyStep.js | 4 ++-- src/pages/settings/Payments/AddDebitCardPage.js | 2 +- src/pages/workspace/WorkspaceNewRoomPage.js | 1 - 8 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/components/AddPlaidBankAccount.js b/src/components/AddPlaidBankAccount.js index 39d1a8f9dd09..9e2b2c373472 100644 --- a/src/components/AddPlaidBankAccount.js +++ b/src/components/AddPlaidBankAccount.js @@ -253,7 +253,7 @@ class AddPlaidBankAccount extends React.Component { label: this.props.translate('bankAccount.chooseAnAccount'), } : {}} value={this.state.selectedIndex} - hasError={this.getErrors().selectedBank} + errorText={this.getErrors().selectedBank} /> {!_.isUndefined(this.state.selectedIndex) && this.props.isPasswordRequired && ( diff --git a/src/components/Picker/BasePicker/basePickerPropTypes.js b/src/components/Picker/BasePicker/basePickerPropTypes.js index 635c4cfc6c18..20cf8f0ec213 100644 --- a/src/components/Picker/BasePicker/basePickerPropTypes.js +++ b/src/components/Picker/BasePicker/basePickerPropTypes.js @@ -11,9 +11,6 @@ const propTypes = { /** Whether or not to show the disabled styles */ disabled: PropTypes.bool, - /** Should the picker be styled for errors */ - hasError: PropTypes.bool, - /** Error text to display */ errorText: PropTypes.string, @@ -58,7 +55,6 @@ const propTypes = { }; const defaultProps = { disabled: false, - hasError: false, errorText: '', focused: false, placeholder: {}, diff --git a/src/components/Picker/BasePicker/index.js b/src/components/Picker/BasePicker/index.js index 1319cd8bfa6f..0fade3e32f05 100644 --- a/src/components/Picker/BasePicker/index.js +++ b/src/components/Picker/BasePicker/index.js @@ -33,7 +33,7 @@ class BasePicker extends React.Component { } render() { - const hasError = !_.isEmpty(this.props.errorText) || this.props.hasError; + const hasError = !_.isEmpty(this.props.errorText); return ( ( onInputChange={props.onChange} value={props.value} label={props.label || props.translate('common.state')} - hasError={props.hasError} errorText={props.errorText} /> ); diff --git a/src/pages/ReimbursementAccount/AddressForm.js b/src/pages/ReimbursementAccount/AddressForm.js index fdf0150f92d2..d8c866ae6463 100644 --- a/src/pages/ReimbursementAccount/AddressForm.js +++ b/src/pages/ReimbursementAccount/AddressForm.js @@ -72,7 +72,6 @@ const AddressForm = props => ( value={props.values.state} onChange={value => props.onFieldChange({state: value})} errorText={props.errors.state ? props.translate('bankAccount.error.addressState') : ''} - hasError={Boolean(props.errors.state)} /> diff --git a/src/pages/ReimbursementAccount/CompanyStep.js b/src/pages/ReimbursementAccount/CompanyStep.js index 384a7bfeba05..0ddc276835a4 100644 --- a/src/pages/ReimbursementAccount/CompanyStep.js +++ b/src/pages/ReimbursementAccount/CompanyStep.js @@ -271,7 +271,7 @@ class CompanyStep extends React.Component { onInputChange={value => this.clearErrorAndSetValue('incorporationType', value)} value={this.state.incorporationType} placeholder={{value: '', label: '-'}} - hasError={this.getErrors().incorporationType} + errorText={this.getErrors().incorporationType} /> @@ -289,7 +289,7 @@ class CompanyStep extends React.Component { label={this.props.translate('companyStep.incorporationState')} onChange={value => this.clearErrorAndSetValue('incorporationState', value)} value={this.state.incorporationState} - hasError={this.getErrors().incorporationState} + errorText={this.getErrors().incorporationState} /> this.clearErrorAndSetValue('addressState', value)} value={this.state.addressState} - hasError={lodashGet(this.state.errors, 'addressState', false)} + errorText={lodashGet(this.state.errors, 'addressState', {})} /> diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index 3b2ce0417fe3..6aec1b883eb3 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -171,7 +171,6 @@ class WorkspaceNewRoomPage extends React.Component { placeholder={{value: '', label: this.props.translate('newRoomPage.selectAWorkspace')}} items={this.state.workspaceOptions} errorText={this.state.errors.policyID} - hasError={Boolean(this.state.errors.policyID)} onInputChange={policyID => this.clearErrorAndSetValue('policyID', policyID)} /> From 40de6cfdb03c9e8e97051df1463dcba8e1a74b6f Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Wed, 4 May 2022 00:43:31 +0200 Subject: [PATCH 037/287] change lodashGet to getErrorText inside StatePicker errorText --- src/pages/settings/Payments/AddDebitCardPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js index 436ad4697acc..c831d3980d1b 100644 --- a/src/pages/settings/Payments/AddDebitCardPage.js +++ b/src/pages/settings/Payments/AddDebitCardPage.js @@ -301,7 +301,7 @@ class DebitCardPage extends Component { this.clearErrorAndSetValue('addressState', value)} value={this.state.addressState} - errorText={lodashGet(this.state.errors, 'addressState', {})} + errorText={this.getErrorText('addressState')} /> From 0a1fab46f749adf7b9577bfac87e3f81b465adef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Wed, 4 May 2022 09:55:13 +0300 Subject: [PATCH 038/287] Changed comments , added meaningful variable names --- src/components/ImageView/index.js | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index cad5d47c6bb5..caa9b7914e05 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -94,21 +94,21 @@ class ImageView extends PureComponent { * @param {SyntheticEvent} e */ onContainerPress(e) { - let sX; - let sY; + let scrollX; + let scrollY; if (this.isZoomed && !this.state.isDragging) { const {offsetX, offsetY} = e.nativeEvent; const delta = this.getScrollOffset(offsetX / this.state.zoomScale, offsetY / this.state.zoomScale); - sX = delta.offsetX; - sY = delta.offsetY; + scrollX = delta.offsetX; + scrollY = delta.offsetY; } if (this.isZoomed && this.state.isDragging && this.state.isMouseDown) { this.setState({isDragging: false, isMouseDown: false}); } else if (this.isZoomed) { this.setState({isZoomed: this.isZoomed}, () => { - this.scrollableRef.scrollTop = sY; - this.scrollableRef.scrollLeft = sX; + this.scrollableRef.scrollTop = scrollY; + this.scrollableRef.scrollLeft = scrollX; }); } } @@ -160,23 +160,23 @@ class ImageView extends PureComponent { * @returns {Object} converted touch point */ getScrollOffset(x, y) { - let sx; - let sy; + let offsetX; + let offsetY; - // container size bigger than clicked position offset + // Container size bigger than clicked position offset if (x <= (this.state.containerWidth / 2)) { - sx = 0; + offsetX = 0; } else if (x > this.state.containerWidth / 2) { - // minus half of container size because we want to be center clicked position - sx = x - (this.state.containerWidth / 2); + // Minus half of container size because we want to be center clicked position + offsetX = x - (this.state.containerWidth / 2); } if (y <= this.state.containerHeight / 2) { - sy = 0; + offsetY = 0; } else if (y > this.state.containerHeight / 2) { - // minus half of container size because we want to be center clicked position - sy = y - (this.state.containerHeight / 2); + // Minus half of container size because we want to be center clicked position + offsetY = y - (this.state.containerHeight / 2); } - return {offsetX: sx, offsetY: sy}; + return {offsetX, offsetY}; } trackMovement(e) { From ff8acbb1c62224b0b9352ee06d3be815da9668f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Wed, 4 May 2022 13:59:21 +0300 Subject: [PATCH 039/287] updated logic comments added --- src/components/ImageView/index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index caa9b7914e05..52c852635d7a 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -98,6 +98,9 @@ class ImageView extends PureComponent { let scrollY; if (this.isZoomed && !this.state.isDragging) { const {offsetX, offsetY} = e.nativeEvent; + + // We divide the clicked positions by the zoomScale. + // We need pixel coordinates. const delta = this.getScrollOffset(offsetX / this.state.zoomScale, offsetY / this.state.zoomScale); scrollX = delta.offsetX; scrollY = delta.offsetY; @@ -106,6 +109,7 @@ class ImageView extends PureComponent { if (this.isZoomed && this.state.isDragging && this.state.isMouseDown) { this.setState({isDragging: false, isMouseDown: false}); } else if (this.isZoomed) { + // We set isZoomed state then scroll image for calculating positions this.setState({isZoomed: this.isZoomed}, () => { this.scrollableRef.scrollTop = scrollY; this.scrollableRef.scrollLeft = scrollX; @@ -118,6 +122,8 @@ class ImageView extends PureComponent { return; } + // We hold to setting isZoomed state if true + // Because when set isZoomed state can't getting actual position user clicked this.isZoomed = !this.state.isZoomed; if (this.isZoomed === false) { this.setState(prevState => ({ @@ -132,7 +138,7 @@ class ImageView extends PureComponent { } /** - * When open image, set image left/right/top/bottom point and width, height + * When open image, set image width and height. If containerHeight is set before set zoomScale * @param {Number} imageWidth * @param {Number} imageHeight */ From 09911676fb32744e94cb3707d5006d5847d196fb Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Wed, 4 May 2022 11:41:33 +0000 Subject: [PATCH 040/287] update fetch conditino --- src/pages/ReimbursementAccount/EnableStep.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ReimbursementAccount/EnableStep.js b/src/pages/ReimbursementAccount/EnableStep.js index 8c2ae53cd87e..7c0b58bf0157 100644 --- a/src/pages/ReimbursementAccount/EnableStep.js +++ b/src/pages/ReimbursementAccount/EnableStep.js @@ -51,7 +51,7 @@ class EnableStep extends React.Component { } componentDidUpdate(prevProps) { - if (prevProps.network.isOffline && !this.props.network.isOffline) { + if (!prevProps.network.isOffline || this.props.network.isOffline) { return; } From 5477628812f3fde87a0cad02b659c9dea5b23bbb Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Wed, 4 May 2022 11:45:03 +0000 Subject: [PATCH 041/287] update refetch data condition --- src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js index a8c3164a085c..9dbfe8dda54b 100644 --- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js +++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js @@ -69,7 +69,7 @@ class BasePaymentsPage extends React.Component { } componentDidUpdate(prevProps) { - if (prevProps.network.isOffline === this.props.network.isOffline) { + if (!prevProps.network.isOffline || this.props.network.isOffline) { return; } From 91980c75cdade359d14756d5a4b99c81a9c237bd Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Wed, 4 May 2022 12:42:22 +0000 Subject: [PATCH 042/287] refetch actions for IOUModal.js --- src/pages/iou/IOUModal.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index a75b7f990cfe..9c6640dc2378 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -26,6 +26,8 @@ import CONST from '../../CONST'; import KeyboardAvoidingView from '../../components/KeyboardAvoidingView'; import * as PersonalDetails from '../../libs/actions/PersonalDetails'; import ROUTES from '../../ROUTES'; +import networkPropTypes from '../../components/networkPropTypes'; +import {withNetwork} from '../../components/OnyxProvider'; /** * IOU modal for requesting money and splitting bills. @@ -50,6 +52,9 @@ const propTypes = { localCurrencyCode: PropTypes.string, }), + /** Information about the network */ + network: networkPropTypes.isRequired, + // Holds data related to IOU view state, rather than the underlying IOU data. iou: PropTypes.shape({ /** Whether or not transaction creation has started */ @@ -138,11 +143,15 @@ class IOUModal extends Component { } componentDidMount() { - PersonalDetails.fetchLocalCurrency(); + this.fetchData(); IOU.setIOUSelectedCurrency(this.props.myPersonalDetails.localCurrencyCode); } componentDidUpdate(prevProps) { + if (prevProps.network.isOffline && !this.props.network.isOffline) { + this.fetchData(); + } + // Successfully close the modal if transaction creation has ended and there is no error if (prevProps.iou.creatingIOUTransaction && !this.props.iou.creatingIOUTransaction && !this.props.iou.error) { Navigation.dismissModal(); @@ -215,6 +224,10 @@ class IOUModal extends Component { return this.props.translate(this.steps[currentStepIndex]) || ''; } + fetchData() { + PersonalDetails.fetchLocalCurrency(); + } + /** * Update comment whenever user enters any new text * @@ -453,6 +466,7 @@ IOUModal.defaultProps = defaultProps; export default compose( withLocalize, + withNetwork(), withOnyx({ report: { key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${lodashGet(route, 'params.reportID', '')}`, From 56c811931332eb924c4aeac8cf099c5ce72b3a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Wed, 4 May 2022 16:47:18 +0300 Subject: [PATCH 043/287] correcting a typo --- src/components/ImageView/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 52c852635d7a..0c4628b52a72 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -122,7 +122,7 @@ class ImageView extends PureComponent { return; } - // We hold to setting isZoomed state if true + // We hold for set isZoomed state if true // Because when set isZoomed state can't getting actual position user clicked this.isZoomed = !this.state.isZoomed; if (this.isZoomed === false) { From 3e87eea6884f5e1ba417800d5b2062a5a27594c9 Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Wed, 4 May 2022 19:46:41 +0530 Subject: [PATCH 044/287] added condition for height and width in avatar, added different fallback icon for workspace --- .../avatars/fallback-workspace-avatar.svg | 15 +++++++++++++++ src/components/Avatar.js | 19 +++++++++++++------ src/components/AvatarWithImagePicker.js | 5 +++++ src/components/Icon/Expensicons.js | 2 ++ src/components/MenuItem.js | 2 ++ src/components/menuItemPropTypes.js | 3 +++ src/pages/settings/InitialSettingsPage.js | 2 ++ src/pages/workspace/WorkspaceInitialPage.js | 2 ++ src/pages/workspace/WorkspaceSettingsPage.js | 1 + src/styles/StyleUtils.js | 1 + 10 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 assets/images/avatars/fallback-workspace-avatar.svg diff --git a/assets/images/avatars/fallback-workspace-avatar.svg b/assets/images/avatars/fallback-workspace-avatar.svg new file mode 100644 index 000000000000..ac2f58122a0f --- /dev/null +++ b/assets/images/avatars/fallback-workspace-avatar.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 706d4cddf637..e59b0cff0320 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -24,6 +24,9 @@ const propTypes = { /** The fill color for the icon. Can be hex, rgb, rgba, or valid react-native named color such as 'red' or 'blue' */ fill: PropTypes.string, + + /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ + isWorkSpace: PropTypes.bool, }; const defaultProps = { @@ -32,6 +35,7 @@ const defaultProps = { containerStyles: [], size: CONST.AVATAR_SIZE.DEFAULT, fill: themeColors.icon, + isWorkSpace: false, }; class Avatar extends PureComponent { @@ -53,20 +57,23 @@ class Avatar extends PureComponent { ]; const iconSize = StyleUtils.getAvatarSize(this.props.size); + const isHeightDefine = _.find(this.props.imageStyles, 'height'); + const isWidthDefine = _.find(this.props.imageStyles, 'width'); + const fallbackAvatar = this.props.isWorkSpace ? Expensicons.FallbackWorkspaceAvatar : Expensicons.FallbackAvatar; + return ( {_.isFunction(this.props.source) || this.state.imageError ? ( ) : ( - this.setState({imageError: true})} /> + this.setState({imageError: true})} /> )} ); diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 7ac5303b02b8..a75b7a016fd7 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -53,6 +53,9 @@ const propTypes = { /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), + /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ + isWorkSpace: PropTypes.bool, + ...withLocalizePropTypes, }; @@ -65,6 +68,7 @@ const defaultProps = { isUsingDefaultAvatar: false, isUploading: false, size: CONST.AVATAR_SIZE.DEFAULT, + isWorkSpace: false, }; class AvatarWithImagePicker extends React.Component { @@ -181,6 +185,7 @@ class AvatarWithImagePicker extends React.Component { containerStyles={styles.avatarLarge} imageStyles={[styles.avatarLarge, styles.alignSelfCenter]} source={this.props.avatarURL} + isWorkSpace={this.props.isWorkSpace} /> ) : ( diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js index dcb9107525dd..a1cf6ff17ca8 100644 --- a/src/components/Icon/Expensicons.js +++ b/src/components/Icon/Expensicons.js @@ -32,6 +32,7 @@ import Eye from '../../../assets/images/eye.svg'; import EyeDisabled from '../../../assets/images/eye-disabled.svg'; import ExpensifyCard from '../../../assets/images/expensifycard.svg'; import FallbackAvatar from '../../../assets/images/avatars/fallback-avatar.svg'; +import FallbackWorkspaceAvatar from '../../../assets/images/avatars/fallback-workspace-avatar.svg'; import Gallery from '../../../assets/images/gallery.svg'; import Gear from '../../../assets/images/gear.svg'; import Hashtag from '../../../assets/images/hashtag.svg'; @@ -112,6 +113,7 @@ export { EyeDisabled, ExpensifyCard, FallbackAvatar, + FallbackWorkspaceAvatar, Gallery, Gear, Hashtag, diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 6c5c20eb008e..c20a346dd538 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -39,6 +39,7 @@ const defaultProps = { iconType: 'icon', onPress: () => {}, interactive: true, + isWorkSpace: false, }; const MenuItem = props => ( @@ -87,6 +88,7 @@ const MenuItem = props => ( )} diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index 0ad5a43498af..5906634c4dff 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -63,6 +63,9 @@ const propTypes = { /** Whether the menu item should be interactive at all */ interactive: PropTypes.bool, + + /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ + isWorkSpace: PropTypes.bool, }; export default propTypes; diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 2bb4544fabb2..d5190b7aacec 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -141,6 +141,7 @@ const InitialSettingsPage = (props) => { action: () => Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policy.id)), iconStyles: [styles.popoverMenuIconEmphasized], iconFill: themeColors.iconReversed, + isWorkSpace: true, })) .value(); menuItems.push(...defaultMenuItems); @@ -195,6 +196,7 @@ const InitialSettingsPage = (props) => { iconFill={item.iconFill} shouldShowRightIcon badgeText={(isPaymentItem && Permissions.canUseWallet(props.betas)) ? walletBalance : undefined} + isWorkSpace={item.isWorkSpace} /> ); })} diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 3e43faf56c14..9d165944e30d 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -156,6 +156,7 @@ class WorkspaceInitialPage extends React.Component { containerStyles={styles.avatarLarge} imageStyles={[styles.avatarLarge, styles.alignSelfCenter]} source={this.props.policy.avatarURL} + isWorkSpace /> ) : ( @@ -200,6 +201,7 @@ class WorkspaceInitialPage extends React.Component { iconRight={item.iconRight} onPress={() => item.action()} shouldShowRightIcon + isWorkSpace /> ))} diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index a0bb45fcbe6b..33c12ee75e81 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -149,6 +149,7 @@ class WorkspaceSettingsPage extends React.Component { fill={defaultTheme.iconSuccessFill} /> )} + isWorkSpace style={[styles.mb3]} anchorPosition={{top: 172, right: 18}} isUsingDefaultAvatar={!this.state.previewAvatarURL} diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js index 7b1ced1f7ec6..4da69f75d427 100644 --- a/src/styles/StyleUtils.js +++ b/src/styles/StyleUtils.js @@ -36,6 +36,7 @@ function getAvatarStyle(size) { height: avatarSize, width: avatarSize, borderRadius: avatarSize, + backgroundColor: themeColors.offline, }; } From babaa26e7423cccada7efdde987b395781d10d0f Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Thu, 5 May 2022 00:30:43 +0800 Subject: [PATCH 045/287] refactor getModalStyles func to "shim" --- .../{ => getModalStyles}/getModalStyles.js | 20 ++++++------------- src/styles/getModalStyles/index.android.js | 8 ++++++++ src/styles/getModalStyles/index.js | 10 ++++++++++ 3 files changed, 24 insertions(+), 14 deletions(-) rename src/styles/{ => getModalStyles}/getModalStyles.js (90%) create mode 100644 src/styles/getModalStyles/index.android.js create mode 100644 src/styles/getModalStyles/index.js diff --git a/src/styles/getModalStyles.js b/src/styles/getModalStyles/getModalStyles.js similarity index 90% rename from src/styles/getModalStyles.js rename to src/styles/getModalStyles/getModalStyles.js index e08390a06015..805fedf17140 100644 --- a/src/styles/getModalStyles.js +++ b/src/styles/getModalStyles/getModalStyles.js @@ -1,10 +1,9 @@ -import CONST from '../CONST'; -import colors from './colors'; -import variables from './variables'; -import themeColors from './themes/default'; -import getPlatform from '../libs/getPlatform'; +import CONST from '../../CONST'; +import colors from '../colors'; +import variables from '../variables'; +import themeColors from '../themes/default'; -export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => { +export default ({shouldModalAddTopSafeAreaPadding = {}}) => (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => { const {isSmallScreenWidth, windowWidth} = windowDimensions; let modalStyle = { @@ -17,7 +16,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty let animationOut; let hideBackdrop = false; let shouldAddBottomSafeAreaPadding = false; - let shouldAddTopSafeAreaPadding = false; + const shouldAddTopSafeAreaPadding = shouldModalAddTopSafeAreaPadding[type] || false; switch (type) { case CONST.MODAL.MODAL_TYPE.CONFIRM: @@ -84,9 +83,6 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty swipeDirection = ['down', 'right']; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - - // Only apply top padding on iOS since only iOS using SafeAreaView and the top insets is not apply - shouldAddTopSafeAreaPadding = getPlatform() === CONST.PLATFORM.IOS; break; case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: // A centered modal that cannot be dismissed with a swipe. @@ -117,9 +113,6 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty swipeDirection = undefined; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - - // Only apply top padding on iOS since only iOS using SafeAreaView and the top insets is not apply - shouldAddTopSafeAreaPadding = getPlatform() === CONST.PLATFORM.IOS; break; case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED: modalStyle = { @@ -201,7 +194,6 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty }; swipeDirection = undefined; shouldAddBottomSafeAreaPadding = true; - shouldAddTopSafeAreaPadding = true; break; default: modalStyle = {}; diff --git a/src/styles/getModalStyles/index.android.js b/src/styles/getModalStyles/index.android.js new file mode 100644 index 000000000000..11347b09babc --- /dev/null +++ b/src/styles/getModalStyles/index.android.js @@ -0,0 +1,8 @@ +import CONST from '../../CONST'; +import getModalStyles from './getModalStyles'; + +export default getModalStyles({ + shouldModalAddTopSafeAreaPadding: { + [CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED]: true, + }, +}); diff --git a/src/styles/getModalStyles/index.js b/src/styles/getModalStyles/index.js new file mode 100644 index 000000000000..446ce34e7f11 --- /dev/null +++ b/src/styles/getModalStyles/index.js @@ -0,0 +1,10 @@ +import CONST from '../../CONST'; +import getModalStyles from './getModalStyles'; + +export default getModalStyles({ + shouldModalAddTopSafeAreaPadding: { + [CONST.MODAL.MODAL_TYPE.CENTERED]: true, + [CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE]: true, + [CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED]: true, + }, +}); From fdf2fe46b3fbaf79bf170a2704f20fe0f35e83c6 Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Wed, 4 May 2022 23:56:51 +0530 Subject: [PATCH 046/287] added size and fallbackIcon props where avatar component used --- src/components/Avatar.js | 13 +++++-------- src/components/AvatarWithImagePicker.js | 7 ++++--- src/components/AvatarWithIndicator.js | 1 + src/components/MenuItem.js | 4 ++-- src/components/menuItemPropTypes.js | 2 +- src/pages/DetailsPage.js | 1 + src/pages/settings/InitialSettingsPage.js | 4 ++-- src/pages/workspace/WorkspaceInitialPage.js | 5 +++-- src/pages/workspace/WorkspaceSettingsPage.js | 2 +- 9 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index e59b0cff0320..e961080bdd49 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -26,7 +26,7 @@ const propTypes = { fill: PropTypes.string, /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ - isWorkSpace: PropTypes.bool, + fallbackIcon: PropTypes.string, }; const defaultProps = { @@ -35,7 +35,7 @@ const defaultProps = { containerStyles: [], size: CONST.AVATAR_SIZE.DEFAULT, fill: themeColors.icon, - isWorkSpace: false, + fallbackIcon: Expensicons.FallbackAvatar, }; class Avatar extends PureComponent { @@ -57,18 +57,15 @@ class Avatar extends PureComponent { ]; const iconSize = StyleUtils.getAvatarSize(this.props.size); - const isHeightDefine = _.find(this.props.imageStyles, 'height'); - const isWidthDefine = _.find(this.props.imageStyles, 'width'); - const fallbackAvatar = this.props.isWorkSpace ? Expensicons.FallbackWorkspaceAvatar : Expensicons.FallbackAvatar; return ( {_.isFunction(this.props.source) || this.state.imageError ? ( ) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index a75b7a016fd7..30bd5bf95dcd 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -54,7 +54,7 @@ const propTypes = { size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ - isWorkSpace: PropTypes.bool, + fallbackIcon: PropTypes.string, ...withLocalizePropTypes, }; @@ -68,7 +68,7 @@ const defaultProps = { isUsingDefaultAvatar: false, isUploading: false, size: CONST.AVATAR_SIZE.DEFAULT, - isWorkSpace: false, + fallbackIcon: Expensicons.FallbackAvatar, }; class AvatarWithImagePicker extends React.Component { @@ -185,7 +185,8 @@ class AvatarWithImagePicker extends React.Component { containerStyles={styles.avatarLarge} imageStyles={[styles.avatarLarge, styles.alignSelfCenter]} source={this.props.avatarURL} - isWorkSpace={this.props.isWorkSpace} + fallbackIcon={this.props.fallbackIcon} + size={this.props.size} /> ) : ( diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index 0db3ff1253ef..aa37769156e3 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -101,6 +101,7 @@ class AvatarWithIndicator extends PureComponent { diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index c20a346dd538..cb488b29fb20 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -39,7 +39,7 @@ const defaultProps = { iconType: 'icon', onPress: () => {}, interactive: true, - isWorkSpace: false, + fallbackIcon: Expensicons.FallbackAvatar, }; const MenuItem = props => ( @@ -88,7 +88,7 @@ const MenuItem = props => ( )} diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index 5906634c4dff..cb1edee344b2 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -65,7 +65,7 @@ const propTypes = { interactive: PropTypes.bool, /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ - isWorkSpace: PropTypes.bool, + fallbackIcon: PropTypes.string, }; export default propTypes; diff --git a/src/pages/DetailsPage.js b/src/pages/DetailsPage.js index 35b81314e72d..7faab14ef8ed 100755 --- a/src/pages/DetailsPage.js +++ b/src/pages/DetailsPage.js @@ -114,6 +114,7 @@ const DetailsPage = (props) => { containerStyles={[styles.avatarLarge, styles.mb3]} imageStyles={[styles.avatarLarge]} source={details.avatar} + size={CONST.AVATAR_SIZE.LARGE} /> )} diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index d5190b7aacec..e9374be7f609 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -141,7 +141,7 @@ const InitialSettingsPage = (props) => { action: () => Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policy.id)), iconStyles: [styles.popoverMenuIconEmphasized], iconFill: themeColors.iconReversed, - isWorkSpace: true, + fallbackIcon: Expensicons.FallbackWorkspaceAvatar, })) .value(); menuItems.push(...defaultMenuItems); @@ -196,7 +196,7 @@ const InitialSettingsPage = (props) => { iconFill={item.iconFill} shouldShowRightIcon badgeText={(isPaymentItem && Permissions.canUseWallet(props.betas)) ? walletBalance : undefined} - isWorkSpace={item.isWorkSpace} + fallbackIcon={item.fallbackIcon} /> ); })} diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 9d165944e30d..bda5f7c97a2c 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -156,7 +156,8 @@ class WorkspaceInitialPage extends React.Component { containerStyles={styles.avatarLarge} imageStyles={[styles.avatarLarge, styles.alignSelfCenter]} source={this.props.policy.avatarURL} - isWorkSpace + fallbackIcon={Expensicons.FallbackWorkspaceAvatar} + size={CONST.AVATAR_SIZE.LARGE} /> ) : ( @@ -201,7 +202,7 @@ class WorkspaceInitialPage extends React.Component { iconRight={item.iconRight} onPress={() => item.action()} shouldShowRightIcon - isWorkSpace + fallbackIcon={Expensicons.FallbackWorkspaceAvatar} /> ))} diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 33c12ee75e81..f38665ee9dfe 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -149,7 +149,7 @@ class WorkspaceSettingsPage extends React.Component { fill={defaultTheme.iconSuccessFill} /> )} - isWorkSpace + fallbackIcon={Expensicons.FallbackWorkspaceAvatar} style={[styles.mb3]} anchorPosition={{top: 172, right: 18}} isUsingDefaultAvatar={!this.state.previewAvatarURL} From 4fb557ff6f3407c62143c0bf1fbe9c9451fd8932 Mon Sep 17 00:00:00 2001 From: sahil Date: Thu, 5 May 2022 02:58:10 +0530 Subject: [PATCH 047/287] add minimum width --- src/components/ReportTransaction.js | 2 +- src/styles/styles.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 599fa482c4b0..8572270e9a13 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -93,7 +93,7 @@ class ReportTransaction extends Component { styles.buttonSmall, styles.chatItemComposeSecondaryRowOffset, styles.mb3, - this.isBeingRejected() ? styles.w20 : styles.wAuto, + styles.iouRejectButton, ]} onPress={this.rejectTransaction} > diff --git a/src/styles/styles.js b/src/styles/styles.js index d022567aa233..b074dbbe361b 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -2519,6 +2519,10 @@ const styles = { marginBottom: 40, padding: 16, }, + + iouRejectButton: { + minWidth: 69, + }, }; export default styles; From 7488136ae88b3e19b5edf5237f18a05783acb625 Mon Sep 17 00:00:00 2001 From: sahil Date: Thu, 5 May 2022 03:16:37 +0530 Subject: [PATCH 048/287] fix footer message overflow --- src/components/Banner.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Banner.js b/src/components/Banner.js index 9c67174f0386..87808c22af24 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -31,6 +31,7 @@ const Banner = props => ( styles.p5, styles.borderRadiusNormal, isHovered ? styles.activeComponentBG : styles.hoveredComponentBG, + styles.breakAll, ]} > From 28fb3a1247bcb54c153fe19ef3389d85c4322764 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Wed, 4 May 2022 12:06:55 -1000 Subject: [PATCH 049/287] Fix tests --- src/libs/Network/index.js | 2 +- tests/unit/NetworkTest.js | 83 +++++++++++++++++++++++++++++---------- 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/libs/Network/index.js b/src/libs/Network/index.js index 6cc267d1538f..40d042788bbc 100644 --- a/src/libs/Network/index.js +++ b/src/libs/Network/index.js @@ -49,7 +49,7 @@ function post(command, data = {}, type = CONST.NETWORK.METHOD.POST, shouldUseSec // If we are offline and attempting to make a read request then we will resolve this promise with a non-200 jsonCode that implies it // could not succeed. We do this any so any requests that block the UI will be able to handle this case (e.g. reset loading flag) if (NetworkStore.isOffline()) { - request.resolve({jsonCode: CONST.JSON_CODE.OFFLINE}); + resolve({jsonCode: CONST.JSON_CODE.OFFLINE}); return; } diff --git a/tests/unit/NetworkTest.js b/tests/unit/NetworkTest.js index 1e3967f1409b..defe9b1169af 100644 --- a/tests/unit/NetworkTest.js +++ b/tests/unit/NetworkTest.js @@ -274,16 +274,15 @@ test('Request will not run until credentials are read from Onyx', () => { }); }); -test('retry network request if connection is lost while request is running', () => { +test('Non-retryable request will not be retried if connection is lost in flight', () => { // Given a xhr mock that will fail as if network connection dropped const xhr = jest.spyOn(HttpUtils, 'xhr') .mockImplementationOnce(() => { Onyx.merge(ONYXKEYS.NETWORK, {isOffline: true}); return Promise.reject(new Error(CONST.ERROR.FAILED_TO_FETCH)); - }) - .mockResolvedValue({jsonCode: CONST.JSON_CODE.SUCCESS, fromRetriedResult: true}); + }); - // Given a regular "retryable" request (that is bound to fail) + // Given a non-retryable request (that is bound to fail) const promise = Network.post('Get'); return waitForPromisesToResolve() @@ -298,15 +297,44 @@ test('retry network request if connection is lost while request is running', () return waitForPromisesToResolve(); }) .then(() => { - // Then the request should be attempted again - expect(xhr).toHaveBeenCalledTimes(2); + // Then the request should only have been attempted once and we should get an unable to retry + expect(xhr).toHaveBeenCalledTimes(1); + + // And the promise should be resolved with the special offline jsonCode + return expect(promise).resolves.toEqual({jsonCode: CONST.JSON_CODE.UNABLE_TO_RETRY}); + }); +}); + +test('Non-retryable request will not be retried if we are offline', () => { + // Given a xhr mock that will fail as if network connection dropped + const xhr = jest.spyOn(HttpUtils, 'xhr'); + let promise; + return Onyx.merge(ONYXKEYS.NETWORK, {isOffline: true}) + .then(() => { + // Given a regular non retryable request + promise = Network.post('Get'); + return waitForPromisesToResolve(); + }) + .then(() => { + // When network connection is recovered + Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false}); + return waitForPromisesToResolve(); + }) + .then(() => { + // Advance the network request queue by 1 second so that it can realize it's back online + jest.advanceTimersByTime(CONST.NETWORK.PROCESS_REQUEST_DELAY_MS); + return waitForPromisesToResolve(); + }) + .then(() => { + // Then the request should not have been attempted at all and we should get an offline jsonCode + expect(xhr).toHaveBeenCalledTimes(0); - // And the promise should be resolved with the 2nd call that succeeded - return expect(promise).resolves.toEqual({jsonCode: CONST.JSON_CODE.SUCCESS, fromRetriedResult: true}); + // And the promise should be resolved with the special offline jsonCode + return expect(promise).resolves.toEqual({jsonCode: CONST.JSON_CODE.OFFLINE}); }); }); -test('requests should be persisted while offline', () => { +test('Retryable requests should be persisted while offline', () => { // We don't expect calls `xhr` so we make the test fail if such call is made const xhr = jest.spyOn(HttpUtils, 'xhr').mockRejectedValue(new Error('Unexpected xhr call')); @@ -328,15 +356,22 @@ test('requests should be persisted while offline', () => { expect.objectContaining({command: 'mock command', data: expect.objectContaining({param1: 'value1'})}), expect.objectContaining({command: 'mock command', data: expect.objectContaining({param3: 'value3'})}), ]); + + PersistedRequests.clear(); + expect(PersistedRequests.getAll()).toEqual([]); }); }); -test('requests should resume when we are online', () => { +test('Retryable requests should resume when we are online', () => { // We're setting up a basic case where all requests succeed when we resume connectivity const xhr = jest.spyOn(HttpUtils, 'xhr').mockResolvedValue({jsonCode: CONST.JSON_CODE.SUCCESS}); // Given we have some requests made while we're offline - return Onyx.set(ONYXKEYS.NETWORK, {isOffline: true}) + return Onyx.multiSet({ + [ONYXKEYS.NETWORK]: {isOffline: true}, + [ONYXKEYS.CREDENTIALS]: {autoGeneratedLogin: 'test', autoGeneratedPassword: 'passwd'}, + [ONYXKEYS.SESSION]: {authToken: 'testToken'}, + }) .then(() => { // When network calls with `persist` are made Network.post('mock command', {param1: 'value1', persist: true}); @@ -352,6 +387,9 @@ test('requests should resume when we are online', () => { .then(() => Onyx.set(ONYXKEYS.NETWORK, {isOffline: false})) .then(waitForPromisesToResolve) .then(() => { + expect(NetworkStore.isOffline()).toBe(false); + expect(SequentialQueue.isRunning()).toBe(false); + // Then `xhr` should be called with expected data, and the persisted queue should be empty expect(xhr).toHaveBeenCalledTimes(2); expect(xhr.mock.calls).toEqual([ @@ -466,18 +504,19 @@ test('test bad response will log alert', () => { }); }); -test('test Failed to fetch error for requests not flagged with shouldRetry will resolve with an offline jsonCode', () => { - // Setup xhr handler that rejects once with a 502 Bad Gateway +test('test Failed to fetch error for non-retryable requests resolve with unable to retry jsonCode', () => { + // Setup xhr handler that rejects once with a Failed to Fetch global.fetch = jest.fn().mockRejectedValue(new Error(CONST.ERROR.FAILED_TO_FETCH)); - const onResolved = jest.fn(); // Given we have a request made while online return Onyx.set(ONYXKEYS.NETWORK, {isOffline: false}) .then(() => { + expect(NetworkStore.isOffline()).toBe(false); + // When network calls with are made Network.post('mock command', {param1: 'value1'}) - .resolve(onResolved); + .then(onResolved); return waitForPromisesToResolve(); }) .then(() => { @@ -526,18 +565,18 @@ test('several actions made while offline will get added in the order they are cr // Given offline state where all requests will eventualy succeed without issue const xhr = jest.spyOn(HttpUtils, 'xhr') .mockResolvedValue({jsonCode: CONST.JSON_CODE.SUCCESS}); - + let nonPersistableRequest; return Onyx.multiSet({ [ONYXKEYS.SESSION]: {authToken: 'anyToken'}, [ONYXKEYS.NETWORK]: {isOffline: true}, [ONYXKEYS.CREDENTIALS]: {autoGeneratedLogin: 'test_user', autoGeneratedPassword: 'psswd'}, }) .then(() => { - // When we queue 6 persistable commands + // When we queue 6 persistable commands and one not persistable Network.post('MockCommand', {content: 'value1', persist: true}); Network.post('MockCommand', {content: 'value2', persist: true}); Network.post('MockCommand', {content: 'value3', persist: true}); - Network.post('MockCommand', {content: 'not-persisted'}); + nonPersistableRequest = Network.post('MockCommand', {content: 'not-persisted'}); Network.post('MockCommand', {content: 'value4', persist: true}); Network.post('MockCommand', {content: 'value5', persist: true}); Network.post('MockCommand', {content: 'value6', persist: true}); @@ -557,12 +596,13 @@ test('several actions made while offline will get added in the order they are cr expect(xhr.mock.calls[4][1].content).toBe('value5'); expect(xhr.mock.calls[5][1].content).toBe('value6'); - // Move main queue forward so it processes the "read" request + // Move main queue forward jest.advanceTimersByTime(CONST.NETWORK.PROCESS_REQUEST_DELAY_MS); return waitForPromisesToResolve(); }) .then(() => { - expect(xhr.mock.calls[6][1].content).toBe('not-persisted'); + // We should not expect the request that could not be retried to resolve + expect(nonPersistableRequest).resolves.toEqual({jsonCode: CONST.JSON_CODE.OFFLINE}); }); }); @@ -574,7 +614,8 @@ test('several actions made while offline will get added in the order they are cr return Onyx.multiSet({ [ONYXKEYS.NETWORK]: {isOffline: true}, - [ONYXKEYS.CREDENTIALS]: {autoGeneratedLogin: 'caca', autoGeneratedPassword: 'caca'}, + [ONYXKEYS.SESSION]: {authToken: 'test'}, + [ONYXKEYS.CREDENTIALS]: {autoGeneratedLogin: 'test', autoGeneratedPassword: 'passwd'}, }) .then(() => { // When we queue 6 persistable commands From 3e56fd9a77e9c193803ca1aac9e84dc48f2f2484 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Wed, 4 May 2022 12:10:49 -1000 Subject: [PATCH 050/287] remove caca --- src/libs/Network/MainQueue.js | 2 +- tests/unit/NetworkTest.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/Network/MainQueue.js b/src/libs/Network/MainQueue.js index 9741d284f6fe..b90592ae7b05 100644 --- a/src/libs/Network/MainQueue.js +++ b/src/libs/Network/MainQueue.js @@ -54,7 +54,7 @@ function process() { } // Some requests should be retried and will end up here if the following conditions are met: - // - we are in the process of authenticating and the request is retryable (most are) + // - we are in the process of authenticating and must wait until we are no longer authenticating // - the request does not have forceNetworkRequest === true (this will trigger it to process immediately) const requestsToProcessOnNextRun = []; diff --git a/tests/unit/NetworkTest.js b/tests/unit/NetworkTest.js index defe9b1169af..b1c107cccb4c 100644 --- a/tests/unit/NetworkTest.js +++ b/tests/unit/NetworkTest.js @@ -535,7 +535,7 @@ test('persisted request can trigger reauthentication for anything retryable', () .mockResolvedValueOnce({jsonCode: CONST.JSON_CODE.SUCCESS}); // Original command return 200 // Given we have a request made while we're offline and we have credentials available to reauthenticate - Onyx.merge(ONYXKEYS.CREDENTIALS, {autoGeneratedLogin: 'caca', autoGeneratedPassword: 'caca'}); + Onyx.merge(ONYXKEYS.CREDENTIALS, {autoGeneratedLogin: 'test', autoGeneratedPassword: 'passwd'}); return waitForPromisesToResolve() .then(() => Onyx.set(ONYXKEYS.NETWORK, {isOffline: true})) .then(() => { From e6808e5a52ce0fd974f2eadbe7a1e1655f6ef494 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Wed, 4 May 2022 12:20:37 -1000 Subject: [PATCH 051/287] Fix test --- tests/unit/NetworkTest.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/NetworkTest.js b/tests/unit/NetworkTest.js index b1c107cccb4c..c60f3354ec25 100644 --- a/tests/unit/NetworkTest.js +++ b/tests/unit/NetworkTest.js @@ -358,6 +358,9 @@ test('Retryable requests should be persisted while offline', () => { ]); PersistedRequests.clear(); + return waitForPromisesToResolve(); + }) + .then(() => { expect(PersistedRequests.getAll()).toEqual([]); }); }); From 64df01859dfdbe01d76f4cf961c2f0409df5ebda Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Wed, 4 May 2022 12:35:53 -1000 Subject: [PATCH 052/287] Do not catch personal details error --- src/libs/actions/PersonalDetails.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/PersonalDetails.js b/src/libs/actions/PersonalDetails.js index 01edb4c41bf6..26acf5123004 100644 --- a/src/libs/actions/PersonalDetails.js +++ b/src/libs/actions/PersonalDetails.js @@ -289,9 +289,9 @@ function setPersonalDetails(details, shouldGrowl) { Growl.error(Localize.translateLocal('personalDetails.error.firstNameLength'), 3000); } else if (response.jsonCode === 401) { Growl.error(Localize.translateLocal('personalDetails.error.lastNameLength'), 3000); + } else { + console.debug('Error while setting personal details', response); } - }).catch((error) => { - console.debug('Error while setting personal details', error); }); } From 9aa22bf5e4c2f671bdd999ad677a9b79f61de820 Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Thu, 5 May 2022 00:49:34 +0200 Subject: [PATCH 053/287] change getErrors to getErrorText on incorporationType and selectedBank --- src/components/AddPlaidBankAccount.js | 2 +- src/pages/ReimbursementAccount/CompanyStep.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AddPlaidBankAccount.js b/src/components/AddPlaidBankAccount.js index 9e2b2c373472..78d4dd3e0855 100644 --- a/src/components/AddPlaidBankAccount.js +++ b/src/components/AddPlaidBankAccount.js @@ -253,7 +253,7 @@ class AddPlaidBankAccount extends React.Component { label: this.props.translate('bankAccount.chooseAnAccount'), } : {}} value={this.state.selectedIndex} - errorText={this.getErrors().selectedBank} + errorText={this.getErrorText('selectedBank')} /> {!_.isUndefined(this.state.selectedIndex) && this.props.isPasswordRequired && ( diff --git a/src/pages/ReimbursementAccount/CompanyStep.js b/src/pages/ReimbursementAccount/CompanyStep.js index b1a759fc1231..3cfe5ae041c8 100644 --- a/src/pages/ReimbursementAccount/CompanyStep.js +++ b/src/pages/ReimbursementAccount/CompanyStep.js @@ -270,7 +270,7 @@ class CompanyStep extends React.Component { onInputChange={value => this.clearErrorAndSetValue('incorporationType', value)} value={this.state.incorporationType} placeholder={{value: '', label: '-'}} - errorText={this.getErrors().incorporationType} + errorText={this.getErrorText('incorporationType')} /> From bb8a612aa504e932c9ee056c873e6158d1520d60 Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Thu, 5 May 2022 10:23:17 +0800 Subject: [PATCH 054/287] function to get shouldAddTopSafeAreaPadding by modal type --- .../index.android.js | 15 +++++++++++++++ .../getShouldAddTopSafeAreaPadding/index.js | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/libs/getShouldAddTopSafeAreaPadding/index.android.js create mode 100644 src/libs/getShouldAddTopSafeAreaPadding/index.js diff --git a/src/libs/getShouldAddTopSafeAreaPadding/index.android.js b/src/libs/getShouldAddTopSafeAreaPadding/index.android.js new file mode 100644 index 000000000000..044a4181f962 --- /dev/null +++ b/src/libs/getShouldAddTopSafeAreaPadding/index.android.js @@ -0,0 +1,15 @@ +import CONST from '../../CONST'; + +/** + * Should modal add top safe area padding by modal type for Android + * @param {String} modalType + * @returns {Boolean} + */ +export default (modalType = '') => { + switch (modalType) { + case CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED: + return true; + default: + return false; + } +}; diff --git a/src/libs/getShouldAddTopSafeAreaPadding/index.js b/src/libs/getShouldAddTopSafeAreaPadding/index.js new file mode 100644 index 000000000000..d0b3d0031b38 --- /dev/null +++ b/src/libs/getShouldAddTopSafeAreaPadding/index.js @@ -0,0 +1,17 @@ +import CONST from '../../CONST'; + +/** + * Should modal add top safe area padding by modal type + * @param {String} modalType + * @returns {Boolean} + */ +export default (modalType = '') => { + switch (modalType) { + case CONST.MODAL.MODAL_TYPE.CENTERED: + case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: + case CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED: + return true; + default: + return false; + } +}; From c9952eeedcc3b4bebd3cf8e591195ec99e671e59 Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Thu, 5 May 2022 10:23:43 +0800 Subject: [PATCH 055/287] revert back the getModalStyles and use getShouldAddTopSafeAreaPadding function --- .../{getModalStyles => }/getModalStyles.js | 16 ++++++++++------ src/styles/getModalStyles/index.android.js | 8 -------- src/styles/getModalStyles/index.js | 10 ---------- 3 files changed, 10 insertions(+), 24 deletions(-) rename src/styles/{getModalStyles => }/getModalStyles.js (92%) delete mode 100644 src/styles/getModalStyles/index.android.js delete mode 100644 src/styles/getModalStyles/index.js diff --git a/src/styles/getModalStyles/getModalStyles.js b/src/styles/getModalStyles.js similarity index 92% rename from src/styles/getModalStyles/getModalStyles.js rename to src/styles/getModalStyles.js index 805fedf17140..f9df31730a65 100644 --- a/src/styles/getModalStyles/getModalStyles.js +++ b/src/styles/getModalStyles.js @@ -1,9 +1,10 @@ -import CONST from '../../CONST'; -import colors from '../colors'; -import variables from '../variables'; -import themeColors from '../themes/default'; +import CONST from '../CONST'; +import colors from './colors'; +import variables from './variables'; +import themeColors from './themes/default'; +import getShouldAddTopSafeAreaPadding from '../libs/getShouldAddTopSafeAreaPadding'; -export default ({shouldModalAddTopSafeAreaPadding = {}}) => (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => { +export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => { const {isSmallScreenWidth, windowWidth} = windowDimensions; let modalStyle = { @@ -16,7 +17,7 @@ export default ({shouldModalAddTopSafeAreaPadding = {}}) => (type, windowDimensi let animationOut; let hideBackdrop = false; let shouldAddBottomSafeAreaPadding = false; - const shouldAddTopSafeAreaPadding = shouldModalAddTopSafeAreaPadding[type] || false; + let shouldAddTopSafeAreaPadding = false; switch (type) { case CONST.MODAL.MODAL_TYPE.CONFIRM: @@ -83,6 +84,7 @@ export default ({shouldModalAddTopSafeAreaPadding = {}}) => (type, windowDimensi swipeDirection = ['down', 'right']; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; + shouldAddTopSafeAreaPadding = getShouldAddTopSafeAreaPadding(type); break; case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: // A centered modal that cannot be dismissed with a swipe. @@ -113,6 +115,7 @@ export default ({shouldModalAddTopSafeAreaPadding = {}}) => (type, windowDimensi swipeDirection = undefined; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; + shouldAddTopSafeAreaPadding = getShouldAddTopSafeAreaPadding(type); break; case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED: modalStyle = { @@ -194,6 +197,7 @@ export default ({shouldModalAddTopSafeAreaPadding = {}}) => (type, windowDimensi }; swipeDirection = undefined; shouldAddBottomSafeAreaPadding = true; + shouldAddTopSafeAreaPadding = getShouldAddTopSafeAreaPadding(type); break; default: modalStyle = {}; diff --git a/src/styles/getModalStyles/index.android.js b/src/styles/getModalStyles/index.android.js deleted file mode 100644 index 11347b09babc..000000000000 --- a/src/styles/getModalStyles/index.android.js +++ /dev/null @@ -1,8 +0,0 @@ -import CONST from '../../CONST'; -import getModalStyles from './getModalStyles'; - -export default getModalStyles({ - shouldModalAddTopSafeAreaPadding: { - [CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED]: true, - }, -}); diff --git a/src/styles/getModalStyles/index.js b/src/styles/getModalStyles/index.js deleted file mode 100644 index 446ce34e7f11..000000000000 --- a/src/styles/getModalStyles/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import CONST from '../../CONST'; -import getModalStyles from './getModalStyles'; - -export default getModalStyles({ - shouldModalAddTopSafeAreaPadding: { - [CONST.MODAL.MODAL_TYPE.CENTERED]: true, - [CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE]: true, - [CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED]: true, - }, -}); From 3983feab80706682aff5fc66f0d50edce7549acc Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Thu, 5 May 2022 08:24:29 +0500 Subject: [PATCH 056/287] Add min height requirement to show graphics --- src/pages/signin/SignInPageLayout/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index 35df9dfa9254..7e93f417a3a0 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -64,7 +64,7 @@ const SignInPageLayout = (props) => { if (props.isMediumScreenWidth) { return ( - {graphicLayout} + {props.windowHeight >= 854 && graphicLayout} {content} From d87227e87bf7830cc749f4ea0c8c11579047dc0d Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Thu, 5 May 2022 10:49:23 +0530 Subject: [PATCH 057/287] changed prop type for fallbackIcon and removed a unnecessary fallbackIcon assignment --- src/components/Avatar.js | 4 ++-- src/components/AvatarWithImagePicker.js | 4 ++-- src/components/menuItemPropTypes.js | 4 ++-- src/pages/workspace/WorkspaceInitialPage.js | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index e961080bdd49..bc8bcc9b9e18 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -25,8 +25,8 @@ const propTypes = { /** The fill color for the icon. Can be hex, rgb, rgba, or valid react-native named color such as 'red' or 'blue' */ fill: PropTypes.string, - /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ - fallbackIcon: PropTypes.string, + /** Function for using fallback avatar */ + fallbackIcon: PropTypes.func, }; const defaultProps = { diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 30bd5bf95dcd..56449d79afcc 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -53,8 +53,8 @@ const propTypes = { /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), - /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ - fallbackIcon: PropTypes.string, + /** Function for using fallback avatar */ + fallbackIcon: PropTypes.func, ...withLocalizePropTypes, }; diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index cb1edee344b2..4f3efd59c4c1 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -64,8 +64,8 @@ const propTypes = { /** Whether the menu item should be interactive at all */ interactive: PropTypes.bool, - /** Flag to check if avatar is from workspace, so that we can use fallback avatar accordingly */ - fallbackIcon: PropTypes.string, + /** Function for using fallback avatar */ + fallbackIcon: PropTypes.func, }; export default propTypes; diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index bda5f7c97a2c..9cb442edb586 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -202,7 +202,6 @@ class WorkspaceInitialPage extends React.Component { iconRight={item.iconRight} onPress={() => item.action()} shouldShowRightIcon - fallbackIcon={Expensicons.FallbackWorkspaceAvatar} /> ))} From 2d62637c8bedc6c0082c6658b18ca9a2a27112c6 Mon Sep 17 00:00:00 2001 From: LucioChavezFuentes Date: Thu, 5 May 2022 22:46:47 +0200 Subject: [PATCH 058/287] add noBankAccountSelected error --- src/components/AddPlaidBankAccount.js | 1 + src/languages/en.js | 1 + src/languages/es.js | 1 + 3 files changed, 3 insertions(+) diff --git a/src/components/AddPlaidBankAccount.js b/src/components/AddPlaidBankAccount.js index 78d4dd3e0855..73fb51e1a929 100644 --- a/src/components/AddPlaidBankAccount.js +++ b/src/components/AddPlaidBankAccount.js @@ -118,6 +118,7 @@ class AddPlaidBankAccount extends React.Component { this.clearError = inputKey => ReimbursementAccountUtils.clearError(this.props, inputKey); this.getErrorText = inputKey => ReimbursementAccountUtils.getErrorText(this.props, { password: 'passwordForm.error.incorrectPassword', + selectedBank: 'bankAccount.error.noBankAccountSelected', }, inputKey); } diff --git a/src/languages/en.js b/src/languages/en.js index 31a9c476856d..2eb93c0cfb20 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -532,6 +532,7 @@ export default { buttonConfirm: 'Got it', error: { noBankAccountAvailable: 'Sorry, no bank account is available', + noBankAccountSelected: 'Please choose an account', taxID: 'Please enter a valid Tax ID Number', website: 'Please enter a valid website', zipCode: 'Please enter a valid zip code', diff --git a/src/languages/es.js b/src/languages/es.js index 646631b14dc3..acee915fe848 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -532,6 +532,7 @@ export default { buttonConfirm: 'OK', error: { noBankAccountAvailable: 'Lo sentimos, no hay ninguna cuenta bancaria disponible', + noBankAccountSelected: 'Por favor, elige una cuenta bancaria', taxID: 'Ingresa un número de identificación fiscal válido', website: 'Ingresa un sitio web válido', zipCode: 'Ingresa un código postal válido', From 7b8b7d97631682c3a929992cb16fe4cbda5756de Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Fri, 6 May 2022 15:47:29 +0300 Subject: [PATCH 059/287] Make emojis larger when multiple are sent at the same time --- src/CONST.js | 2 ++ src/libs/EmojiUtils.js | 25 +++++++++++++++++++ .../home/report/ReportActionItemFragment.js | 2 +- src/styles/styles.js | 2 +- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 894cf295b27c..59b51b2d0b83 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -387,6 +387,8 @@ const CONST = { EMOJI_FREQUENT_ROW_COUNT: 3, + EMOJI_INVISIBLE_CODEPOINT: 'fe0f', + LOGIN_TYPE: { PHONE: 'phone', EMAIL: 'email', diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 61684d37d0f9..044fedbab462 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -70,6 +70,30 @@ function isSingleEmoji(message) { return matchedUnicode === currentMessageUnicode; } +/** + * Validates that this string contains only emojis + * + * @param {String} message + * @returns {Boolean} + */ +function containsOnlyEmojis(message) { + const match = message.match(CONST.REGEX.EMOJIS); + if (match) { + const codes = []; + + _.map(match, emoji => _.map(getEmojiUnicode(emoji).split(' '), (code) => { + if (code !== CONST.EMOJI_INVISIBLE_CODEPOINT) { + codes.push(code); + } + return code; + })); + + const messageCodes = _.filter(_.map([...message], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + return codes.length === messageCodes.length; + } + return false; +} + /** * Get the header indices based on the max emojis per row * @param {Object[]} emojis @@ -176,4 +200,5 @@ export { getDynamicHeaderIndices, mergeEmojisWithFrequentlyUsedEmojis, addToFrequentlyUsedEmojis, + containsOnlyEmojis, }; diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 194a865636f7..3d2ec24975dd 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -106,7 +106,7 @@ const ReportActionItemFragment = (props) => { ) : ( {Str.htmlDecode(props.fragment.text)} {props.fragment.isEdited && ( diff --git a/src/styles/styles.js b/src/styles/styles.js index d022567aa233..c11587ea9501 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1042,7 +1042,7 @@ const styles = { textDecorationLine: 'none', }, - singleEmojiText: { + multipleEmojisText: { fontSize: variables.fontSizeSingleEmoji, lineHeight: variables.fontSizeSingleEmojiHeight, }, From 10fc82e10c1f2b7bc57a8aa5f96807a170219262 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Mon, 9 May 2022 20:29:20 +0300 Subject: [PATCH 060/287] Update comment --- src/libs/EmojiUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 044fedbab462..ecb71de9362b 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -71,7 +71,7 @@ function isSingleEmoji(message) { } /** - * Validates that this string contains only emojis + * Validates that this message contains only emojis * * @param {String} message * @returns {Boolean} From 316d03082bbc571e60c13c671be85f3b12666301 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Mon, 9 May 2022 20:38:03 +0300 Subject: [PATCH 061/287] Memoize getEmojiUnicode function --- src/libs/EmojiUtils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index ecb71de9362b..e72096992223 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -9,7 +9,7 @@ import * as User from './actions/User'; * @param {String} input * @returns {String} */ -function getEmojiUnicode(input) { +const getEmojiUnicode = _.memoize((input) => { if (input.length === 0) { return ''; } @@ -40,7 +40,7 @@ function getEmojiUnicode(input) { } } return _.map(pairs, val => parseInt(val, 10).toString(16)).join(' '); -} +}); /** * Function to remove Skin Tone and utf16 surrogates from Emoji From f89d249f5e7118027ecde47fb9a9728c462ab81d Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Mon, 9 May 2022 21:17:07 +0300 Subject: [PATCH 062/287] Return early in containsOnlyEmojis function --- src/libs/EmojiUtils.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index e72096992223..4e9d654e0ee0 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -78,20 +78,21 @@ function isSingleEmoji(message) { */ function containsOnlyEmojis(message) { const match = message.match(CONST.REGEX.EMOJIS); - if (match) { - const codes = []; - _.map(match, emoji => _.map(getEmojiUnicode(emoji).split(' '), (code) => { - if (code !== CONST.EMOJI_INVISIBLE_CODEPOINT) { - codes.push(code); - } - return code; - })); - - const messageCodes = _.filter(_.map([...message], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); - return codes.length === messageCodes.length; + if (!match) { + return false; } - return false; + + const codes = []; + _.map(match, emoji => _.map(getEmojiUnicode(emoji).split(' '), (code) => { + if (code !== CONST.EMOJI_INVISIBLE_CODEPOINT) { + codes.push(code); + } + return code; + })); + + const messageCodes = _.filter(_.map([...message], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + return codes.length === messageCodes.length; } /** From d3ac4623eaf063114d6ab2c15038d72fa4d5b3af Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 11:25:58 +0300 Subject: [PATCH 063/287] Update styles name --- src/pages/home/report/ReportActionItemFragment.js | 2 +- src/styles/styles.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 3d2ec24975dd..76ab07500782 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -106,7 +106,7 @@ const ReportActionItemFragment = (props) => { ) : ( {Str.htmlDecode(props.fragment.text)} {props.fragment.isEdited && ( diff --git a/src/styles/styles.js b/src/styles/styles.js index c11587ea9501..11c67fd6819c 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1042,7 +1042,7 @@ const styles = { textDecorationLine: 'none', }, - multipleEmojisText: { + onlyEmojisText: { fontSize: variables.fontSizeSingleEmoji, lineHeight: variables.fontSizeSingleEmojiHeight, }, From 3f491f0de8fca1132f19015719d3124671de520d Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Tue, 10 May 2022 14:23:32 +0500 Subject: [PATCH 064/287] Move minHeigth value to variables file --- src/pages/signin/SignInPageLayout/index.js | 3 ++- src/styles/variables.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index 7e93f417a3a0..c10a1e7b39e0 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -8,6 +8,7 @@ import SVGImage from '../../../components/SVGImage'; import styles from '../../../styles/styles'; import * as StyleUtils from '../../../styles/StyleUtils'; import * as Link from '../../../libs/actions/Link'; +import variables from '../../../styles/variables'; const propTypes = { /** The children to show inside the layout */ @@ -64,7 +65,7 @@ const SignInPageLayout = (props) => { if (props.isMediumScreenWidth) { return ( - {props.windowHeight >= 854 && graphicLayout} + {props.windowHeight >= variables.minHeigthToShowGraphics && graphicLayout} {content} diff --git a/src/styles/variables.js b/src/styles/variables.js index 5ffd6bf29131..4894e84ee3ec 100644 --- a/src/styles/variables.js +++ b/src/styles/variables.js @@ -44,4 +44,5 @@ export default { tooltipzIndex: 10050, gutterWidth: 16, popoverMenuShadow: '0px 4px 12px 0px rgba(0, 0, 0, 0.06)', + minHeigthToShowGraphics: 854 }; From 44d6972fc18adfd6ea91d6d7ce5da4dd8c39c834 Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Tue, 10 May 2022 20:51:49 +0500 Subject: [PATCH 065/287] eslint changes --- src/pages/signin/SignInPageLayout/index.js | 2 +- src/styles/variables.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index c10a1e7b39e0..cfd265451909 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -8,7 +8,7 @@ import SVGImage from '../../../components/SVGImage'; import styles from '../../../styles/styles'; import * as StyleUtils from '../../../styles/StyleUtils'; import * as Link from '../../../libs/actions/Link'; -import variables from '../../../styles/variables'; +import variables from '../../../styles/variables'; const propTypes = { /** The children to show inside the layout */ diff --git a/src/styles/variables.js b/src/styles/variables.js index 4894e84ee3ec..00c00f2e6549 100644 --- a/src/styles/variables.js +++ b/src/styles/variables.js @@ -44,5 +44,5 @@ export default { tooltipzIndex: 10050, gutterWidth: 16, popoverMenuShadow: '0px 4px 12px 0px rgba(0, 0, 0, 0.06)', - minHeigthToShowGraphics: 854 + minHeightToShowGraphics: 854, }; From 306722acff4bd2f6c948dabd44883ffa6ab4fe6c Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Tue, 10 May 2022 20:56:46 +0500 Subject: [PATCH 066/287] Add height check with screen check --- src/pages/signin/SignInPageLayout/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index cfd265451909..995b0c807548 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -62,10 +62,10 @@ const SignInPageLayout = (props) => { return content; } - if (props.isMediumScreenWidth) { + if (props.isMediumScreenWidth && props.windowHeight >= variables.minHeigthToShowGraphics) { return ( - {props.windowHeight >= variables.minHeigthToShowGraphics && graphicLayout} + {graphicLayout} {content} From e9945b39acb4aff6e0b3e205e6525d8fe22b892f Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 20:17:08 +0300 Subject: [PATCH 067/287] Rename onlyEmojis style variables --- src/styles/styles.js | 4 ++-- src/styles/variables.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/styles/styles.js b/src/styles/styles.js index 11c67fd6819c..9a8b59f10bd1 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1043,8 +1043,8 @@ const styles = { }, onlyEmojisText: { - fontSize: variables.fontSizeSingleEmoji, - lineHeight: variables.fontSizeSingleEmojiHeight, + fontSize: variables.fontSizeOnlyEmojis, + lineHeight: variables.fontSizeOnlyEmojisHeight, }, createMenuPositionSidebar: { diff --git a/src/styles/variables.js b/src/styles/variables.js index 4302947ac879..506755712154 100644 --- a/src/styles/variables.js +++ b/src/styles/variables.js @@ -14,8 +14,8 @@ export default { avatarSizeSmall: 28, avatarSizeSubscript: 20, avatarSizeSmallSubscript: 14, - fontSizeSingleEmoji: 30, - fontSizeSingleEmojiHeight: 35, + fontSizeOnlyEmojis: 30, + fontSizeOnlyEmojisHeight: 35, fontSizeSmall: 11, fontSizeExtraSmall: 9, fontSizeLabel: 13, From 4a782667992828eca6b18238b002817b26e8f183 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 20:17:56 +0300 Subject: [PATCH 068/287] Ignore spaces in containsOnlyEmojis function --- src/libs/EmojiUtils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 4e9d654e0ee0..2cbecbff5cd6 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -77,7 +77,7 @@ function isSingleEmoji(message) { * @returns {Boolean} */ function containsOnlyEmojis(message) { - const match = message.match(CONST.REGEX.EMOJIS); + const match = message.replace(/ /g, '').match(CONST.REGEX.EMOJIS); if (!match) { return false; @@ -91,7 +91,7 @@ function containsOnlyEmojis(message) { return code; })); - const messageCodes = _.filter(_.map([...message], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + const messageCodes = _.filter(_.map([...message.replace(/ /g, '')], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); return codes.length === messageCodes.length; } From d7362250a3c86a71192c8a2016a5e4920225d518 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 23:33:57 +0300 Subject: [PATCH 069/287] Add support for multiple emojis with line breaks between them --- src/libs/EmojiUtils.js | 5 +++-- src/pages/home/report/ReportActionItemFragment.js | 10 +++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 2cbecbff5cd6..b928f33fedbe 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -77,7 +77,7 @@ function isSingleEmoji(message) { * @returns {Boolean} */ function containsOnlyEmojis(message) { - const match = message.replace(/ /g, '').match(CONST.REGEX.EMOJIS); + const match = message.replace(/ /g, '').replaceAll('\n', '').match(CONST.REGEX.EMOJIS); if (!match) { return false; @@ -91,7 +91,8 @@ function containsOnlyEmojis(message) { return code; })); - const messageCodes = _.filter(_.map([...message.replace(/ /g, '')], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + const messageCodes = _.filter(_.map([...message.replace(/ /g, '').replaceAll('\n', '')], + char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); return codes.length === messageCodes.length; } diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 76ab07500782..25a651929549 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -68,7 +68,7 @@ const defaultProps = { const ReportActionItemFragment = (props) => { switch (props.fragment.type) { - case 'COMMENT': + case 'COMMENT': { // If this is an attachment placeholder, return the placeholder component if (props.isAttachment && props.loading) { return ( @@ -97,6 +97,13 @@ const ReportActionItemFragment = (props) => { ); } + const differByLineBreaksOnly = props.fragment.html.replaceAll('
', ' ') === props.fragment.text; + if (differByLineBreaksOnly) { + const textWithLineBreaks = props.fragment.html.replaceAll('
', '\n'); + // eslint-disable-next-line no-param-reassign + props.fragment = {...props.fragment, text: textWithLineBreaks, html: textWithLineBreaks}; + } + // Only render HTML if we have html in the fragment return props.fragment.html !== props.fragment.text ? ( @@ -119,6 +126,7 @@ const ReportActionItemFragment = (props) => { )}
); + } case 'TEXT': return ( From 5b29f4f13435b40b21f872f1140ded0f99b8bb4a Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 23:41:46 +0300 Subject: [PATCH 070/287] Add comment about spread operator in containsOnlyEmojis --- src/libs/EmojiUtils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index b928f33fedbe..edbdf14c33fb 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -91,6 +91,8 @@ function containsOnlyEmojis(message) { return code; })); + // Emojis are stored as multiple characters, so we're using spread operator + // to iterate over the actual emojis, not just characters that compose them const messageCodes = _.filter(_.map([...message.replace(/ /g, '').replaceAll('\n', '')], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); return codes.length === messageCodes.length; From e493a51fdc3a1292247b9d933145cf1bc2ba5fac Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Wed, 11 May 2022 10:44:37 +0300 Subject: [PATCH 071/287] Add comment in ReportActionItemFragment --- src/pages/home/report/ReportActionItemFragment.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 25a651929549..8cfcfe9aac73 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -97,6 +97,9 @@ const ReportActionItemFragment = (props) => { ); } + // If the only difference between fragment.text and fragment.html is
tags + // we replace them with line breaks and render it as text, not as html. + // This is done to render emojis with line breaks between them as text. const differByLineBreaksOnly = props.fragment.html.replaceAll('
', ' ') === props.fragment.text; if (differByLineBreaksOnly) { const textWithLineBreaks = props.fragment.html.replaceAll('
', '\n'); From 29b0ad8734ffd0d3c084e9d83ffad94b041bf1e2 Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Wed, 11 May 2022 17:16:46 +0700 Subject: [PATCH 072/287] getModalStyles to library --- src/components/Modal/BaseModal.js | 2 +- .../getModalStyles}/getModalStyles.js | 15 +++++++-------- src/libs/getModalStyles/index.android.js | 6 ++++++ src/libs/getModalStyles/index.js | 3 +++ .../index.android.js | 15 --------------- .../getShouldAddTopSafeAreaPadding/index.js | 17 ----------------- 6 files changed, 17 insertions(+), 41 deletions(-) rename src/{styles => libs/getModalStyles}/getModalStyles.js (94%) create mode 100644 src/libs/getModalStyles/index.android.js create mode 100644 src/libs/getModalStyles/index.js delete mode 100644 src/libs/getShouldAddTopSafeAreaPadding/index.android.js delete mode 100644 src/libs/getShouldAddTopSafeAreaPadding/index.js diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js index d6f0a7cbc424..27e5b81620a0 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.js @@ -7,8 +7,8 @@ import styles from '../../styles/styles'; import * as StyleUtils from '../../styles/StyleUtils'; import themeColors from '../../styles/themes/default'; import {propTypes as modalPropTypes, defaultProps as modalDefaultProps} from './modalPropTypes'; -import getModalStyles from '../../styles/getModalStyles'; import * as Modal from '../../libs/actions/Modal'; +import getModalStyles from '../../libs/getModalStyles'; const propTypes = { ...modalPropTypes, diff --git a/src/styles/getModalStyles.js b/src/libs/getModalStyles/getModalStyles.js similarity index 94% rename from src/styles/getModalStyles.js rename to src/libs/getModalStyles/getModalStyles.js index f9df31730a65..ed926e87a4f2 100644 --- a/src/styles/getModalStyles.js +++ b/src/libs/getModalStyles/getModalStyles.js @@ -1,8 +1,7 @@ -import CONST from '../CONST'; -import colors from './colors'; -import variables from './variables'; -import themeColors from './themes/default'; -import getShouldAddTopSafeAreaPadding from '../libs/getShouldAddTopSafeAreaPadding'; +import CONST from '../../CONST'; +import colors from '../../styles/colors'; +import variables from '../../styles/variables'; +import themeColors from '../../styles/themes/default'; export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => { const {isSmallScreenWidth, windowWidth} = windowDimensions; @@ -84,7 +83,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty swipeDirection = ['down', 'right']; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - shouldAddTopSafeAreaPadding = getShouldAddTopSafeAreaPadding(type); + shouldAddTopSafeAreaPadding = true; break; case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: // A centered modal that cannot be dismissed with a swipe. @@ -115,7 +114,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty swipeDirection = undefined; animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - shouldAddTopSafeAreaPadding = getShouldAddTopSafeAreaPadding(type); + shouldAddTopSafeAreaPadding = true; break; case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED: modalStyle = { @@ -197,7 +196,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty }; swipeDirection = undefined; shouldAddBottomSafeAreaPadding = true; - shouldAddTopSafeAreaPadding = getShouldAddTopSafeAreaPadding(type); + shouldAddTopSafeAreaPadding = true; break; default: modalStyle = {}; diff --git a/src/libs/getModalStyles/index.android.js b/src/libs/getModalStyles/index.android.js new file mode 100644 index 000000000000..cadf74803f70 --- /dev/null +++ b/src/libs/getModalStyles/index.android.js @@ -0,0 +1,6 @@ +import getModalStyles from './getModalStyles'; + +export default (type, windowDimensions, popoverAnchorPosition, containerStyle) => ({ + ...getModalStyles(type, windowDimensions, popoverAnchorPosition, containerStyle), + shouldAddTopSafeAreaPadding: false, +}); diff --git a/src/libs/getModalStyles/index.js b/src/libs/getModalStyles/index.js new file mode 100644 index 000000000000..869dbf45afc0 --- /dev/null +++ b/src/libs/getModalStyles/index.js @@ -0,0 +1,3 @@ +import getModalStyles from './getModalStyles'; + +export default getModalStyles; diff --git a/src/libs/getShouldAddTopSafeAreaPadding/index.android.js b/src/libs/getShouldAddTopSafeAreaPadding/index.android.js deleted file mode 100644 index 044a4181f962..000000000000 --- a/src/libs/getShouldAddTopSafeAreaPadding/index.android.js +++ /dev/null @@ -1,15 +0,0 @@ -import CONST from '../../CONST'; - -/** - * Should modal add top safe area padding by modal type for Android - * @param {String} modalType - * @returns {Boolean} - */ -export default (modalType = '') => { - switch (modalType) { - case CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED: - return true; - default: - return false; - } -}; diff --git a/src/libs/getShouldAddTopSafeAreaPadding/index.js b/src/libs/getShouldAddTopSafeAreaPadding/index.js deleted file mode 100644 index d0b3d0031b38..000000000000 --- a/src/libs/getShouldAddTopSafeAreaPadding/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import CONST from '../../CONST'; - -/** - * Should modal add top safe area padding by modal type - * @param {String} modalType - * @returns {Boolean} - */ -export default (modalType = '') => { - switch (modalType) { - case CONST.MODAL.MODAL_TYPE.CENTERED: - case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: - case CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED: - return true; - default: - return false; - } -}; From 7933540ff0f350f41f6623f5fa91793d8230721d Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Wed, 11 May 2022 17:34:49 +0300 Subject: [PATCH 073/287] Fix linter error --- src/CONST.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CONST.js b/src/CONST.js index fcb1a245e30a..c0e26e78fca7 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -388,7 +388,7 @@ const CONST = { EMOJI_FREQUENT_ROW_COUNT: 3, EMOJI_INVISIBLE_CODEPOINT: 'fe0f', - + TOOLTIP_MAX_LINES: 3, LOGIN_TYPE: { From 17e1d3ff970e491f485708db0509520826e8603c Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Wed, 11 May 2022 22:06:47 +0700 Subject: [PATCH 074/287] add default value --- src/libs/getModalStyles/index.android.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/getModalStyles/index.android.js b/src/libs/getModalStyles/index.android.js index cadf74803f70..1929e49dabeb 100644 --- a/src/libs/getModalStyles/index.android.js +++ b/src/libs/getModalStyles/index.android.js @@ -1,6 +1,6 @@ import getModalStyles from './getModalStyles'; -export default (type, windowDimensions, popoverAnchorPosition, containerStyle) => ({ +export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => ({ ...getModalStyles(type, windowDimensions, popoverAnchorPosition, containerStyle), shouldAddTopSafeAreaPadding: false, }); From 232ec696c248509f31fcc12202fb1e1338a8f8a5 Mon Sep 17 00:00:00 2001 From: Paulo Vale Date: Wed, 11 May 2022 13:37:29 -0300 Subject: [PATCH 075/287] Reload WorkspacePageWithSections data when toggling network connection --- .../workspace/WorkspacePageWithSections.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/pages/workspace/WorkspacePageWithSections.js b/src/pages/workspace/WorkspacePageWithSections.js index f5fa19fc6700..6d84ed2484a8 100644 --- a/src/pages/workspace/WorkspacePageWithSections.js +++ b/src/pages/workspace/WorkspacePageWithSections.js @@ -17,8 +17,13 @@ import reimbursementAccountPropTypes from '../ReimbursementAccount/reimbursement import userPropTypes from '../settings/userPropTypes'; import KeyboardAvoidingView from '../../components/KeyboardAvoidingView'; import withFullPolicy from './withFullPolicy'; +import {withNetwork} from '../../components/OnyxProvider'; +import networkPropTypes from '../../components/networkPropTypes'; const propTypes = { + /** Information about the network from Onyx */ + network: networkPropTypes.isRequired, + /** The text to display in the header */ headerText: PropTypes.string.isRequired, @@ -65,6 +70,18 @@ const defaultProps = { class WorkspacePageWithSections extends React.Component { componentDidMount() { + this.fetchData(); + } + + componentDidUpdate(prevProps) { + if (!prevProps.network.isOffline || this.props.network.isOffline) { + return; + } + + this.fetchData(); + } + + fetchData() { const achState = lodashGet(this.props.reimbursementAccount, 'achData.state', ''); BankAccounts.fetchFreePlanVerifiedBankAccount('', achState); } @@ -118,4 +135,5 @@ export default compose( }, }), withFullPolicy, + withNetwork(), )(WorkspacePageWithSections); From 9c86b32dab4b12dc2f0a5d2ea5ad7646fb42498d Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Thu, 12 May 2022 20:50:27 +0300 Subject: [PATCH 076/287] Trim message only once --- src/libs/EmojiUtils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index edbdf14c33fb..208dd6b1cf4d 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -77,7 +77,8 @@ function isSingleEmoji(message) { * @returns {Boolean} */ function containsOnlyEmojis(message) { - const match = message.replace(/ /g, '').replaceAll('\n', '').match(CONST.REGEX.EMOJIS); + const trimmedMessage = message.replace(/ /g, '').replaceAll('\n', ''); + const match = trimmedMessage.match(CONST.REGEX.EMOJIS); if (!match) { return false; @@ -93,8 +94,7 @@ function containsOnlyEmojis(message) { // Emojis are stored as multiple characters, so we're using spread operator // to iterate over the actual emojis, not just characters that compose them - const messageCodes = _.filter(_.map([...message.replace(/ /g, '').replaceAll('\n', '')], - char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + const messageCodes = _.filter(_.map([...trimmedMessage], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); return codes.length === messageCodes.length; } From f590ea6c73b0c7baaa477a08259c2ba0552362e8 Mon Sep 17 00:00:00 2001 From: Tushu17 Date: Fri, 13 May 2022 02:07:00 +0530 Subject: [PATCH 077/287] make navigateToDetailsPage a util function --- src/libs/ReportUtils.js | 21 +++++++++++++++++++ src/pages/home/HeaderView.js | 15 +------------ .../home/report/ReportActionItemCreated.js | 18 +--------------- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 2cfdfa289711..f55c5788d22f 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -8,6 +8,8 @@ import * as Localize from './Localize'; import * as LocalePhoneNumber from './LocalePhoneNumber'; import * as Expensicons from '../components/Icon/Expensicons'; import md5 from './md5'; +import Navigation from './Navigation/Navigation'; +import ROUTES from '../ROUTES'; let sessionEmail; Onyx.connect({ @@ -481,6 +483,24 @@ function getReportName(report, personalDetailsForParticipants = {}, policies = { return _.map(displayNamesWithTooltips, ({displayName}) => displayName).join(', '); } +/** + * Navigate to the details page of a given report + * + * @param {Object} report + * @param {Array} participants + */ +function navigateToDetailsPage(report, participants) { + if (isChatRoom(report) || isPolicyExpenseChat(report)) { + Navigation.navigate(ROUTES.getReportDetailsRoute(report.reportID)); + return; + } + if (participants.length === 1) { + Navigation.navigate(ROUTES.getDetailsRoute(participants[0])); + return; + } + Navigation.navigate(ROUTES.getReportParticipantsRoute(report.reportID)); +} + export { getReportParticipantsTitle, isReportMessageAttachment, @@ -507,4 +527,5 @@ export { getRoomWelcomeMessage, getDisplayNamesWithTooltips, getReportName, + navigateToDetailsPage, }; diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js index a8f6209d1190..bd2ee2a02daf 100644 --- a/src/pages/home/HeaderView.js +++ b/src/pages/home/HeaderView.js @@ -14,8 +14,6 @@ import * as Report from '../../libs/actions/Report'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions'; import MultipleAvatars from '../../components/MultipleAvatars'; import SubscriptAvatar from '../../components/SubscriptAvatar'; -import Navigation from '../../libs/Navigation/Navigation'; -import ROUTES from '../../ROUTES'; import DisplayNames from '../../components/DisplayNames'; import * as OptionsListUtils from '../../libs/OptionsListUtils'; import participantPropTypes from '../../components/participantPropTypes'; @@ -28,9 +26,6 @@ import Text from '../../components/Text'; import Tooltip from '../../components/Tooltip'; const propTypes = { - /** The ID of the report */ - reportID: PropTypes.number.isRequired, - /** Toggles the navigationMenu open and closed */ onNavigationMenuButtonClicked: PropTypes.func.isRequired, @@ -113,15 +108,7 @@ const HeaderView = (props) => { ]} > { - if (isChatRoom || isPolicyExpenseChat) { - return Navigation.navigate(ROUTES.getReportDetailsRoute(props.reportID)); - } - if (participants.length === 1) { - return Navigation.navigate(ROUTES.getDetailsRoute(participants[0])); - } - Navigation.navigate(ROUTES.getReportParticipantsRoute(props.reportID)); - }} + onPress={() => ReportUtils.navigateToDetailsPage(props.report, participants)} style={[styles.flexRow, styles.alignItemsCenter, styles.flex1]} > {shouldShowSubscript ? ( diff --git a/src/pages/home/report/ReportActionItemCreated.js b/src/pages/home/report/ReportActionItemCreated.js index f4b125c3bfc8..a76af7d5ec6d 100644 --- a/src/pages/home/report/ReportActionItemCreated.js +++ b/src/pages/home/report/ReportActionItemCreated.js @@ -9,8 +9,6 @@ import ReportWelcomeText from '../../../components/ReportWelcomeText'; import participantPropTypes from '../../../components/participantPropTypes'; import * as ReportUtils from '../../../libs/ReportUtils'; import styles from '../../../styles/styles'; -import Navigation from '../../../libs/Navigation/Navigation'; -import ROUTES from '../../../ROUTES'; const propTypes = { /** The report currently being looked at */ @@ -20,9 +18,6 @@ const propTypes = { /** Whether the user is not an admin of policyExpenseChat chat */ isOwnPolicyExpenseChat: PropTypes.bool, - - /** ID of the report */ - reportID: PropTypes.number, }), /** Personal details of all the users */ @@ -42,20 +37,9 @@ const defaultProps = { const ReportActionItemCreated = (props) => { const participants = lodashGet(props.report, 'participants', []); - const isChatRoom = ReportUtils.isChatRoom(props.report); const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(props.report); const icons = ReportUtils.getIcons(props.report, props.personalDetails, props.policies); - function navigateToDetailsPage() { - if (isChatRoom || isPolicyExpenseChat) { - return Navigation.navigate(ROUTES.getReportDetailsRoute(props.report.reportID)); - } - if (participants.length === 1) { - return Navigation.navigate(ROUTES.getDetailsRoute(participants[0])); - } - Navigation.navigate(ROUTES.getReportParticipantsRoute(props.report.reportID)); - } - return ( { ]} > - + ReportUtils.navigateToDetailsPage(props.report, participants)}> Date: Fri, 13 May 2022 00:04:02 +0200 Subject: [PATCH 078/287] set default value to onBlur, remove check --- src/components/Picker/BasePicker/basePickerPropTypes.js | 2 +- src/components/Picker/BasePicker/index.js | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/Picker/BasePicker/basePickerPropTypes.js b/src/components/Picker/BasePicker/basePickerPropTypes.js index 20cf8f0ec213..a3468ec71fea 100644 --- a/src/components/Picker/BasePicker/basePickerPropTypes.js +++ b/src/components/Picker/BasePicker/basePickerPropTypes.js @@ -77,7 +77,7 @@ const defaultProps = { ), size: 'normal', - onBlur: undefined, + onBlur: () => {}, }; export { diff --git a/src/components/Picker/BasePicker/index.js b/src/components/Picker/BasePicker/index.js index 0fade3e32f05..bdd5def02ec3 100644 --- a/src/components/Picker/BasePicker/index.js +++ b/src/components/Picker/BasePicker/index.js @@ -26,10 +26,7 @@ class BasePicker extends React.Component { executeOnCloseAndOnBlur() { // Picker's onClose is not executed on Web and Desktop, so props.onClose has to be called with onBlur callback. this.props.onClose(); - - if (this.props.onBlur) { - this.props.onBlur(); - } + this.props.onBlur(); } render() { From a1559c3bdc34a6beb9a937a801aa0a2c83cc7c25 Mon Sep 17 00:00:00 2001 From: mateusbra Date: Thu, 12 May 2022 20:27:21 -0300 Subject: [PATCH 079/287] use same logic without link regression --- .../HTMLRenderers/AnchorRenderer.js | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js index e768e59bbf98..14d529a8ab86 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js @@ -6,6 +6,8 @@ import { import lodashGet from 'lodash/get'; import htmlRendererPropTypes from './htmlRendererPropTypes'; import * as HTMLEngineUtils from '../htmlEngineUtils'; +import * as Link from '../../../libs/actions/Link'; +import CONFIG from '../../../CONFIG'; import Text from '../../Text'; import CONST from '../../../CONST'; import styles from '../../../styles/styles'; @@ -20,16 +22,29 @@ const AnchorRenderer = (props) => { const displayName = lodashGet(props.tnode, 'domNode.children[0].data', ''); const parentStyle = lodashGet(props.tnode, 'parent.styles.nativeTextRet', {}); const attrHref = htmlAttribs.href || ''; - const internalExpensifyPath = (attrHref.startsWith(CONST.NEW_EXPENSIFY_URL) && attrHref.replace(CONST.NEW_EXPENSIFY_URL, '')) + const internalNewExpensifyPath = (attrHref.startsWith(CONST.NEW_EXPENSIFY_URL) && attrHref.replace(CONST.NEW_EXPENSIFY_URL, '')) || (attrHref.startsWith(CONST.STAGING_NEW_EXPENSIFY_URL) && attrHref.replace(CONST.STAGING_NEW_EXPENSIFY_URL, '')); + const internalExpensifyPath = attrHref.startsWith(CONFIG.EXPENSIFY.EXPENSIFY_URL) && attrHref.replace(CONFIG.EXPENSIFY.EXPENSIFY_URL, ''); // If we are handling a New Expensify link then we will assume this should be opened by the app internally. This ensures that the links are opened internally via react-navigation // instead of in a new tab or with a page refresh (which is the default behavior of an anchor tag) - if (internalExpensifyPath) { + if (internalNewExpensifyPath) { return ( Navigation.navigate(internalExpensifyPath)} + onPress={() => Navigation.navigate(internalNewExpensifyPath)} + > + + + ); + } + + // If we are handling an old dot Expensify link we need to open it with openOldDotLink() so we can navigate to it with the user already logged in. + if (internalExpensifyPath && !isAttachment) { + return ( + Link.openOldDotLink(internalExpensifyPath)} > From ce0407511a26abfde85a00fea3d98fee853a143e Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Fri, 13 May 2022 08:18:56 +0700 Subject: [PATCH 080/287] move to styles folder and rename the base function --- src/components/Modal/BaseModal.js | 2 +- src/libs/getModalStyles/index.android.js | 6 ------ src/libs/getModalStyles/index.js | 3 --- .../getModalStyles/baseGetModalStyles.js} | 6 +++--- src/styles/getModalStyles/index.android.js | 6 ++++++ src/styles/getModalStyles/index.js | 3 +++ 6 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 src/libs/getModalStyles/index.android.js delete mode 100644 src/libs/getModalStyles/index.js rename src/{libs/getModalStyles/getModalStyles.js => styles/getModalStyles/baseGetModalStyles.js} (98%) create mode 100644 src/styles/getModalStyles/index.android.js create mode 100644 src/styles/getModalStyles/index.js diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js index 27e5b81620a0..3779304830f0 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.js @@ -8,7 +8,7 @@ import * as StyleUtils from '../../styles/StyleUtils'; import themeColors from '../../styles/themes/default'; import {propTypes as modalPropTypes, defaultProps as modalDefaultProps} from './modalPropTypes'; import * as Modal from '../../libs/actions/Modal'; -import getModalStyles from '../../libs/getModalStyles'; +import getModalStyles from '../../styles/getModalStyles'; const propTypes = { ...modalPropTypes, diff --git a/src/libs/getModalStyles/index.android.js b/src/libs/getModalStyles/index.android.js deleted file mode 100644 index 1929e49dabeb..000000000000 --- a/src/libs/getModalStyles/index.android.js +++ /dev/null @@ -1,6 +0,0 @@ -import getModalStyles from './getModalStyles'; - -export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => ({ - ...getModalStyles(type, windowDimensions, popoverAnchorPosition, containerStyle), - shouldAddTopSafeAreaPadding: false, -}); diff --git a/src/libs/getModalStyles/index.js b/src/libs/getModalStyles/index.js deleted file mode 100644 index 869dbf45afc0..000000000000 --- a/src/libs/getModalStyles/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import getModalStyles from './getModalStyles'; - -export default getModalStyles; diff --git a/src/libs/getModalStyles/getModalStyles.js b/src/styles/getModalStyles/baseGetModalStyles.js similarity index 98% rename from src/libs/getModalStyles/getModalStyles.js rename to src/styles/getModalStyles/baseGetModalStyles.js index ed926e87a4f2..f61d7968644f 100644 --- a/src/libs/getModalStyles/getModalStyles.js +++ b/src/styles/getModalStyles/baseGetModalStyles.js @@ -1,7 +1,7 @@ import CONST from '../../CONST'; -import colors from '../../styles/colors'; -import variables from '../../styles/variables'; -import themeColors from '../../styles/themes/default'; +import colors from '../colors'; +import variables from '../variables'; +import themeColors from '../themes/default'; export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => { const {isSmallScreenWidth, windowWidth} = windowDimensions; diff --git a/src/styles/getModalStyles/index.android.js b/src/styles/getModalStyles/index.android.js new file mode 100644 index 000000000000..327543cf2065 --- /dev/null +++ b/src/styles/getModalStyles/index.android.js @@ -0,0 +1,6 @@ +import baseGetModalStyles from './baseGetModalStyles'; + +export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => ({ + ...baseGetModalStyles(type, windowDimensions, popoverAnchorPosition, containerStyle), + shouldAddTopSafeAreaPadding: false, +}); diff --git a/src/styles/getModalStyles/index.js b/src/styles/getModalStyles/index.js new file mode 100644 index 000000000000..14b5bec034aa --- /dev/null +++ b/src/styles/getModalStyles/index.js @@ -0,0 +1,3 @@ +import baseGetModalStyles from './baseGetModalStyles'; + +export default baseGetModalStyles; From abefcba5f7ce5d0c442969b3a9632a41c05e363c Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Fri, 13 May 2022 08:44:34 +0000 Subject: [PATCH 081/287] remove method binding --- src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js index 9dbfe8dda54b..e0b6b61d4668 100644 --- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js +++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js @@ -58,7 +58,6 @@ class BasePaymentsPage extends React.Component { this.hidePasswordPrompt = this.hidePasswordPrompt.bind(this); this.navigateToTransferBalancePage = this.navigateToTransferBalancePage.bind(this); this.setMenuPosition = this.setMenuPosition.bind(this); - this.fetchData = this.fetchData.bind(this); } componentDidMount() { From 28f509e89d34f4aa4911d2c5822d399fd41c2580 Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Sat, 14 May 2022 01:14:37 +0700 Subject: [PATCH 082/287] rename base styles and add comment --- .../{baseGetModalStyles.js => getBaseModalStyles.js} | 0 src/styles/getModalStyles/index.android.js | 6 ++++-- src/styles/getModalStyles/index.js | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) rename src/styles/getModalStyles/{baseGetModalStyles.js => getBaseModalStyles.js} (100%) diff --git a/src/styles/getModalStyles/baseGetModalStyles.js b/src/styles/getModalStyles/getBaseModalStyles.js similarity index 100% rename from src/styles/getModalStyles/baseGetModalStyles.js rename to src/styles/getModalStyles/getBaseModalStyles.js diff --git a/src/styles/getModalStyles/index.android.js b/src/styles/getModalStyles/index.android.js index 327543cf2065..440b77ea59b5 100644 --- a/src/styles/getModalStyles/index.android.js +++ b/src/styles/getModalStyles/index.android.js @@ -1,6 +1,8 @@ -import baseGetModalStyles from './baseGetModalStyles'; +import getBaseModalStyles from './getBaseModalStyles'; +// Overrides the value of shouldAddTopSafeAreaPadding to false +// Only apply top padding on iOS since it's the only platform using SafeAreaView export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => ({ - ...baseGetModalStyles(type, windowDimensions, popoverAnchorPosition, containerStyle), + ...getBaseModalStyles(type, windowDimensions, popoverAnchorPosition, containerStyle), shouldAddTopSafeAreaPadding: false, }); diff --git a/src/styles/getModalStyles/index.js b/src/styles/getModalStyles/index.js index 14b5bec034aa..4e35fa589119 100644 --- a/src/styles/getModalStyles/index.js +++ b/src/styles/getModalStyles/index.js @@ -1,3 +1,3 @@ -import baseGetModalStyles from './baseGetModalStyles'; +import getBaseModalStyles from './getBaseModalStyles'; -export default baseGetModalStyles; +export default getBaseModalStyles; From 8b385352969ff8d8e0521922e5cd5e932deeaf4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Sat, 14 May 2022 09:59:46 +0300 Subject: [PATCH 083/287] unnecesary function removed, better comments added, code has been improved. --- src/components/ImageView/index.js | 39 ++++++++----------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 0c4628b52a72..89670caec651 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -23,7 +23,6 @@ class ImageView extends PureComponent { this.onContainerLayoutChanged = this.onContainerLayoutChanged.bind(this); this.onContainerPressIn = this.onContainerPressIn.bind(this); this.onContainerPress = this.onContainerPress.bind(this); - this.onContainerPressOut = this.onContainerPressOut.bind(this); this.imageLoadingStart = this.imageLoadingStart.bind(this); this.imageLoadingEnd = this.imageLoadingEnd.bind(this); this.state = { @@ -96,43 +95,26 @@ class ImageView extends PureComponent { onContainerPress(e) { let scrollX; let scrollY; - if (this.isZoomed && !this.state.isDragging) { + if (!this.state.isZoomed && !this.state.isDragging) { const {offsetX, offsetY} = e.nativeEvent; - // We divide the clicked positions by the zoomScale. - // We need pixel coordinates. + // Dividing clicked positions by the zoom scale to get coordinates + // so that once we zoom we will scroll to the clicked location. const delta = this.getScrollOffset(offsetX / this.state.zoomScale, offsetY / this.state.zoomScale); scrollX = delta.offsetX; scrollY = delta.offsetY; } - if (this.isZoomed && this.state.isDragging && this.state.isMouseDown) { + if (this.state.isZoomed && this.state.isDragging && this.state.isMouseDown) { this.setState({isDragging: false, isMouseDown: false}); - } else if (this.isZoomed) { - // We set isZoomed state then scroll image for calculating positions - this.setState({isZoomed: this.isZoomed}, () => { - this.scrollableRef.scrollTop = scrollY; - this.scrollableRef.scrollLeft = scrollX; - }); - } - } - - onContainerPressOut() { - if (this.state.isDragging) { - return; - } - - // We hold for set isZoomed state if true - // Because when set isZoomed state can't getting actual position user clicked - this.isZoomed = !this.state.isZoomed; - if (this.isZoomed === false) { + } else { + // We first zoom and once its done then we scroll to the location the user clicked. this.setState(prevState => ({ - isMouseDown: false, isZoomed: !prevState.isZoomed, - })); - } else { - this.setState({ isMouseDown: false, + }), () => { + this.scrollableRef.scrollTop = scrollY; + this.scrollableRef.scrollLeft = scrollX; }); } } @@ -170,7 +152,7 @@ class ImageView extends PureComponent { let offsetY; // Container size bigger than clicked position offset - if (x <= (this.state.containerWidth / 2)) { + if (x <= this.state.containerWidth / 2) { offsetX = 0; } else if (x > this.state.containerWidth / 2) { // Minus half of container size because we want to be center clicked position @@ -255,7 +237,6 @@ class ImageView extends PureComponent { }} onPressIn={this.onContainerPressIn} onPress={this.onContainerPress} - onPressOut={this.onContainerPressOut} > Date: Sat, 14 May 2022 10:40:07 +0300 Subject: [PATCH 084/287] unnecesary condition removed. --- src/components/ImageView/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 89670caec651..45cfe8c6c35a 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -120,7 +120,7 @@ class ImageView extends PureComponent { } /** - * When open image, set image width and height. If containerHeight is set before set zoomScale + * When open image, set image width, height and zoomScale. * @param {Number} imageWidth * @param {Number} imageHeight */ @@ -134,11 +134,11 @@ class ImageView extends PureComponent { const height = imageHeight; const newZoomScale = Math.min(containerWidth / width, containerHeight / height); - this.setState(prevState => ({ + this.setState({ imgWidth: width, imgHeight: height, - zoomScale: containerHeight ? newZoomScale : prevState.zoomScale, - })); + zoomScale: newZoomScale, + }); } /** From d8979141a088b72e5fdc01deee3d4a57059b2698 Mon Sep 17 00:00:00 2001 From: Santhoshkumar Sellavel Date: Mon, 16 May 2022 00:19:16 +0530 Subject: [PATCH 085/287] IOU creator cannot deselect their account --- src/components/IOUConfirmationList.js | 1 + src/components/OptionsList/BaseOptionsList.js | 2 +- src/components/OptionsSelector.js | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index d15d34795e57..7468e2138ca4 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -225,6 +225,7 @@ class IOUConfirmationList extends Component { data: [formattedMyPersonalDetails], shouldShow: true, indexOffset: 0, + isDisabled: true, }, { title: this.props.translate('iOUConfirmationList.whoWasThere'), data: formattedSelectedParticipants, diff --git a/src/components/OptionsList/BaseOptionsList.js b/src/components/OptionsList/BaseOptionsList.js index f6049a886c5a..1b66eec802dd 100644 --- a/src/components/OptionsList/BaseOptionsList.js +++ b/src/components/OptionsList/BaseOptionsList.js @@ -111,7 +111,7 @@ class BaseOptionsList extends Component { showSelectedState={this.props.canSelectMultipleOptions} hideAdditionalOptionStates={this.props.hideAdditionalOptionStates} forceTextUnreadStyle={this.props.forceTextUnreadStyle} - isDisabled={this.props.isDisabled} + isDisabled={this.props.isDisabled || section.isDisabled} /> ); } diff --git a/src/components/OptionsSelector.js b/src/components/OptionsSelector.js index 48c34b1fcb15..81a83cbdf19e 100755 --- a/src/components/OptionsSelector.js +++ b/src/components/OptionsSelector.js @@ -30,6 +30,9 @@ const propTypes = { /** Whether this section should show or not */ shouldShow: PropTypes.bool, + + /** Whether this section items disabled for selection */ + isDisabled: PropTypes.bool, })).isRequired, /** Value in the search input field */ From 8beeb85497209244d41283ad39e2845e13c81012 Mon Sep 17 00:00:00 2001 From: mollfpr Date: Mon, 16 May 2022 07:44:35 +0700 Subject: [PATCH 086/287] Update src/styles/getModalStyles/index.android.js Co-authored-by: Santhoshkumar Sellavel <85645967+Santhosh-Sellavel@users.noreply.github.com> --- src/styles/getModalStyles/index.android.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/styles/getModalStyles/index.android.js b/src/styles/getModalStyles/index.android.js index 440b77ea59b5..e7e3531171ae 100644 --- a/src/styles/getModalStyles/index.android.js +++ b/src/styles/getModalStyles/index.android.js @@ -1,6 +1,5 @@ import getBaseModalStyles from './getBaseModalStyles'; -// Overrides the value of shouldAddTopSafeAreaPadding to false // Only apply top padding on iOS since it's the only platform using SafeAreaView export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => ({ ...getBaseModalStyles(type, windowDimensions, popoverAnchorPosition, containerStyle), From 09857bf11e74319a1904a522cc2f43f7e96690dc Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Mon, 16 May 2022 17:37:41 +0300 Subject: [PATCH 087/287] Do not disable whitespace collapsing --- src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js b/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js index a7e4c910f938..874a7364d084 100755 --- a/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js +++ b/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js @@ -53,7 +53,6 @@ const BaseHTMLEngineProvider = (props) => { baseStyle={styles.webViewStyles.baseFontStyle} tagsStyles={styles.webViewStyles.tagStyles} enableCSSInlineProcessing={false} - dangerouslyDisableWhitespaceCollapsing systemFonts={_.values(fontFamily)} > Date: Mon, 16 May 2022 17:39:24 +0300 Subject: [PATCH 088/287] Add styles to baseFontStyle --- src/styles/styles.js | 1 + src/styles/utilities/whiteSpace/index.js | 3 +++ src/styles/utilities/whiteSpace/index.native.js | 3 +++ 3 files changed, 7 insertions(+) diff --git a/src/styles/styles.js b/src/styles/styles.js index f222d4f56246..8a25f765ea36 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -131,6 +131,7 @@ const webViewStyles = { }, baseFontStyle: { + ...whiteSpace.pre, color: themeColors.text, fontSize: variables.fontSizeNormal, fontFamily: fontFamily.GTA, diff --git a/src/styles/utilities/whiteSpace/index.js b/src/styles/utilities/whiteSpace/index.js index 7a7ac524d2cc..a7051cda6c21 100644 --- a/src/styles/utilities/whiteSpace/index.js +++ b/src/styles/utilities/whiteSpace/index.js @@ -5,4 +5,7 @@ export default { preWrap: { whiteSpace: 'pre-wrap', }, + pre: { + whiteSpace: 'pre', + }, }; diff --git a/src/styles/utilities/whiteSpace/index.native.js b/src/styles/utilities/whiteSpace/index.native.js index 250ded17052a..d807b47f208a 100644 --- a/src/styles/utilities/whiteSpace/index.native.js +++ b/src/styles/utilities/whiteSpace/index.native.js @@ -1,4 +1,7 @@ export default { noWrap: {}, preWrap: {}, + pre: { + whiteSpace: 'pre', + }, }; From 33e08d747246d4ee10115c8152e9ad3b07e875f1 Mon Sep 17 00:00:00 2001 From: Orkun Karakus Date: Mon, 16 May 2022 18:56:21 +0300 Subject: [PATCH 089/287] refactored --- .../HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index ee3981fc1541..c3be9a55cc5e 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -30,8 +30,8 @@ class PreRenderer extends React.Component { scrollNode(event) { const node = this.ref.getScrollableNode(); const horizontalOverflow = node.scrollWidth > node.offsetWidth; - - if ((event.currentTarget === node) && horizontalOverflow) { + const isVerticalScrolling = Math.abs(event.deltaY) > 3; // This is for touchpads sensitive + if ((event.currentTarget === node) && horizontalOverflow && !isVerticalScrolling) { node.scrollLeft += event.deltaX; event.preventDefault(); event.stopPropagation(); From e3337c04cf803dd1007fc8d7ac9003b3ac995d44 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Mon, 16 May 2022 18:58:39 +0300 Subject: [PATCH 090/287] Update baseFontStyle --- src/styles/styles.js | 2 +- src/styles/utilities/whiteSpace/index.js | 3 --- src/styles/utilities/whiteSpace/index.native.js | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/styles/styles.js b/src/styles/styles.js index 8a25f765ea36..9f35e60fb728 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -131,11 +131,11 @@ const webViewStyles = { }, baseFontStyle: { - ...whiteSpace.pre, color: themeColors.text, fontSize: variables.fontSizeNormal, fontFamily: fontFamily.GTA, flex: 1, + whiteSpace: 'pre', }, }; diff --git a/src/styles/utilities/whiteSpace/index.js b/src/styles/utilities/whiteSpace/index.js index a7051cda6c21..7a7ac524d2cc 100644 --- a/src/styles/utilities/whiteSpace/index.js +++ b/src/styles/utilities/whiteSpace/index.js @@ -5,7 +5,4 @@ export default { preWrap: { whiteSpace: 'pre-wrap', }, - pre: { - whiteSpace: 'pre', - }, }; diff --git a/src/styles/utilities/whiteSpace/index.native.js b/src/styles/utilities/whiteSpace/index.native.js index d807b47f208a..250ded17052a 100644 --- a/src/styles/utilities/whiteSpace/index.native.js +++ b/src/styles/utilities/whiteSpace/index.native.js @@ -1,7 +1,4 @@ export default { noWrap: {}, preWrap: {}, - pre: { - whiteSpace: 'pre', - }, }; From 9b062365314f27d7833dfaa0955d0f52b5e6943b Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 16 May 2022 16:44:50 +0000 Subject: [PATCH 091/287] Update version to 1.1.61-0 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 4 ++-- ios/NewExpensifyTests/Info.plist | 4 ++-- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 0b16d9136f37..2b377a66361c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016003 - versionName "1.1.60-3" + versionCode 1001016100 + versionName "1.1.61-0" } splits { abi { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 93d6601ab4fa..1de1d16e0fc7 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.1.60 + 1.1.61 CFBundleSignature ???? CFBundleURLTypes @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.60.3 + 1.1.61.0 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 5e9bf6b0f020..4c971fcd7d98 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.1.60 + 1.1.61 CFBundleSignature ???? CFBundleVersion - 1.1.60.3 + 1.1.61.0 diff --git a/package-lock.json b/package-lock.json index 91c8c59bdb3c..03622292f8e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.60-3", + "version": "1.1.61-0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4096beb17bfb..47bfc39973d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.60-3", + "version": "1.1.61-0", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From efa4fd57c147980c4cfea3188e4335c07811b988 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Mon, 16 May 2022 09:53:34 -0700 Subject: [PATCH 092/287] retrying delete branch --- .github/workflows/cherryPick.yml | 2 +- .github/workflows/updateProtectedBranch.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cherryPick.yml b/.github/workflows/cherryPick.yml index 350380aed2b9..479e4c4367f6 100644 --- a/.github/workflows/cherryPick.yml +++ b/.github/workflows/cherryPick.yml @@ -205,7 +205,7 @@ jobs: - name: Auto-merge the PR # Important: only auto-merge if there was no merge conflict and the PR is mergable (not blocked by a missing status check)! if: ${{ fromJSON(steps.cherryPick.outputs.SHOULD_AUTOMERGE) && fromJSON(steps.isPullRequestMergeable.outputs.IS_MERGEABLE) }} - run: gh pr merge --merge --delete-branch + run: gh pr merge --merge --delete-branch || sleep 5 && gh pr merge --merge --delete-branch env: GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} diff --git a/.github/workflows/updateProtectedBranch.yml b/.github/workflows/updateProtectedBranch.yml index 40f00fb63cd0..8bcaca2fa2a5 100644 --- a/.github/workflows/updateProtectedBranch.yml +++ b/.github/workflows/updateProtectedBranch.yml @@ -129,7 +129,7 @@ jobs: run: exit 1 - name: Auto-merge the PR - run: gh pr merge --merge --delete-branch + run: gh pr merge --merge --delete-branch || sleep 5 && gh pr merge --merge --delete-branch env: GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} From 7d240cd9e1091cce4971a84c1fbdcc8a7df5a79e Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 16 May 2022 17:10:00 +0000 Subject: [PATCH 093/287] Update version to 1.1.61-1 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 2b377a66361c..4b6298c65b69 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016100 - versionName "1.1.61-0" + versionCode 1001016101 + versionName "1.1.61-1" } splits { abi { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 1de1d16e0fc7..d51c95067b69 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.61.0 + 1.1.61.1 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 4c971fcd7d98..d6302d355d0b 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.61.0 + 1.1.61.1 diff --git a/package-lock.json b/package-lock.json index 03622292f8e6..3655ee7217fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-0", + "version": "1.1.61-1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 47bfc39973d0..33e9fa94cfb7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-0", + "version": "1.1.61-1", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 5b54adf14c6f38c0c7b0a0d1891befdacf06b778 Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Mon, 16 May 2022 11:20:58 -0600 Subject: [PATCH 094/287] Remove cocoapods cache as it's causing issues --- .github/workflows/platformDeploy.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/platformDeploy.yml b/.github/workflows/platformDeploy.yml index 608aa21204e1..3c11a168f096 100644 --- a/.github/workflows/platformDeploy.yml +++ b/.github/workflows/platformDeploy.yml @@ -209,11 +209,6 @@ jobs: max_attempts: 5 command: npm ci - - uses: actions/cache@v2 - with: - path: ios/Pods - key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} - - name: Install cocoapods run: cd ios && pod install From 40064a74ce88358ed8caa1568fcf570b287fdbbe Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Mon, 16 May 2022 10:55:45 -0700 Subject: [PATCH 095/287] Providing PR number while merging --- .github/workflows/cherryPick.yml | 2 +- .github/workflows/updateProtectedBranch.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cherryPick.yml b/.github/workflows/cherryPick.yml index 479e4c4367f6..1e986010c8dd 100644 --- a/.github/workflows/cherryPick.yml +++ b/.github/workflows/cherryPick.yml @@ -205,7 +205,7 @@ jobs: - name: Auto-merge the PR # Important: only auto-merge if there was no merge conflict and the PR is mergable (not blocked by a missing status check)! if: ${{ fromJSON(steps.cherryPick.outputs.SHOULD_AUTOMERGE) && fromJSON(steps.isPullRequestMergeable.outputs.IS_MERGEABLE) }} - run: gh pr merge --merge --delete-branch || sleep 5 && gh pr merge --merge --delete-branch + run: gh pr merge ${{ steps.createPullRequest.outputs.pr_number }} --merge --delete-branch env: GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} diff --git a/.github/workflows/updateProtectedBranch.yml b/.github/workflows/updateProtectedBranch.yml index 8bcaca2fa2a5..93c84a2b14c8 100644 --- a/.github/workflows/updateProtectedBranch.yml +++ b/.github/workflows/updateProtectedBranch.yml @@ -129,7 +129,7 @@ jobs: run: exit 1 - name: Auto-merge the PR - run: gh pr merge --merge --delete-branch || sleep 5 && gh pr merge --merge --delete-branch + run: gh pr merge ${{ steps.createPullRequest.outputs.PR_NUMBER }} --merge --delete-branch env: GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} From da524361b130c3c549c9fa4c8368fe7f8e12ad8e Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 16 May 2022 18:24:44 +0000 Subject: [PATCH 096/287] Update version to 1.1.61-2 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4b6298c65b69..b347422c122e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016101 - versionName "1.1.61-1" + versionCode 1001016102 + versionName "1.1.61-2" } splits { abi { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index d51c95067b69..ebed143d55d3 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.61.1 + 1.1.61.2 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index d6302d355d0b..5385e67fc5e0 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.61.1 + 1.1.61.2 diff --git a/package-lock.json b/package-lock.json index 3655ee7217fe..e56d0700ac5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-1", + "version": "1.1.61-2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 33e9fa94cfb7..3ce4a82886f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-1", + "version": "1.1.61-2", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 9bf2c4b18f642df1982e3de00c715bf609cd62f9 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 16 May 2022 18:30:01 +0000 Subject: [PATCH 097/287] Update version to 1.1.61-3 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index b347422c122e..6536d77a4f38 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016102 - versionName "1.1.61-2" + versionCode 1001016103 + versionName "1.1.61-3" } splits { abi { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index ebed143d55d3..11022248ac59 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.61.2 + 1.1.61.3 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 5385e67fc5e0..aeca405ac99a 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.61.2 + 1.1.61.3 diff --git a/package-lock.json b/package-lock.json index e56d0700ac5f..f05b89eb37fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-2", + "version": "1.1.61-3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3ce4a82886f5..e3974a4f014f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-2", + "version": "1.1.61-3", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 69e76f2e67b1c32d9893d199a7a29aad34a38ad8 Mon Sep 17 00:00:00 2001 From: Tushu17 Date: Tue, 17 May 2022 01:11:30 +0530 Subject: [PATCH 098/287] remove particpants from the param --- src/libs/ReportUtils.js | 5 +++-- src/pages/home/HeaderView.js | 2 +- src/pages/home/report/ReportActionItemCreated.js | 4 +--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index f55c5788d22f..e1fff4ab699e 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -487,9 +487,10 @@ function getReportName(report, personalDetailsForParticipants = {}, policies = { * Navigate to the details page of a given report * * @param {Object} report - * @param {Array} participants */ -function navigateToDetailsPage(report, participants) { +function navigateToDetailsPage(report) { + const participants = lodashGet(report, 'participants', []); + if (isChatRoom(report) || isPolicyExpenseChat(report)) { Navigation.navigate(ROUTES.getReportDetailsRoute(report.reportID)); return; diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js index bd2ee2a02daf..88a88b7d10b2 100644 --- a/src/pages/home/HeaderView.js +++ b/src/pages/home/HeaderView.js @@ -108,7 +108,7 @@ const HeaderView = (props) => { ]} > ReportUtils.navigateToDetailsPage(props.report, participants)} + onPress={() => ReportUtils.navigateToDetailsPage(props.report)} style={[styles.flexRow, styles.alignItemsCenter, styles.flex1]} > {shouldShowSubscript ? ( diff --git a/src/pages/home/report/ReportActionItemCreated.js b/src/pages/home/report/ReportActionItemCreated.js index a76af7d5ec6d..f0a2a3a6e09d 100644 --- a/src/pages/home/report/ReportActionItemCreated.js +++ b/src/pages/home/report/ReportActionItemCreated.js @@ -2,7 +2,6 @@ import React from 'react'; import {Pressable, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; -import lodashGet from 'lodash/get'; import ONYXKEYS from '../../../ONYXKEYS'; import RoomHeaderAvatars from '../../../components/RoomHeaderAvatars'; import ReportWelcomeText from '../../../components/ReportWelcomeText'; @@ -36,7 +35,6 @@ const defaultProps = { }; const ReportActionItemCreated = (props) => { - const participants = lodashGet(props.report, 'participants', []); const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(props.report); const icons = ReportUtils.getIcons(props.report, props.personalDetails, props.policies); @@ -48,7 +46,7 @@ const ReportActionItemCreated = (props) => { ]} > - ReportUtils.navigateToDetailsPage(props.report, participants)}> + ReportUtils.navigateToDetailsPage(props.report)}> Date: Mon, 16 May 2022 15:52:23 -1000 Subject: [PATCH 099/287] Fix tests --- src/CONST.js | 1 - src/libs/API.js | 3 +- src/libs/Authentication.js | 1 + src/libs/Log.js | 1 + src/libs/Middleware/Reauthentication.js | 14 +++++++++ src/libs/Network/MainQueue.js | 13 ++++++-- src/libs/Network/index.js | 12 ++------ src/libs/actions/Session/index.js | 4 +++ tests/unit/NetworkTest.js | 40 +------------------------ 9 files changed, 36 insertions(+), 53 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 9e4a85a534ca..073d671b65e0 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -313,7 +313,6 @@ const CONST = { SUCCESS: 200, NOT_AUTHENTICATED: 407, EXP_ERROR: 666, - OFFLINE: 'offline', UNABLE_TO_RETRY: 'unableToRetry', }, ERROR: { diff --git a/src/libs/API.js b/src/libs/API.js index 14455aad1627..23db86ce6d43 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -107,11 +107,12 @@ function DeleteFund(parameters) { * @param {String} parameters.partnerUserID * @param {String} parameters.partnerName * @param {String} parameters.partnerPassword + * @param {Boolean} parameters.shouldRetry * @returns {Promise} */ function DeleteLogin(parameters) { const commandName = 'DeleteLogin'; - requireParameters(['partnerUserID', 'partnerName', 'partnerPassword'], + requireParameters(['partnerUserID', 'partnerName', 'partnerPassword', 'shouldRetry'], parameters, commandName); // Non-cancellable request: during logout, when requests are cancelled, we don't want to cancel the actual logout request diff --git a/src/libs/Authentication.js b/src/libs/Authentication.js index bbe301a0ea6c..cd32c958eb25 100644 --- a/src/libs/Authentication.js +++ b/src/libs/Authentication.js @@ -41,6 +41,7 @@ function Authenticate(parameters) { partnerUserSecret: parameters.partnerUserSecret, twoFactorAuthCode: parameters.twoFactorAuthCode, authToken: parameters.authToken, + shouldRetry: false, // Force this request to be made because the network queue is paused when re-authentication is happening forceNetworkRequest: true, diff --git a/src/libs/Log.js b/src/libs/Log.js index 6a0ccc41f899..b0f82656a32a 100644 --- a/src/libs/Log.js +++ b/src/libs/Log.js @@ -37,6 +37,7 @@ function LogCommand(parameters) { function serverLoggingCallback(logger, params) { const requestParams = params; requestParams.shouldProcessImmediately = false; + requestParams.shouldRetry = false; requestParams.expensifyCashAppVersion = `expensifyCash[${getPlatform()}]${version}`; if (requestParams.parameters) { requestParams.parameters = JSON.stringify(params.parameters); diff --git a/src/libs/Middleware/Reauthentication.js b/src/libs/Middleware/Reauthentication.js index a9419e5b63d4..d75b3bde86e0 100644 --- a/src/libs/Middleware/Reauthentication.js +++ b/src/libs/Middleware/Reauthentication.js @@ -1,3 +1,4 @@ +import lodashGet from 'lodash/get'; import CONST from '../../CONST'; import * as NetworkStore from '../Network/NetworkStore'; import * as MainQueue from '../Network/MainQueue'; @@ -23,6 +24,19 @@ function Reauthentication(response, request, isFromSequentialQueue) { } if (data.jsonCode === CONST.JSON_CODE.NOT_AUTHENTICATED) { + // There are some API requests that should not be retried when there is an auth failure like + // creating and deleting logins. In those cases, they should handle the original response instead + // of the new response created by handleExpiredAuthToken. + const shouldRetry = lodashGet(request, 'data.shouldRetry'); + if (!shouldRetry) { + if (isFromSequentialQueue) { + return data; + } + + request.resolve(data); + return; + } + // We are already authenticating if (NetworkStore.isAuthenticating()) { if (isFromSequentialQueue) { diff --git a/src/libs/Network/MainQueue.js b/src/libs/Network/MainQueue.js index b90592ae7b05..2070959668ce 100644 --- a/src/libs/Network/MainQueue.js +++ b/src/libs/Network/MainQueue.js @@ -1,4 +1,5 @@ import _ from 'underscore'; +import lodashGet from 'lodash/get'; import * as NetworkStore from './NetworkStore'; import * as SequentialQueue from './SequentialQueue'; import HttpUtils from '../HttpUtils'; @@ -54,14 +55,20 @@ function process() { } // Some requests should be retried and will end up here if the following conditions are met: - // - we are in the process of authenticating and must wait until we are no longer authenticating + // - we are in the process of authenticating and the request is retryable (most are) // - the request does not have forceNetworkRequest === true (this will trigger it to process immediately) + // - the request does not have shouldRetry === false (specified when we do not want to retry, defaults to true) const requestsToProcessOnNextRun = []; _.each(networkRequestQueue, (queuedRequest) => { - // Save request for the next run if we can't make it yet + // Check if we can make this request at all and if we can't see if we should save it for the next run or chuck it into the ether if (!canMakeRequest(queuedRequest)) { - requestsToProcessOnNextRun.push(queuedRequest); + const shouldRetry = lodashGet(queuedRequest, 'data.shouldRetry'); + if (shouldRetry) { + requestsToProcessOnNextRun.push(queuedRequest); + } else { + console.debug('Skipping request that should not be re-tried: ', {command: queuedRequest.command}); + } return; } diff --git a/src/libs/Network/index.js b/src/libs/Network/index.js index 40d042788bbc..78e91172a973 100644 --- a/src/libs/Network/index.js +++ b/src/libs/Network/index.js @@ -32,10 +32,11 @@ function post(command, data = {}, type = CONST.NETWORK.METHOD.POST, shouldUseSec shouldUseSecure, }; + // By default, request are retry-able and cancellable + // (e.g. any requests currently happening when the user logs out are cancelled) request.data = { ...data, - - // By default, requests are cancellable and any requests currently happening when the user logs out are cancelled. + shouldRetry: lodashGet(data, 'shouldRetry', true), canCancel: lodashGet(data, 'canCancel', true), appversion: version, }; @@ -46,13 +47,6 @@ function post(command, data = {}, type = CONST.NETWORK.METHOD.POST, shouldUseSec return; } - // If we are offline and attempting to make a read request then we will resolve this promise with a non-200 jsonCode that implies it - // could not succeed. We do this any so any requests that block the UI will be able to handle this case (e.g. reset loading flag) - if (NetworkStore.isOffline()) { - resolve({jsonCode: CONST.JSON_CODE.OFFLINE}); - return; - } - // Add promise handlers to any request that we are not persisting request.resolve = resolve; request.reject = reject; diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index e32876fb5f99..ab35b7ead85d 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -78,6 +78,7 @@ function signOut() { partnerUserID: credentials.autoGeneratedLogin, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, + shouldRetry: false, }) .then((response) => { if (response.jsonCode === CONST.JSON_CODE.SUCCESS) { @@ -189,6 +190,7 @@ function createTemporaryLogin(authToken, email) { partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, partnerUserID: autoGeneratedLogin, partnerUserSecret: autoGeneratedPassword, + shouldRetry: false, forceNetworkRequest: true, email, includeEncryptedAuthToken: true, @@ -208,6 +210,7 @@ function createTemporaryLogin(authToken, email) { partnerUserID: credentials.autoGeneratedLogin, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, + shouldRetry: false, }) .then((response) => { if (response.jsonCode === CONST.JSON_CODE.SUCCESS) { @@ -457,6 +460,7 @@ function authenticatePusher(socketID, channelName, callback) { API.Push_Authenticate({ socket_id: socketID, channel_name: channelName, + shouldRetry: false, forceNetworkRequest: true, }) .then((response) => { diff --git a/tests/unit/NetworkTest.js b/tests/unit/NetworkTest.js index c60f3354ec25..1c24199793ff 100644 --- a/tests/unit/NetworkTest.js +++ b/tests/unit/NetworkTest.js @@ -305,35 +305,6 @@ test('Non-retryable request will not be retried if connection is lost in flight' }); }); -test('Non-retryable request will not be retried if we are offline', () => { - // Given a xhr mock that will fail as if network connection dropped - const xhr = jest.spyOn(HttpUtils, 'xhr'); - let promise; - return Onyx.merge(ONYXKEYS.NETWORK, {isOffline: true}) - .then(() => { - // Given a regular non retryable request - promise = Network.post('Get'); - return waitForPromisesToResolve(); - }) - .then(() => { - // When network connection is recovered - Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false}); - return waitForPromisesToResolve(); - }) - .then(() => { - // Advance the network request queue by 1 second so that it can realize it's back online - jest.advanceTimersByTime(CONST.NETWORK.PROCESS_REQUEST_DELAY_MS); - return waitForPromisesToResolve(); - }) - .then(() => { - // Then the request should not have been attempted at all and we should get an offline jsonCode - expect(xhr).toHaveBeenCalledTimes(0); - - // And the promise should be resolved with the special offline jsonCode - return expect(promise).resolves.toEqual({jsonCode: CONST.JSON_CODE.OFFLINE}); - }); -}); - test('Retryable requests should be persisted while offline', () => { // We don't expect calls `xhr` so we make the test fail if such call is made const xhr = jest.spyOn(HttpUtils, 'xhr').mockRejectedValue(new Error('Unexpected xhr call')); @@ -568,7 +539,6 @@ test('several actions made while offline will get added in the order they are cr // Given offline state where all requests will eventualy succeed without issue const xhr = jest.spyOn(HttpUtils, 'xhr') .mockResolvedValue({jsonCode: CONST.JSON_CODE.SUCCESS}); - let nonPersistableRequest; return Onyx.multiSet({ [ONYXKEYS.SESSION]: {authToken: 'anyToken'}, [ONYXKEYS.NETWORK]: {isOffline: true}, @@ -579,7 +549,7 @@ test('several actions made while offline will get added in the order they are cr Network.post('MockCommand', {content: 'value1', persist: true}); Network.post('MockCommand', {content: 'value2', persist: true}); Network.post('MockCommand', {content: 'value3', persist: true}); - nonPersistableRequest = Network.post('MockCommand', {content: 'not-persisted'}); + Network.post('MockCommand', {content: 'not-persisted'}); Network.post('MockCommand', {content: 'value4', persist: true}); Network.post('MockCommand', {content: 'value5', persist: true}); Network.post('MockCommand', {content: 'value6', persist: true}); @@ -598,14 +568,6 @@ test('several actions made while offline will get added in the order they are cr expect(xhr.mock.calls[3][1].content).toBe('value4'); expect(xhr.mock.calls[4][1].content).toBe('value5'); expect(xhr.mock.calls[5][1].content).toBe('value6'); - - // Move main queue forward - jest.advanceTimersByTime(CONST.NETWORK.PROCESS_REQUEST_DELAY_MS); - return waitForPromisesToResolve(); - }) - .then(() => { - // We should not expect the request that could not be retried to resolve - expect(nonPersistableRequest).resolves.toEqual({jsonCode: CONST.JSON_CODE.OFFLINE}); }); }); From 0aaf3e2e6caafe763fa9bdb34e70a0e45d045a95 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Mon, 16 May 2022 15:54:17 -1000 Subject: [PATCH 100/287] Revert import and param update --- src/libs/API.js | 1 + src/libs/Network/index.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/API.js b/src/libs/API.js index 23db86ce6d43..beb567a5b799 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -76,6 +76,7 @@ function User_SignUp(parameters) { * @param {String} parameters.partnerPassword * @param {String} parameters.partnerUserID * @param {String} parameters.partnerUserSecret + * @param {Boolean} [parameters.shouldRetry] * @param {String} [parameters.email] * @returns {Promise} */ diff --git a/src/libs/Network/index.js b/src/libs/Network/index.js index 78e91172a973..b4d6dab94f36 100644 --- a/src/libs/Network/index.js +++ b/src/libs/Network/index.js @@ -4,7 +4,6 @@ import CONST from '../../CONST'; import * as MainQueue from './MainQueue'; import * as SequentialQueue from './SequentialQueue'; import {version} from '../../../package.json'; -import * as NetworkStore from './NetworkStore'; // We must wait until the ActiveClientManager is ready so that we ensure only the "leader" tab processes any persisted requests ActiveClientManager.isReady().then(() => { From e81788227d02d30ddfd356e31f0e2710bbab09b3 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Tue, 17 May 2022 12:17:34 +0530 Subject: [PATCH 101/287] fixed download issues for files rendered as anchor tag instead of images --- src/libs/fileDownload/getAttachmentDetails.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libs/fileDownload/getAttachmentDetails.js b/src/libs/fileDownload/getAttachmentDetails.js index 8b8e777ab911..d393c6ed45be 100644 --- a/src/libs/fileDownload/getAttachmentDetails.js +++ b/src/libs/fileDownload/getAttachmentDetails.js @@ -6,11 +6,14 @@ import Config from '../../CONFIG'; * @param {String} html * @returns {Object} */ -const PREVIEW_SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_PREVIEW_ATTRIBUTE}*=*"(.+?)"`, 'i'); -const SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_SOURCE_ATTRIBUTE}*=*"(.+?)"`, 'i'); -const ORIGINAL_FILENAME_REGEX = new RegExp(`${CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE}*=*"(.+?)"`, 'i'); export default function getAttachmentName(html) { + // Files can be rendered either as anchor tag or as an image so based on that we have to form regex. + const IMG_TAG_REGEX = //i; + const IS_IMAGE_TAG = IMG_TAG_REGEX.test(html); + const PREVIEW_SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_PREVIEW_ATTRIBUTE}*=*"(.+?)"`, 'i'); + const SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_SOURCE_ATTRIBUTE}*=*"(.+?)"`, 'i'); + const ORIGINAL_FILENAME_REGEX = IS_IMAGE_TAG ? new RegExp(`${CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE}*=*"(.+?)"`, 'i') : new RegExp(']*>([^<]+)', 'i'); if (!html) { return { previewSourceURL: null, @@ -18,11 +21,11 @@ export default function getAttachmentName(html) { originalFileName: null, }; } - const previewSourceURL = html.match(PREVIEW_SOURCE_REGEX)[1].replace( + const sourceURL = html.match(SOURCE_REGEX)[1].replace( Config.EXPENSIFY.EXPENSIFY_URL, Config.EXPENSIFY.URL_API_ROOT, ); - const sourceURL = html.match(SOURCE_REGEX)[1].replace( + const previewSourceURL = (IS_IMAGE_TAG ? html.match(PREVIEW_SOURCE_REGEX)[1] : sourceURL).replace( Config.EXPENSIFY.EXPENSIFY_URL, Config.EXPENSIFY.URL_API_ROOT, ); From 11d60aebfe671f818f509fdfb3dccf00a908e008 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Tue, 17 May 2022 15:46:17 +0530 Subject: [PATCH 102/287] remove dissmiss modal option when clicking on workskpace add work email --- src/pages/workspace/card/WorkspaceCardVBANoECardView.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/card/WorkspaceCardVBANoECardView.js b/src/pages/workspace/card/WorkspaceCardVBANoECardView.js index edece8912aa7..a34828a01575 100644 --- a/src/pages/workspace/card/WorkspaceCardVBANoECardView.js +++ b/src/pages/workspace/card/WorkspaceCardVBANoECardView.js @@ -27,7 +27,6 @@ const WorkspaceCardVBANoECardView = props => ( { title: props.translate('workspace.card.addWorkEmail'), onPress: () => { - Navigation.dismissModal(); Link.openOldDotLink(CONST.ADD_SECONDARY_LOGIN_URL); User.subscribeToExpensifyCardUpdates(); }, From 0f9972ab826a7584a773e60d5742fe1b73c26f00 Mon Sep 17 00:00:00 2001 From: Orkun Karakus Date: Tue, 17 May 2022 15:36:09 +0300 Subject: [PATCH 103/287] detailed comment added --- .../HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index c3be9a55cc5e..7d4f29670956 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -30,6 +30,10 @@ class PreRenderer extends React.Component { scrollNode(event) { const node = this.ref.getScrollableNode(); const horizontalOverflow = node.scrollWidth > node.offsetWidth; + + /* if the user scrolls horizontally while scrolling with two fingers on the touchpads, + the fingers may go up a little during that scroll, and the page will start to scroll + vertically due to this going up. With this sensitive we eliminate this bug. */ const isVerticalScrolling = Math.abs(event.deltaY) > 3; // This is for touchpads sensitive if ((event.currentTarget === node) && horizontalOverflow && !isVerticalScrolling) { node.scrollLeft += event.deltaX; From 8ed628399a4d966d89f77a049c9b0ad6cdbfe7fe Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Tue, 17 May 2022 12:55:44 +0000 Subject: [PATCH 104/287] Allow MacOS app download link to be copy from Right Hand fix --- src/pages/settings/AppDownloadLinks.js | 57 ++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/src/pages/settings/AppDownloadLinks.js b/src/pages/settings/AppDownloadLinks.js index d395d375f304..a724fe0ddf74 100644 --- a/src/pages/settings/AppDownloadLinks.js +++ b/src/pages/settings/AppDownloadLinks.js @@ -7,15 +7,25 @@ import CONST from '../../CONST'; import * as Expensicons from '../../components/Icon/Expensicons'; import ScreenWrapper from '../../components/ScreenWrapper'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import compose from '../../libs/compose'; import MenuItem from '../../components/MenuItem'; import styles from '../../styles/styles'; import * as Link from '../../libs/actions/Link'; +import PressableWithSecondaryInteraction from '../../components/PressableWithSecondaryInteraction'; +import ControlSelection from '../../libs/ControlSelection'; +import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions'; +import canUseTouchScreen from '../../libs/canUseTouchscreen'; +import * as ReportActionContextMenu from '../home/report/ContextMenu/ReportActionContextMenu'; +import * as ContextMenuActions from '../home/report/ContextMenu/ContextMenuActions'; const propTypes = { ...withLocalizePropTypes, + ...windowDimensionsPropTypes, }; const AppDownloadLinksPage = (props) => { + let popoverAnchor; + const menuItems = [ { translationKey: 'initialSettingsPage.appDownloadLinks.android.label', @@ -24,6 +34,7 @@ const AppDownloadLinksPage = (props) => { action: () => { Link.openExternalLink(CONST.APP_DOWNLOAD_LINKS.ANDROID); }, + link: CONST.APP_DOWNLOAD_LINKS.ANDROID, }, { translationKey: 'initialSettingsPage.appDownloadLinks.ios.label', @@ -32,6 +43,7 @@ const AppDownloadLinksPage = (props) => { action: () => { Link.openExternalLink(CONST.APP_DOWNLOAD_LINKS.IOS); }, + link: CONST.APP_DOWNLOAD_LINKS.IOS, }, { translationKey: 'initialSettingsPage.appDownloadLinks.desktop.label', @@ -40,9 +52,25 @@ const AppDownloadLinksPage = (props) => { action: () => { Link.openExternalLink(CONST.APP_DOWNLOAD_LINKS.DESKTOP); }, + link: CONST.APP_DOWNLOAD_LINKS.DESKTOP, }, ]; + /** + * Show the ReportActionContextMenu modal popover. + * + * @param {Object} [event] - A press event. + * @param {string} [selection] - A copy text. + */ + const showPopover = (event, selection) => { + ReportActionContextMenu.showContextMenu( + ContextMenuActions.CONTEXT_MENU_TYPES.LINK, + event, + selection, + popoverAnchor, + ); + }; + return ( { /> {_.map(menuItems, item => ( - item.action()} - shouldShowRightIcon - /> + onPressIn={() => props.isSmallScreenWidth && canUseTouchScreen() && ControlSelection.block()} + onPressOut={() => ControlSelection.unblock()} + onSecondaryInteraction={e => showPopover(e, item.link)} + ref={el => popoverAnchor = el} + onKeyDown={(event) => { + event.target.blur(); + }} + > + item.action()} + shouldShowRightIcon + /> + ))} @@ -70,4 +108,7 @@ const AppDownloadLinksPage = (props) => { AppDownloadLinksPage.propTypes = propTypes; AppDownloadLinksPage.displayName = 'AppDownloadLinksPage'; -export default withLocalize(AppDownloadLinksPage); +export default compose( + withWindowDimensions, + withLocalize, +)(AppDownloadLinksPage); From f2a42a8c6ffa39492eded6d86261293b86e8587a Mon Sep 17 00:00:00 2001 From: kakajann Date: Tue, 17 May 2022 18:50:24 +0500 Subject: [PATCH 105/287] fix workspace member growl fix --- src/pages/workspace/WorkspaceMembersPage.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index a4ae23252d78..bbaab115a517 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -148,7 +148,13 @@ class WorkspaceMembersPage extends React.Component { const canBeRemoved = this.props.policy.owner !== login && this.props.session.email !== login; if (!canBeRemoved) { - this.setState({showTooltipForLogin: login}); + this.setState({ + showTooltipForLogin: login, + }, () => { + this.setState({ + showTooltipForLogin: '', + }); + }); } return !canBeRemoved; From 5fd2a653e030fb3c45d60875629c6ca22c5eb383 Mon Sep 17 00:00:00 2001 From: kakajann Date: Tue, 17 May 2022 19:13:20 +0500 Subject: [PATCH 106/287] minor refactor and comment --- src/pages/workspace/WorkspaceMembersPage.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index bbaab115a517..acd886de5ca1 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -148,13 +148,10 @@ class WorkspaceMembersPage extends React.Component { const canBeRemoved = this.props.policy.owner !== login && this.props.session.email !== login; if (!canBeRemoved) { + // Show growl notification to inform the user that they can not remove themselves. this.setState({ showTooltipForLogin: login, - }, () => { - this.setState({ - showTooltipForLogin: '', - }); - }); + }, () => this.setState({showTooltipForLogin: ''})); } return !canBeRemoved; From e87646d2868849d0818a19ec6f0bb7f584ebba85 Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Tue, 17 May 2022 21:00:13 +0530 Subject: [PATCH 107/287] updated fallbackIcon comment --- src/components/Avatar.js | 2 +- src/components/AvatarWithImagePicker.js | 2 +- src/components/menuItemPropTypes.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index bc8bcc9b9e18..ff51d2c427b8 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -25,7 +25,7 @@ const propTypes = { /** The fill color for the icon. Can be hex, rgb, rgba, or valid react-native named color such as 'red' or 'blue' */ fill: PropTypes.string, - /** Function for using fallback avatar */ + /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ fallbackIcon: PropTypes.func, }; diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 66284c31eb54..2e0d4f3c8792 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -53,7 +53,7 @@ const propTypes = { /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), - /** Function for using fallback avatar */ + /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ fallbackIcon: PropTypes.func, ...withLocalizePropTypes, diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index 4f3efd59c4c1..0dd6b954aa4f 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -64,7 +64,7 @@ const propTypes = { /** Whether the menu item should be interactive at all */ interactive: PropTypes.bool, - /** Function for using fallback avatar */ + /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ fallbackIcon: PropTypes.func, }; From c39c830bf73631a9e1bc6ea2d4c0c47e16dce588 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Tue, 17 May 2022 16:37:19 +0000 Subject: [PATCH 108/287] Update version to 1.1.62-0 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 4 ++-- ios/NewExpensifyTests/Info.plist | 4 ++-- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 6536d77a4f38..9675636abf79 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016103 - versionName "1.1.61-3" + versionCode 1001016200 + versionName "1.1.62-0" } splits { abi { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 11022248ac59..22b5d68f1311 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.1.61 + 1.1.62 CFBundleSignature ???? CFBundleURLTypes @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.61.3 + 1.1.62.0 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index aeca405ac99a..6c3ab90cfbca 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.1.61 + 1.1.62 CFBundleSignature ???? CFBundleVersion - 1.1.61.3 + 1.1.62.0 diff --git a/package-lock.json b/package-lock.json index f05b89eb37fb..3652910fd625 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-3", + "version": "1.1.62-0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e3974a4f014f..2c55c635b2ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-3", + "version": "1.1.62-0", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 36d72b7db2a4580a6979592e5d004868c99b40a7 Mon Sep 17 00:00:00 2001 From: Orkun Karakus Date: Tue, 17 May 2022 19:47:30 +0300 Subject: [PATCH 109/287] detailed comment added --- .../HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index 7d4f29670956..9e7a63fd9091 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -31,9 +31,9 @@ class PreRenderer extends React.Component { const node = this.ref.getScrollableNode(); const horizontalOverflow = node.scrollWidth > node.offsetWidth; - /* if the user scrolls horizontally while scrolling with two fingers on the touchpads, - the fingers may go up a little during that scroll, and the page will start to scroll - vertically due to this going up. With this sensitive we eliminate this bug. */ + /* Scrolling horizontally with two fingers on the touchpads, + the fingers may go up a little during that scroll, and the page will + start to scroll vertically. We eliminate this bug by checking the large delta. */ const isVerticalScrolling = Math.abs(event.deltaY) > 3; // This is for touchpads sensitive if ((event.currentTarget === node) && horizontalOverflow && !isVerticalScrolling) { node.scrollLeft += event.deltaX; From 08a7996e3b130783f3b1efb630531a97a75c630c Mon Sep 17 00:00:00 2001 From: kakajann Date: Tue, 17 May 2022 23:27:52 +0500 Subject: [PATCH 110/287] minor refactor --- src/pages/workspace/WorkspaceMembersPage.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index acd886de5ca1..54ed92ef36a7 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -141,17 +141,24 @@ class WorkspaceMembersPage extends React.Component { * @returns {Boolean} Return true if the tooltip was displayed so we can use the state of it in other functions. */ willTooltipShowForLogin(login, wasHovered = false) { + const isSmallOrMediumScreen = this.props.isSmallScreenWidth || this.props.isMediumScreenWidth; + // Small screens only show the tooltip on press, so ignore hovered event on those cases. - if (wasHovered && (this.props.isSmallScreenWidth || this.props.isMediumScreenWidth)) { + if (wasHovered && isSmallOrMediumScreen) { return false; } const canBeRemoved = this.props.policy.owner !== login && this.props.session.email !== login; if (!canBeRemoved) { - // Show growl notification to inform the user that they can not remove themselves. this.setState({ showTooltipForLogin: login, - }, () => this.setState({showTooltipForLogin: ''})); + }, () => { + // Immediately reset the login to deactivate the tooltip trigger, otherwise, the tooltip will not be open again on further interactions on small screens. + if (!isSmallOrMediumScreen) { + return; + } + this.setState({showTooltipForLogin: ''}); + }); } return !canBeRemoved; @@ -249,6 +256,8 @@ class WorkspaceMembersPage extends React.Component { const policyID = lodashGet(this.props.route, 'params.policyID'); const policyName = lodashGet(this.props.policy, 'name'); + console.log(this.state.showTooltipForLogin); + return ( Date: Tue, 17 May 2022 23:41:50 +0500 Subject: [PATCH 111/287] remove console.log --- src/pages/workspace/WorkspaceMembersPage.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 54ed92ef36a7..f19a2f9f5187 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -256,8 +256,6 @@ class WorkspaceMembersPage extends React.Component { const policyID = lodashGet(this.props.route, 'params.policyID'); const policyName = lodashGet(this.props.policy, 'name'); - console.log(this.state.showTooltipForLogin); - return ( Date: Tue, 17 May 2022 20:56:07 +0100 Subject: [PATCH 112/287] fix display of remove photo option for avatar on profile page --- src/pages/settings/Profile/ProfilePage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js index 1aaf232db0bf..fbeb7b69b16c 100755 --- a/src/pages/settings/Profile/ProfilePage.js +++ b/src/pages/settings/Profile/ProfilePage.js @@ -231,7 +231,7 @@ class ProfilePage extends Component { Date: Wed, 18 May 2022 01:35:26 +0530 Subject: [PATCH 113/287] removed Navigation import --- src/pages/workspace/card/WorkspaceCardVBANoECardView.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/card/WorkspaceCardVBANoECardView.js b/src/pages/workspace/card/WorkspaceCardVBANoECardView.js index a34828a01575..73b2ef6dad28 100644 --- a/src/pages/workspace/card/WorkspaceCardVBANoECardView.js +++ b/src/pages/workspace/card/WorkspaceCardVBANoECardView.js @@ -7,7 +7,6 @@ import * as Expensicons from '../../../components/Icon/Expensicons'; import * as Illustrations from '../../../components/Icon/Illustrations'; import UnorderedList from '../../../components/UnorderedList'; import Section from '../../../components/Section'; -import Navigation from '../../../libs/Navigation/Navigation'; import * as Link from '../../../libs/actions/Link'; import * as User from '../../../libs/actions/User'; import ONYXKEYS from '../../../ONYXKEYS'; From fbe2b7d5fe96d4009fc744d5ad454190042d3431 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Wed, 18 May 2022 02:09:04 +0530 Subject: [PATCH 114/287] made testing for image tag single line --- src/libs/fileDownload/getAttachmentDetails.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/fileDownload/getAttachmentDetails.js b/src/libs/fileDownload/getAttachmentDetails.js index d393c6ed45be..8a465403f8a8 100644 --- a/src/libs/fileDownload/getAttachmentDetails.js +++ b/src/libs/fileDownload/getAttachmentDetails.js @@ -6,11 +6,9 @@ import Config from '../../CONFIG'; * @param {String} html * @returns {Object} */ - export default function getAttachmentName(html) { // Files can be rendered either as anchor tag or as an image so based on that we have to form regex. - const IMG_TAG_REGEX = //i; - const IS_IMAGE_TAG = IMG_TAG_REGEX.test(html); + const IS_IMAGE_TAG = //i.test(html); const PREVIEW_SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_PREVIEW_ATTRIBUTE}*=*"(.+?)"`, 'i'); const SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_SOURCE_ATTRIBUTE}*=*"(.+?)"`, 'i'); const ORIGINAL_FILENAME_REGEX = IS_IMAGE_TAG ? new RegExp(`${CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE}*=*"(.+?)"`, 'i') : new RegExp(']*>([^<]+)', 'i'); From 3fc927e1be502cb6e218ff12f9e4402c6e860803 Mon Sep 17 00:00:00 2001 From: James Stanley Date: Wed, 18 May 2022 00:42:43 +0100 Subject: [PATCH 115/287] retrigger cla check From ced4039c37414616b57c878b226ab3a050b42d36 Mon Sep 17 00:00:00 2001 From: Orkun Karakus Date: Wed, 18 May 2022 08:35:18 +0300 Subject: [PATCH 116/287] refactored comment --- .../HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index 9e7a63fd9091..6b911a720aff 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -31,9 +31,7 @@ class PreRenderer extends React.Component { const node = this.ref.getScrollableNode(); const horizontalOverflow = node.scrollWidth > node.offsetWidth; - /* Scrolling horizontally with two fingers on the touchpads, - the fingers may go up a little during that scroll, and the page will - start to scroll vertically. We eliminate this bug by checking the large delta. */ + // Account for vertical scrolling variation when horizontally scrolling via touchpad by checking a large delta. const isVerticalScrolling = Math.abs(event.deltaY) > 3; // This is for touchpads sensitive if ((event.currentTarget === node) && horizontalOverflow && !isVerticalScrolling) { node.scrollLeft += event.deltaX; From 11ea962e7fca64cda4f10e7d44552ac99013a81f Mon Sep 17 00:00:00 2001 From: Kakajann Dortguly Date: Wed, 18 May 2022 18:35:08 +0500 Subject: [PATCH 117/287] Update src/pages/workspace/WorkspaceMembersPage.js Co-authored-by: Rajat Parashar --- src/pages/workspace/WorkspaceMembersPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index f19a2f9f5187..764da2999e21 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -153,7 +153,7 @@ class WorkspaceMembersPage extends React.Component { this.setState({ showTooltipForLogin: login, }, () => { - // Immediately reset the login to deactivate the tooltip trigger, otherwise, the tooltip will not be open again on further interactions on small screens. + // Immediately reset the login to deactivate the tooltip trigger, otherwise, the tooltip will not open again on further interactions on small screens. if (!isSmallOrMediumScreen) { return; } From 23c251789bb7793a23313bc922f077e412aeb687 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 18 May 2022 15:11:55 +0000 Subject: [PATCH 118/287] Update version to 1.1.63-0 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 4 ++-- ios/NewExpensifyTests/Info.plist | 4 ++-- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 9675636abf79..6ff704b5b54d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016200 - versionName "1.1.62-0" + versionCode 1001016300 + versionName "1.1.63-0" } splits { abi { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 22b5d68f1311..aad569e3192f 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.1.62 + 1.1.63 CFBundleSignature ???? CFBundleURLTypes @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.62.0 + 1.1.63.0 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 6c3ab90cfbca..9b233a12611c 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.1.62 + 1.1.63 CFBundleSignature ???? CFBundleVersion - 1.1.62.0 + 1.1.63.0 diff --git a/package-lock.json b/package-lock.json index 3652910fd625..a5d34b5f80af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.62-0", + "version": "1.1.63-0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2c55c635b2ab..00ee723a64e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.62-0", + "version": "1.1.63-0", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 7049189b8fd199dcfa3df5c95d06899c06bb935d Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 18 May 2022 09:56:34 -0600 Subject: [PATCH 119/287] Simplify growl is ready --- src/components/GrowlNotification/index.js | 5 +++-- src/libs/Growl.js | 10 ++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js index 6d7fe9f2417a..ed212fcde76d 100644 --- a/src/components/GrowlNotification/index.js +++ b/src/components/GrowlNotification/index.js @@ -12,7 +12,7 @@ import * as Expensicons from '../Icon/Expensicons'; import styles from '../../styles/styles'; import GrowlNotificationContainer from './GrowlNotificationContainer'; import CONST from '../../CONST'; -import * as Growl from '../../libs/Growl'; +import Growl, {setIsReady} from '../../libs/Growl'; const types = { [CONST.GROWL.SUCCESS]: { @@ -46,7 +46,8 @@ class GrowlNotification extends Component { } componentDidMount() { - Growl.setIsReady(); + Growl.show('test', CONST.GROWL.SUCCESS); + setIsReady(); } /** diff --git a/src/libs/Growl.js b/src/libs/Growl.js index 325a4ecd213c..3da2b7543532 100644 --- a/src/libs/Growl.js +++ b/src/libs/Growl.js @@ -1,12 +1,14 @@ import React from 'react'; import CONST from '../CONST'; -import createOnReadyTask from './createOnReadyTask'; const growlRef = React.createRef(); -const growlReadyTask = createOnReadyTask(); +let resolveIsReadyPromise; +const isReadyPromise = new Promise((resolve) => { + resolveIsReadyPromise = resolve; +}); function setIsReady() { - growlReadyTask.setIsReady(); + resolveIsReadyPromise(); } /** @@ -17,7 +19,7 @@ function setIsReady() { * @param {Number} [duration] */ function show(bodyText, type, duration = CONST.GROWL.DURATION) { - growlReadyTask.isReady().then(() => growlRef.current.show(bodyText, type, duration)); + isReadyPromise.then(() => growlRef.current.show(bodyText, type, duration)); } /** From d84f973c81e28f5524d2c335caa8456805cf4379 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 18 May 2022 16:11:13 +0000 Subject: [PATCH 120/287] Update version to 1.1.63-1 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 6ff704b5b54d..71730bf982f7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016300 - versionName "1.1.63-0" + versionCode 1001016301 + versionName "1.1.63-1" } splits { abi { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index aad569e3192f..617b012c711a 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.63.0 + 1.1.63.1 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 9b233a12611c..2ebfc76f498c 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.63.0 + 1.1.63.1 diff --git a/package-lock.json b/package-lock.json index a5d34b5f80af..fff3aadc12b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.63-0", + "version": "1.1.63-1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 00ee723a64e0..ace3a4513e33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.63-0", + "version": "1.1.63-1", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From dcd4f6d5bf88906b932ac6c259c5525425b1d469 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 18 May 2022 16:45:14 +0000 Subject: [PATCH 121/287] Update version to 1.1.63-2 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 71730bf982f7..9c58dc62b540 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016301 - versionName "1.1.63-1" + versionCode 1001016302 + versionName "1.1.63-2" } splits { abi { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 617b012c711a..164ae00377ad 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.63.1 + 1.1.63.2 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 2ebfc76f498c..762c7fc37d4f 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.63.1 + 1.1.63.2 diff --git a/package-lock.json b/package-lock.json index fff3aadc12b5..49929060196f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.63-1", + "version": "1.1.63-2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ace3a4513e33..ad194baa99fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.63-1", + "version": "1.1.63-2", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From dc27ac3a15147aa1eb42c5ff29562a4dab466064 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 18 May 2022 10:51:33 -0600 Subject: [PATCH 122/287] Remove test growl --- src/components/GrowlNotification/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js index ed212fcde76d..6d7fe9f2417a 100644 --- a/src/components/GrowlNotification/index.js +++ b/src/components/GrowlNotification/index.js @@ -12,7 +12,7 @@ import * as Expensicons from '../Icon/Expensicons'; import styles from '../../styles/styles'; import GrowlNotificationContainer from './GrowlNotificationContainer'; import CONST from '../../CONST'; -import Growl, {setIsReady} from '../../libs/Growl'; +import * as Growl from '../../libs/Growl'; const types = { [CONST.GROWL.SUCCESS]: { @@ -46,8 +46,7 @@ class GrowlNotification extends Component { } componentDidMount() { - Growl.show('test', CONST.GROWL.SUCCESS); - setIsReady(); + Growl.setIsReady(); } /** From 392287d68e02ad749cd7b0ba196645128b887c65 Mon Sep 17 00:00:00 2001 From: sahil Date: Thu, 19 May 2022 00:09:18 +0530 Subject: [PATCH 123/287] show the activity indicator above the hidden text --- src/components/Button.js | 11 +++++++---- src/styles/styles.js | 4 ++++ src/styles/utilities/positioning.js | 6 ++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/components/Button.js b/src/components/Button.js index 85254d4c1e75..cbd633305591 100644 --- a/src/components/Button.js +++ b/src/components/Button.js @@ -173,14 +173,11 @@ class Button extends Component { return ; } - if (this.props.isLoading) { - return ; - } - const textComponent = ( {this.renderContent()} + {this.props.isLoading && ( + + )} )} diff --git a/src/styles/styles.js b/src/styles/styles.js index 75c22fd4c785..df1f89d65939 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -320,6 +320,10 @@ const styles = { backgroundColor: 'transparent', }, + opacity0: { + opacity: 0, + }, + opacity1: { opacity: 1, }, diff --git a/src/styles/utilities/positioning.js b/src/styles/utilities/positioning.js index 455566b4655d..f25c757fbfc3 100644 --- a/src/styles/utilities/positioning.js +++ b/src/styles/utilities/positioning.js @@ -15,6 +15,12 @@ export default { tn8: { top: -32, }, + l0: { + left: 0, + }, + r0: { + right: 0, + }, r4: { right: 16, }, From f49aaa28bf6ccb68ef36c507edb51bfeddb98669 Mon Sep 17 00:00:00 2001 From: sahil Date: Thu, 19 May 2022 00:09:31 +0530 Subject: [PATCH 124/287] use button --- src/components/ReportTransaction.js | 35 +++++++---------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 8572270e9a13..c201434d9569 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -1,18 +1,16 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; -import { - View, Pressable, ActivityIndicator, -} from 'react-native'; +import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; -import themeColors from '../styles/themes/default'; import * as IOU from '../libs/actions/IOU'; import reportActionPropTypes from '../pages/home/report/reportActionPropTypes'; import ReportActionItemSingle from '../pages/home/report/ReportActionItemSingle'; import Text from './Text'; +import Button from './Button'; const propTypes = { /** The chatReport which the transaction is associated with */ @@ -88,30 +86,13 @@ class ReportTransaction extends Component { {this.props.canBeRejected && ( - - { - this.isBeingRejected() - ? ( - - ) - : ( - - {this.props.rejectButtonLabelText} - - ) - } - + isLoading={this.isBeingRejected()} + /> )} From f457cb6ad23f60ab06fc6114bf4f9768d832e41c Mon Sep 17 00:00:00 2001 From: sahil Date: Thu, 19 May 2022 00:21:17 +0530 Subject: [PATCH 125/287] remove minimum width --- src/pages/signin/ResendValidationForm.js | 1 - src/styles/styles.js | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/pages/signin/ResendValidationForm.js b/src/pages/signin/ResendValidationForm.js index 3a19e901cc15..701cc41d8561 100755 --- a/src/pages/signin/ResendValidationForm.js +++ b/src/pages/signin/ResendValidationForm.js @@ -143,7 +143,6 @@ class ResendValidationForm extends React.Component { text={this.props.translate('resendValidationForm.resendLink')} isLoading={this.props.account.loading} onPress={this.validateAndSubmitForm} - style={styles.resendLinkButton} /> diff --git a/src/styles/styles.js b/src/styles/styles.js index df1f89d65939..a76ff5311106 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -956,10 +956,6 @@ const styles = { height: '100%', }, - resendLinkButton: { - minWidth: 124, - }, - sidebarFooter: { alignItems: 'center', display: 'flex', From d6dfae1044583456fa37ae50ebb0ff806dd1ee8d Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Wed, 18 May 2022 13:28:28 -0600 Subject: [PATCH 126/287] Retry Cocoapod install --- .github/workflows/platformDeploy.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/platformDeploy.yml b/.github/workflows/platformDeploy.yml index 3c11a168f096..5575d05609f2 100644 --- a/.github/workflows/platformDeploy.yml +++ b/.github/workflows/platformDeploy.yml @@ -210,7 +210,11 @@ jobs: command: npm ci - name: Install cocoapods - run: cd ios && pod install + uses: nick-invision/retry@7c68161adf97a48beb850a595b8784ec57a98cbb + with: + timeout_minutes: 10 + max_attempts: 5 + command: cd ios && pod install - name: Decrypt profile run: cd ios && gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" --output chat_expensify_appstore.mobileprovision chat_expensify_appstore.mobileprovision.gpg From f251a443e2fab2dba93f804848f50486d69e0f86 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 18 May 2022 14:31:18 -0600 Subject: [PATCH 127/287] Simplify the ready state of active clients --- src/libs/ActiveClientManager/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/ActiveClientManager/index.js b/src/libs/ActiveClientManager/index.js index 661cc38fb777..7f0d4bf0cd91 100644 --- a/src/libs/ActiveClientManager/index.js +++ b/src/libs/ActiveClientManager/index.js @@ -3,22 +3,22 @@ import Onyx from 'react-native-onyx'; import Str from 'expensify-common/lib/str'; import ONYXKEYS from '../../ONYXKEYS'; import * as ActiveClients from '../actions/ActiveClients'; -import createOnReadyTask from '../createOnReadyTask'; const clientID = Str.guid(); const maxClients = 20; let activeClients; -// Keeps track of the ActiveClientManager's readiness in one place -// so that multiple calls of isReady resolve the same promise -const activeClientsReadyTask = createOnReadyTask(); +let resolveIsReadyPromise; +const isReadyPromise = new Promise((resolve) => { + resolveIsReadyPromise = resolve; +}); /** * @returns {Promise} */ function isReady() { - return activeClientsReadyTask.isReady(); + return isReadyPromise; } Onyx.connect({ @@ -37,7 +37,7 @@ Onyx.connect({ */ function init() { ActiveClients.addClient(clientID) - .then(activeClientsReadyTask.setIsReady); + .then(resolveIsReadyPromise); } /** From 558fae281b1de567a07967874d0c921a924f2b07 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Wed, 18 May 2022 14:41:45 -0600 Subject: [PATCH 128/287] Simplify the ready state of network store --- src/libs/Network/NetworkStore.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libs/Network/NetworkStore.js b/src/libs/Network/NetworkStore.js index 81fd59e4c8a8..8420d27f6667 100644 --- a/src/libs/Network/NetworkStore.js +++ b/src/libs/Network/NetworkStore.js @@ -3,7 +3,6 @@ import Onyx from 'react-native-onyx'; import _ from 'underscore'; import ONYXKEYS from '../../ONYXKEYS'; import createCallback from '../createCallback'; -import createOnReadyTask from '../createOnReadyTask'; let credentials; let authToken; @@ -12,7 +11,11 @@ let offline = false; let authenticating = false; const [triggerConnectivityResumed, onConnectivityResumed] = createCallback(); -const requiredDataReadyTask = createOnReadyTask(); + +let resolveIsReadyPromise; +let isReadyPromise = new Promise((resolve) => { + resolveIsReadyPromise = resolve; +}); /** * This is a hack to workaround the fact that Onyx may not yet have read these values from storage by the time Network starts processing requests. @@ -23,11 +26,14 @@ function checkRequiredData() { return; } - requiredDataReadyTask.setIsReady(); + resolveIsReadyPromise(); } function resetHasReadRequiredDataFromStorage() { - requiredDataReadyTask.reset(); + // Create a new promise and a new resolve function + isReadyPromise = new Promise((resolve) => { + resolveIsReadyPromise = resolve; + }); } Onyx.connect({ @@ -104,7 +110,7 @@ function getCurrentUserEmail() { * @returns {Promise} */ function hasReadRequiredDataFromStorage() { - return requiredDataReadyTask.isReady(); + return isReadyPromise; } /** From ce25fc7c05b1f87656d5931656d46814d2ba5161 Mon Sep 17 00:00:00 2001 From: Aneeque Ahmad Date: Thu, 19 May 2022 04:07:12 +0500 Subject: [PATCH 129/287] Feedback helping comment and refactoring --- src/pages/signin/SignInPageLayout/SignInPageContent.js | 2 +- src/styles/variables.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/signin/SignInPageLayout/SignInPageContent.js b/src/pages/signin/SignInPageLayout/SignInPageContent.js index 1a02c11c9f91..f22fddd4fcac 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageContent.js +++ b/src/pages/signin/SignInPageLayout/SignInPageContent.js @@ -55,7 +55,7 @@ const SignInPageContent = props => ( Date: Wed, 18 May 2022 21:11:48 -0300 Subject: [PATCH 130/287] attachment comment --- .../HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js index 14d529a8ab86..af05610fa8c7 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js @@ -40,6 +40,7 @@ const AnchorRenderer = (props) => { } // If we are handling an old dot Expensify link we need to open it with openOldDotLink() so we can navigate to it with the user already logged in. + // As we store attachments under expensify.com URL we don't want it working the same as links. if (internalExpensifyPath && !isAttachment) { return ( Date: Thu, 19 May 2022 12:07:12 +0000 Subject: [PATCH 131/287] remove focus from disabled buttons --- src/styles/styles.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/styles/styles.js b/src/styles/styles.js index dab500cd8db4..3c7cf217bbc8 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -2188,6 +2188,8 @@ const styles = { cursorDisabled: { cursor: 'not-allowed', + boxShadow: 'none', + outline: 'none', }, cursorPointer: { From 6e915724c4d7a27f378e6fd981ef9acb25623a5f Mon Sep 17 00:00:00 2001 From: Justice Arthur Date: Thu, 19 May 2022 12:45:01 +0000 Subject: [PATCH 132/287] remove focus from cancel button --- src/components/Button.js | 2 +- src/components/ConfirmContent.js | 2 +- src/styles/styles.js | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/Button.js b/src/components/Button.js index 85254d4c1e75..a315abc160fc 100644 --- a/src/components/Button.js +++ b/src/components/Button.js @@ -247,7 +247,7 @@ class Button extends Component { onPressOut={this.props.onPressOut} disabled={this.props.isLoading || this.props.isDisabled} style={[ - this.props.isDisabled ? styles.cursorDisabled : {}, + this.props.isDisabled ? {...styles.cursorDisabled, ...styles.noSelect} : {}, ...this.additionalStyles, ]} > diff --git a/src/components/ConfirmContent.js b/src/components/ConfirmContent.js index 78e01b756a61..164a21ce9a8e 100644 --- a/src/components/ConfirmContent.js +++ b/src/components/ConfirmContent.js @@ -76,7 +76,7 @@ const ConfirmContent = props => ( /> {props.shouldShowCancelButton && (