From d581791b319135fb1b0e88970473b9b3f5fd14f2 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Fri, 26 Mar 2021 18:18:16 +0000 Subject: [PATCH 01/32] Created IOU preview component within chat --- src/components/ReportActionItemIOUPreview.js | 44 +++++++++++++++++++ src/pages/home/report/ReportActionItem.js | 29 +++++++++++- .../home/report/ReportActionItemFragment.js | 11 +++++ .../home/report/ReportActionItemGrouped.js | 23 +++++++++- .../home/report/ReportActionItemMessage.js | 1 + .../home/report/ReportActionItemSingle.js | 23 +++++++++- src/pages/home/report/ReportActionsView.js | 18 +++++++- 7 files changed, 142 insertions(+), 7 deletions(-) create mode 100644 src/components/ReportActionItemIOUPreview.js diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js new file mode 100644 index 000000000000..11aa628a4c52 --- /dev/null +++ b/src/components/ReportActionItemIOUPreview.js @@ -0,0 +1,44 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; +import ONYXKEYS from '../ONYXKEYS'; +import ReportActionItemMessage from '../pages/home/report/ReportActionItemMessage'; +import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; + +const propTypes = { + // All the data of the action + action: PropTypes.shape(ReportActionPropTypes).isRequired, + + // Is this the most recent IOU Action? + isMostRecentIOUReport: PropTypes.bool.isRequired, + + // The report currently being looked at + report: PropTypes.shape({ + + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, + + /* --- Onyx Props --- */ + // TODO: Will define IOUPropTypes + // Active IOU Report for current report + // eslint-disable-next-line react/forbid-prop-types + iou: PropTypes.object.isRequired, + +}; + +const ReportActionItemIOUPreview = ({ + action, + isMostRecentIOUReport, + report, + iou, +}) => ( + +); + +ReportActionItemIOUPreview.propTypes = propTypes; +export default withOnyx({ + iou: { + key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, + }, +})(ReportActionItemIOUPreview); diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index a0d920a60185..8c8535cf9980 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -27,9 +27,19 @@ const propTypes = { // Should the comment have the appearance of being grouped with the previous comment? displayAsGroup: PropTypes.bool.isRequired, + // Is this the most recent IOU Action? + isMostRecentIOUReport: PropTypes.bool.isRequired, + /* --- Onyx Props --- */ // List of betas for the current user. betas: PropTypes.arrayOf(PropTypes.string), + + // The report currently being looked at + report: PropTypes.shape({ + + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, }; const defaultProps = { @@ -111,8 +121,20 @@ class ReportActionItem extends Component { {!this.props.displayAsGroup - ? - : } + ? ( + + ) + : ( + + )} `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + }, })(ReportActionItem); diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index a94cfebdb49c..827e5f6c87cb 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -19,6 +19,9 @@ const propTypes = { // Is this fragment an attachment? isAttachment: PropTypes.bool, + // Type of the current action + actionName: PropTypes.string, + // Does this fragment belong to a reportAction that has not yet loaded? loading: PropTypes.bool, }; @@ -27,6 +30,7 @@ const defaultProps = { isAttachment: false, loading: false, tooltipText: '', + actionName: '', }; class ReportActionItemFragment extends React.PureComponent { @@ -54,6 +58,13 @@ class ReportActionItemFragment extends React.PureComponent { {Str.htmlDecode(fragment.text)} ); case 'TEXT': + if (this.props.actionName === 'IOU') { + const viewDetails = '
View Details'; + const html = `
${fragment.text}${viewDetails}
`; + return ( + + ); + } return ( ( +const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( - + {action.actionName === 'IOU' + ? ( + + ) + : } ); diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index 121b2e2d3378..ad6a552d2a1f 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -19,6 +19,7 @@ const ReportActionItemMessage = ({action}) => ( fragment={fragment} isAttachment={action.isAttachment} loading={action.loading} + actionName={action.actionName} /> ))}
diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index bf40be5e8cda..1e894ab2a07a 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -9,13 +9,24 @@ import styles from '../../../styles/styles'; import CONST from '../../../CONST'; import ReportActionItemDate from './ReportActionItemDate'; import Avatar from '../../../components/Avatar'; +import ReportActionItemIOUPreview from '../../../components/ReportActionItemIOUPreview'; const propTypes = { // All the data of the action action: PropTypes.shape(ReportActionPropTypes).isRequired, + + // Is this the most recent IOU Action? + isMostRecentIOUReport: PropTypes.bool.isRequired, + + // The report currently being looked at + report: PropTypes.shape({ + + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, }; -const ReportActionItemSingle = ({action}) => { +const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { const avatarUrl = action.automatic ? `${CONST.CLOUDFRONT_URL}/images/icons/concierge_2019.svg` : action.avatar; @@ -38,7 +49,15 @@ const ReportActionItemSingle = ({action}) => { ))}
- + {action.actionName === 'IOU' + ? ( + + ) + : } ); diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index fc867be054d7..f140acb15bd2 100644 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -223,7 +223,7 @@ class ReportActionsView extends React.Component { updateSortedReportActions() { this.sortedReportActions = _.chain(this.props.reportActions) .sortBy('sequenceNumber') - .filter(action => action.actionName === 'ADDCOMMENT') + .filter(action => action.actionName === 'ADDCOMMENT' || action.actionName === 'IOU') .map((item, index) => ({action: item, index})) .value() .reverse(); @@ -278,6 +278,21 @@ class ReportActionsView extends React.Component { updateLastReadActionID(this.props.reportID, maxVisibleSequenceNumber); } + /** + * Checks whether given sequence number belongs to the most recent IOU Report + * + * @param {Number} actionSequenceNumber + * @returns {Boolean} + */ + isMostRecentIOUReport(actionSequenceNumber) { + const mostRecentIOUReportSequenceNumber = _.chain(this.props.reportActions) + .sortBy('sequenceNumber') + .filter(action => action.actionName === 'IOU') + .max(action => action.sequenceNumber) + .value().sequenceNumber; + return actionSequenceNumber === mostRecentIOUReportSequenceNumber; + } + /** * This function is triggered from the ref callback for the scrollview. That way it can be scrolled once all the * items have been rendered. If the number of actions has changed since it was last rendered, then @@ -344,6 +359,7 @@ class ReportActionsView extends React.Component { displayAsGroup={this.isConsecutiveActionMadeByPreviousActor(index)} onLayout={onLayout} needsLayoutCalculation={needsLayoutCalculation} + isMostRecentIOUReport={this.isMostRecentIOUReport(item.action.sequenceNumber)} /> ); From 1e7a1c9c7da86ef4236dee71fe3f8c8c28babb6b Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Sun, 28 Mar 2021 16:17:50 +0100 Subject: [PATCH 02/32] Added ReportActionItemIOUQuote component --- src/components/ReportActionItemIOUPreview.js | 7 +++-- src/components/ReportActionItemIOUQuote.js | 30 +++++++++++++++++++ .../home/report/ReportActionItemFragment.js | 11 ------- .../home/report/ReportActionItemMessage.js | 1 - 4 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 src/components/ReportActionItemIOUQuote.js diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index 11aa628a4c52..ddfd6830f7bd 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import ONYXKEYS from '../ONYXKEYS'; -import ReportActionItemMessage from '../pages/home/report/ReportActionItemMessage'; +import ReportActionItemIOUQuote from './ReportActionItemIOUQuote'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; const propTypes = { @@ -24,7 +24,6 @@ const propTypes = { // Active IOU Report for current report // eslint-disable-next-line react/forbid-prop-types iou: PropTypes.object.isRequired, - }; const ReportActionItemIOUPreview = ({ @@ -33,10 +32,12 @@ const ReportActionItemIOUPreview = ({ report, iou, }) => ( - + ); ReportActionItemIOUPreview.propTypes = propTypes; +ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview'; + export default withOnyx({ iou: { key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, diff --git a/src/components/ReportActionItemIOUQuote.js b/src/components/ReportActionItemIOUQuote.js new file mode 100644 index 000000000000..a190309d6c94 --- /dev/null +++ b/src/components/ReportActionItemIOUQuote.js @@ -0,0 +1,30 @@ +import React from 'react'; +import {View} from 'react-native'; +import PropTypes from 'prop-types'; +import _ from 'underscore'; +import styles from '../styles/styles'; +import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; +import RenderHTML from './RenderHTML'; + +const propTypes = { + // All the data of the action + action: PropTypes.shape(ReportActionPropTypes).isRequired, + +}; +const ReportActionItemIOUQuote = ({action}) => ( + + {_.map(_.compact(action.message), (fragment, index) => { + const viewDetails = '
View Details'; + const html = `
${fragment.text}${viewDetails}
`; + return ( + + ); + })} +
+ +); + +ReportActionItemIOUQuote.propTypes = propTypes; +ReportActionItemIOUQuote.displayName = 'ReportActionItemIOUQuote'; + +export default ReportActionItemIOUQuote; diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 827e5f6c87cb..a94cfebdb49c 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -19,9 +19,6 @@ const propTypes = { // Is this fragment an attachment? isAttachment: PropTypes.bool, - // Type of the current action - actionName: PropTypes.string, - // Does this fragment belong to a reportAction that has not yet loaded? loading: PropTypes.bool, }; @@ -30,7 +27,6 @@ const defaultProps = { isAttachment: false, loading: false, tooltipText: '', - actionName: '', }; class ReportActionItemFragment extends React.PureComponent { @@ -58,13 +54,6 @@ class ReportActionItemFragment extends React.PureComponent { {Str.htmlDecode(fragment.text)} ); case 'TEXT': - if (this.props.actionName === 'IOU') { - const viewDetails = '
View Details'; - const html = `
${fragment.text}${viewDetails}
`; - return ( - - ); - } return ( ( fragment={fragment} isAttachment={action.isAttachment} loading={action.loading} - actionName={action.actionName} /> ))} From 095aad99185dcef2e9606bad1b8a2a6aca940161 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Tue, 30 Mar 2021 17:53:01 +0100 Subject: [PATCH 03/32] Added IOU Preview UI --- src/components/ReportActionItemIOUPreview.js | 156 +++++++++++++++--- src/components/ReportActionItemIOUQuote.js | 7 +- src/pages/home/report/ReportActionItem.js | 4 +- .../home/report/ReportActionItemGrouped.js | 15 +- .../home/report/ReportActionItemSingle.js | 15 +- src/styles/styles.js | 15 ++ 6 files changed, 172 insertions(+), 40 deletions(-) diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index ddfd6830f7bd..481de53c26e9 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -1,9 +1,20 @@ import React from 'react'; +import {View, TouchableOpacity} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; +import lodashGet from 'lodash/get'; import ONYXKEYS from '../ONYXKEYS'; import ReportActionItemIOUQuote from './ReportActionItemIOUQuote'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; +import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions'; +import Text from './Text'; +import MultipleAvatars from './MultipleAvatars'; +import styles from '../styles/styles'; + +const personalDetailsPropTypes = PropTypes.shape({ + // This is either the user's full name, or their login if full name is an empty string + displayName: PropTypes.string.isRequired, +}); const propTypes = { // All the data of the action @@ -12,34 +23,139 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // The report currently being looked at - report: PropTypes.shape({ - - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }).isRequired, + /* Window Dimensions Props */ + ...windowDimensionsPropTypes, /* --- Onyx Props --- */ - // TODO: Will define IOUPropTypes // Active IOU Report for current report - // eslint-disable-next-line react/forbid-prop-types - iou: PropTypes.object.isRequired, + iou: PropTypes.shape({ + // Email address of the manager in this iou report + managerEmail: PropTypes.string, + + // Email address of the creator of this iou report + ownerEmail: PropTypes.string, + + // Outstanding amount of this transaction + cachedTotal: PropTypes.string, + }), + + // All of the personal details for everyone + personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired, + + // Session info for the currently logged in user. + session: PropTypes.shape({ + // Currently logged in user email + email: PropTypes.string, + }).isRequired, }; -const ReportActionItemIOUPreview = ({ - action, - isMostRecentIOUReport, - report, - iou, -}) => ( - -); +const defaultProps = { + iou: null, +}; + +class ReportActionItemIOUPreview extends React.Component { + /** + * Creates IOU preview pay button. + * + * @returns {View} + */ + createPayButton() { + return ( + + + Pay + + + ); + } + + /** + * Creates IOU preview box view if outstanding amount is not 0. + * + * @returns {View} + */ + createPreviewBox() { + const managerName = lodashGet( + this.props.personalDetails, + [this.props.iou.managerEmail, 'displayName'], + this.props.iou.managerEmail, + ); + const ownerName = lodashGet( + this.props.personalDetails, + [this.props.iou.ownerEmail, 'displayName'], + this.props.iou.ownerEmail, + ); + const managerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.managerEmail, 'avatar'], ''); + const ownerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.ownerEmail, 'avatar'], ''); + const sessionEmail = lodashGet(this.props.session, 'email', null); + const cachedTotal = this.props.iou.cachedTotal.replace(/[()]/g, ''); + const amount = Number(cachedTotal.substring(1)); + + if (amount === 0) { + return null; + } + + return ( + + + + {cachedTotal} + + {managerName} + {' owes '} + {ownerName} + + + + + {(this.props.iou.managerEmail === sessionEmail) ? ( + this.createPayButton() + ) + : null} + + ); + } + + render() { + return ( + + + {this.props.isMostRecentIOUReport && this.props.iou ? ( + this.createPreviewBox() + ) + : null} + + ); + } +} ReportActionItemIOUPreview.propTypes = propTypes; +ReportActionItemIOUPreview.defaultProps = defaultProps; ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview'; -export default withOnyx({ +export default withWindowDimensions(withOnyx({ iou: { - key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, + key: ({iouReportID}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportID}`, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS, + }, + session: { + key: ONYXKEYS.SESSION, }, -})(ReportActionItemIOUPreview); +})(ReportActionItemIOUPreview)); diff --git a/src/components/ReportActionItemIOUQuote.js b/src/components/ReportActionItemIOUQuote.js index a190309d6c94..60be313f80f4 100644 --- a/src/components/ReportActionItemIOUQuote.js +++ b/src/components/ReportActionItemIOUQuote.js @@ -9,19 +9,18 @@ import RenderHTML from './RenderHTML'; const propTypes = { // All the data of the action action: PropTypes.shape(ReportActionPropTypes).isRequired, - }; + const ReportActionItemIOUQuote = ({action}) => ( {_.map(_.compact(action.message), (fragment, index) => { - const viewDetails = '
View Details'; + const viewDetails = '
View Details'; const html = `
${fragment.text}${viewDetails}
`; return ( - + ); })}
- ); ReportActionItemIOUQuote.propTypes = propTypes; diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 8c8535cf9980..6b9b4e1186da 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -124,14 +124,14 @@ class ReportActionItem extends Component { ? ( ) : ( )} diff --git a/src/pages/home/report/ReportActionItemGrouped.js b/src/pages/home/report/ReportActionItemGrouped.js index f31683039d28..fd9942eaa2dd 100644 --- a/src/pages/home/report/ReportActionItemGrouped.js +++ b/src/pages/home/report/ReportActionItemGrouped.js @@ -13,21 +13,21 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // The report currently being looked at - report: PropTypes.shape({ + // IOU report ID associated with current report + iouReportID: PropTypes.number, +}; - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }).isRequired, +const defaultProps = { + iouReportID: null, }; -const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( +const ReportActionItemGrouped = ({action, iouReportID, isMostRecentIOUReport}) => ( {action.actionName === 'IOU' ? ( @@ -38,4 +38,5 @@ const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( ); ReportActionItemGrouped.propTypes = propTypes; +ReportActionItemGrouped.defaultProps = defaultProps; export default ReportActionItemGrouped; diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 1e894ab2a07a..e920565afc45 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -18,15 +18,15 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // The report currently being looked at - report: PropTypes.shape({ + // IOU report ID associated with current report + iouReportID: PropTypes.number, +}; - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }).isRequired, +const defaultProps = { + iouReportID: null, }; -const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { +const ReportActionItemSingle = ({action, iouReportID, isMostRecentIOUReport}) => { const avatarUrl = action.automatic ? `${CONST.CLOUDFRONT_URL}/images/icons/concierge_2019.svg` : action.avatar; @@ -52,7 +52,7 @@ const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { {action.actionName === 'IOU' ? ( @@ -64,4 +64,5 @@ const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { }; ReportActionItemSingle.propTypes = propTypes; +ReportActionItemSingle.defaultProps = defaultProps; export default ReportActionItemSingle; diff --git a/src/styles/styles.js b/src/styles/styles.js index 9a55ef7a7d34..0fcb178236dc 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -128,6 +128,9 @@ const styles = { buttonSmallText: { fontSize: variables.fontSizeSmall, lineHeight: 16, + fontFamily: fontFamily.GTA_BOLD, + fontWeight: fontWeightBold, + textAlign: 'center', }, buttonSuccess: { @@ -1237,6 +1240,18 @@ const styles = { fontWeight: fontWeightBold, fontSize: variables.iouAmountTextSize, }, 0), + + iouPreviewBox: { + borderColor: themeColors.border, + borderWidth: 1, + borderRadius: variables.componentBorderRadiusNormal, + padding: 15, + marginTop: 15, + }, + + normalRadius: { + borderRadius: variables.componentBorderRadius, + }, }; const baseCodeTagStyles = { From 8b2a0b48fe33cc49240a9ba6bd04a71766b29692 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Wed, 31 Mar 2021 21:52:01 +0100 Subject: [PATCH 04/32] Fixed live update issues and addressing comments --- src/components/ReportActionItemIOUPreview.js | 45 ++++++++++--------- src/libs/actions/Report.js | 1 + src/pages/home/report/ReportActionItem.js | 7 +-- .../home/report/ReportActionItemGrouped.js | 15 +++---- .../home/report/ReportActionItemSingle.js | 15 +++---- src/styles/styles.js | 5 +++ 6 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index 481de53c26e9..09bd6f9128de 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -11,11 +11,6 @@ import Text from './Text'; import MultipleAvatars from './MultipleAvatars'; import styles from '../styles/styles'; -const personalDetailsPropTypes = PropTypes.shape({ - // This is either the user's full name, or their login if full name is an empty string - displayName: PropTypes.string.isRequired, -}); - const propTypes = { // All the data of the action action: PropTypes.shape(ReportActionPropTypes).isRequired, @@ -23,6 +18,16 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, + // The report currently being looked at + report: PropTypes.shape({ + + // IOU report ID associated with current report + iouReportID: PropTypes.number, + + // Whether there is an outstanding amount in IOU + hasOutstandingIOU: PropTypes.bool, + }).isRequired, + /* Window Dimensions Props */ ...windowDimensionsPropTypes, @@ -40,7 +45,11 @@ const propTypes = { }), // All of the personal details for everyone - personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired, + personalDetails: PropTypes.objectOf(PropTypes.shape({ + + // This is either the user's full name, or their login if full name is an empty string + displayName: PropTypes.string.isRequired, + })).isRequired, // Session info for the currently logged in user. session: PropTypes.shape({ @@ -50,7 +59,7 @@ const propTypes = { }; const defaultProps = { - iou: null, + iou: {}, }; class ReportActionItemIOUPreview extends React.Component { @@ -96,11 +105,6 @@ class ReportActionItemIOUPreview extends React.Component { const ownerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.ownerEmail, 'avatar'], ''); const sessionEmail = lodashGet(this.props.session, 'email', null); const cachedTotal = this.props.iou.cachedTotal.replace(/[()]/g, ''); - const amount = Number(cachedTotal.substring(1)); - - if (amount === 0) { - return null; - } return ( @@ -115,12 +119,7 @@ class ReportActionItemIOUPreview extends React.Component { {(this.props.iou.managerEmail === sessionEmail) ? ( @@ -135,9 +134,11 @@ class ReportActionItemIOUPreview extends React.Component { return ( - {this.props.isMostRecentIOUReport && this.props.iou ? ( - this.createPreviewBox() - ) + {this.props.isMostRecentIOUReport + && this.props.report.hasOutstandingIOU + && this.props.iou ? ( + this.createPreviewBox() + ) : null} ); @@ -150,7 +151,7 @@ ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview'; export default withWindowDimensions(withOnyx({ iou: { - key: ({iouReportID}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportID}`, + key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, }, personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 11e6709e2176..be8f72096181 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -307,6 +307,7 @@ function fetchChatReportsByIDs(chatList) { simplifiedReports[reportKey].iouReportID = iouReportObject.reportID; simplifiedReports[reportKey].hasOutstandingIOU = iouReportObject.stateNum === 1 && iouReportObject.total !== 0; + Onyx.merge(iouReportKey, iouReportObject); }); // We use mergeCollection such that it updates the collection in one go. diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 6b9b4e1186da..b0be7a629519 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -68,7 +68,8 @@ class ReportActionItem extends Component { shouldComponentUpdate(nextProps, nextState) { return this.state.isPopoverVisible !== nextState.isPopoverVisible || this.props.displayAsGroup !== nextProps.displayAsGroup - || !_.isEqual(this.props.action, nextProps.action); + || !_.isEqual(this.props.action, nextProps.action) + || this.props.isMostRecentIOUReport !== nextProps.isMostRecentIOUReport; } /** @@ -124,14 +125,14 @@ class ReportActionItem extends Component { ? ( ) : ( )} diff --git a/src/pages/home/report/ReportActionItemGrouped.js b/src/pages/home/report/ReportActionItemGrouped.js index fd9942eaa2dd..f31683039d28 100644 --- a/src/pages/home/report/ReportActionItemGrouped.js +++ b/src/pages/home/report/ReportActionItemGrouped.js @@ -13,21 +13,21 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // IOU report ID associated with current report - iouReportID: PropTypes.number, -}; + // The report currently being looked at + report: PropTypes.shape({ -const defaultProps = { - iouReportID: null, + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, }; -const ReportActionItemGrouped = ({action, iouReportID, isMostRecentIOUReport}) => ( +const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( {action.actionName === 'IOU' ? ( @@ -38,5 +38,4 @@ const ReportActionItemGrouped = ({action, iouReportID, isMostRecentIOUReport}) = ); ReportActionItemGrouped.propTypes = propTypes; -ReportActionItemGrouped.defaultProps = defaultProps; export default ReportActionItemGrouped; diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index e920565afc45..1e894ab2a07a 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -18,15 +18,15 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // IOU report ID associated with current report - iouReportID: PropTypes.number, -}; + // The report currently being looked at + report: PropTypes.shape({ -const defaultProps = { - iouReportID: null, + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, }; -const ReportActionItemSingle = ({action, iouReportID, isMostRecentIOUReport}) => { +const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { const avatarUrl = action.automatic ? `${CONST.CLOUDFRONT_URL}/images/icons/concierge_2019.svg` : action.avatar; @@ -52,7 +52,7 @@ const ReportActionItemSingle = ({action, iouReportID, isMostRecentIOUReport}) => {action.actionName === 'IOU' ? ( @@ -64,5 +64,4 @@ const ReportActionItemSingle = ({action, iouReportID, isMostRecentIOUReport}) => }; ReportActionItemSingle.propTypes = propTypes; -ReportActionItemSingle.defaultProps = defaultProps; export default ReportActionItemSingle; diff --git a/src/styles/styles.js b/src/styles/styles.js index 0fcb178236dc..6c0c8bf9e059 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -884,6 +884,11 @@ const styles = { borderColor: 'transparent', }, + secondAvatarInline: { + bottom: -3, + right: -25, + }, + avatarNormal: { height: variables.componentSizeNormal, width: variables.componentSizeNormal, From b04df47297a614a5bce57a34f89ee8b7ae1f69ce Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Fri, 26 Mar 2021 18:18:16 +0000 Subject: [PATCH 05/32] Created IOU preview component within chat --- src/components/ReportActionItemIOUPreview.js | 44 +++++++++++++++++++ src/pages/home/report/ReportActionItem.js | 29 +++++++++++- .../home/report/ReportActionItemFragment.js | 11 +++++ .../home/report/ReportActionItemGrouped.js | 23 +++++++++- .../home/report/ReportActionItemMessage.js | 1 + .../home/report/ReportActionItemSingle.js | 23 +++++++++- src/pages/home/report/ReportActionsView.js | 16 +++++++ 7 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 src/components/ReportActionItemIOUPreview.js diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js new file mode 100644 index 000000000000..11aa628a4c52 --- /dev/null +++ b/src/components/ReportActionItemIOUPreview.js @@ -0,0 +1,44 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; +import ONYXKEYS from '../ONYXKEYS'; +import ReportActionItemMessage from '../pages/home/report/ReportActionItemMessage'; +import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; + +const propTypes = { + // All the data of the action + action: PropTypes.shape(ReportActionPropTypes).isRequired, + + // Is this the most recent IOU Action? + isMostRecentIOUReport: PropTypes.bool.isRequired, + + // The report currently being looked at + report: PropTypes.shape({ + + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, + + /* --- Onyx Props --- */ + // TODO: Will define IOUPropTypes + // Active IOU Report for current report + // eslint-disable-next-line react/forbid-prop-types + iou: PropTypes.object.isRequired, + +}; + +const ReportActionItemIOUPreview = ({ + action, + isMostRecentIOUReport, + report, + iou, +}) => ( + +); + +ReportActionItemIOUPreview.propTypes = propTypes; +export default withOnyx({ + iou: { + key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, + }, +})(ReportActionItemIOUPreview); diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index c40efa8d516d..e8b6ec02e254 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -27,9 +27,19 @@ const propTypes = { // Should the comment have the appearance of being grouped with the previous comment? displayAsGroup: PropTypes.bool.isRequired, + // Is this the most recent IOU Action? + isMostRecentIOUReport: PropTypes.bool.isRequired, + /* --- Onyx Props --- */ // List of betas for the current user. betas: PropTypes.arrayOf(PropTypes.string), + + // The report currently being looked at + report: PropTypes.shape({ + + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, }; const defaultProps = { @@ -111,8 +121,20 @@ class ReportActionItem extends Component { {!this.props.displayAsGroup - ? - : } + ? ( + + ) + : ( + + )} `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + }, })(ReportActionItem); diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index a94cfebdb49c..827e5f6c87cb 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -19,6 +19,9 @@ const propTypes = { // Is this fragment an attachment? isAttachment: PropTypes.bool, + // Type of the current action + actionName: PropTypes.string, + // Does this fragment belong to a reportAction that has not yet loaded? loading: PropTypes.bool, }; @@ -27,6 +30,7 @@ const defaultProps = { isAttachment: false, loading: false, tooltipText: '', + actionName: '', }; class ReportActionItemFragment extends React.PureComponent { @@ -54,6 +58,13 @@ class ReportActionItemFragment extends React.PureComponent { {Str.htmlDecode(fragment.text)} ); case 'TEXT': + if (this.props.actionName === 'IOU') { + const viewDetails = '
View Details'; + const html = `
${fragment.text}${viewDetails}
`; + return ( + + ); + } return ( ( +const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( - + {action.actionName === 'IOU' + ? ( + + ) + : } ); diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index 121b2e2d3378..ad6a552d2a1f 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -19,6 +19,7 @@ const ReportActionItemMessage = ({action}) => ( fragment={fragment} isAttachment={action.isAttachment} loading={action.loading} + actionName={action.actionName} /> ))}
diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index bf40be5e8cda..1e894ab2a07a 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -9,13 +9,24 @@ import styles from '../../../styles/styles'; import CONST from '../../../CONST'; import ReportActionItemDate from './ReportActionItemDate'; import Avatar from '../../../components/Avatar'; +import ReportActionItemIOUPreview from '../../../components/ReportActionItemIOUPreview'; const propTypes = { // All the data of the action action: PropTypes.shape(ReportActionPropTypes).isRequired, + + // Is this the most recent IOU Action? + isMostRecentIOUReport: PropTypes.bool.isRequired, + + // The report currently being looked at + report: PropTypes.shape({ + + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, }; -const ReportActionItemSingle = ({action}) => { +const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { const avatarUrl = action.automatic ? `${CONST.CLOUDFRONT_URL}/images/icons/concierge_2019.svg` : action.avatar; @@ -38,7 +49,15 @@ const ReportActionItemSingle = ({action}) => { ))}
- + {action.actionName === 'IOU' + ? ( + + ) + : }
); diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 708130ac689f..418dfaa5240e 100644 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -278,6 +278,21 @@ class ReportActionsView extends React.Component { updateLastReadActionID(this.props.reportID, maxVisibleSequenceNumber); } + /** + * Checks whether given sequence number belongs to the most recent IOU Report + * + * @param {Number} actionSequenceNumber + * @returns {Boolean} + */ + isMostRecentIOUReport(actionSequenceNumber) { + const mostRecentIOUReportSequenceNumber = _.chain(this.props.reportActions) + .sortBy('sequenceNumber') + .filter(action => action.actionName === 'IOU') + .max(action => action.sequenceNumber) + .value().sequenceNumber; + return actionSequenceNumber === mostRecentIOUReportSequenceNumber; + } + /** * This function is triggered from the ref callback for the scrollview. That way it can be scrolled once all the * items have been rendered. If the number of actions has changed since it was last rendered, then @@ -344,6 +359,7 @@ class ReportActionsView extends React.Component { displayAsGroup={this.isConsecutiveActionMadeByPreviousActor(index)} onLayout={onLayout} needsLayoutCalculation={needsLayoutCalculation} + isMostRecentIOUReport={this.isMostRecentIOUReport(item.action.sequenceNumber)} />
); From 6870e6950149b25a1ce9083ff6d0a43d68a27394 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Sun, 28 Mar 2021 16:17:50 +0100 Subject: [PATCH 06/32] Added ReportActionItemIOUQuote component --- src/components/ReportActionItemIOUPreview.js | 7 +++-- src/components/ReportActionItemIOUQuote.js | 30 +++++++++++++++++++ .../home/report/ReportActionItemFragment.js | 11 ------- .../home/report/ReportActionItemMessage.js | 1 - 4 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 src/components/ReportActionItemIOUQuote.js diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index 11aa628a4c52..ddfd6830f7bd 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import ONYXKEYS from '../ONYXKEYS'; -import ReportActionItemMessage from '../pages/home/report/ReportActionItemMessage'; +import ReportActionItemIOUQuote from './ReportActionItemIOUQuote'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; const propTypes = { @@ -24,7 +24,6 @@ const propTypes = { // Active IOU Report for current report // eslint-disable-next-line react/forbid-prop-types iou: PropTypes.object.isRequired, - }; const ReportActionItemIOUPreview = ({ @@ -33,10 +32,12 @@ const ReportActionItemIOUPreview = ({ report, iou, }) => ( - + ); ReportActionItemIOUPreview.propTypes = propTypes; +ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview'; + export default withOnyx({ iou: { key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, diff --git a/src/components/ReportActionItemIOUQuote.js b/src/components/ReportActionItemIOUQuote.js new file mode 100644 index 000000000000..a190309d6c94 --- /dev/null +++ b/src/components/ReportActionItemIOUQuote.js @@ -0,0 +1,30 @@ +import React from 'react'; +import {View} from 'react-native'; +import PropTypes from 'prop-types'; +import _ from 'underscore'; +import styles from '../styles/styles'; +import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; +import RenderHTML from './RenderHTML'; + +const propTypes = { + // All the data of the action + action: PropTypes.shape(ReportActionPropTypes).isRequired, + +}; +const ReportActionItemIOUQuote = ({action}) => ( + + {_.map(_.compact(action.message), (fragment, index) => { + const viewDetails = '
View Details'; + const html = `
${fragment.text}${viewDetails}
`; + return ( + + ); + })} +
+ +); + +ReportActionItemIOUQuote.propTypes = propTypes; +ReportActionItemIOUQuote.displayName = 'ReportActionItemIOUQuote'; + +export default ReportActionItemIOUQuote; diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 827e5f6c87cb..a94cfebdb49c 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -19,9 +19,6 @@ const propTypes = { // Is this fragment an attachment? isAttachment: PropTypes.bool, - // Type of the current action - actionName: PropTypes.string, - // Does this fragment belong to a reportAction that has not yet loaded? loading: PropTypes.bool, }; @@ -30,7 +27,6 @@ const defaultProps = { isAttachment: false, loading: false, tooltipText: '', - actionName: '', }; class ReportActionItemFragment extends React.PureComponent { @@ -58,13 +54,6 @@ class ReportActionItemFragment extends React.PureComponent { {Str.htmlDecode(fragment.text)} ); case 'TEXT': - if (this.props.actionName === 'IOU') { - const viewDetails = '
View Details'; - const html = `
${fragment.text}${viewDetails}
`; - return ( - - ); - } return ( ( fragment={fragment} isAttachment={action.isAttachment} loading={action.loading} - actionName={action.actionName} /> ))} From 8bc24d20699c958141c6cc3f4c86e0ac7d0d31a2 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Tue, 30 Mar 2021 17:53:01 +0100 Subject: [PATCH 07/32] Added IOU Preview UI --- src/components/ReportActionItemIOUPreview.js | 156 +++++++++++++++--- src/components/ReportActionItemIOUQuote.js | 7 +- src/pages/home/report/ReportActionItem.js | 4 +- .../home/report/ReportActionItemGrouped.js | 15 +- .../home/report/ReportActionItemSingle.js | 15 +- src/styles/styles.js | 15 ++ 6 files changed, 172 insertions(+), 40 deletions(-) diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index ddfd6830f7bd..481de53c26e9 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -1,9 +1,20 @@ import React from 'react'; +import {View, TouchableOpacity} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; +import lodashGet from 'lodash/get'; import ONYXKEYS from '../ONYXKEYS'; import ReportActionItemIOUQuote from './ReportActionItemIOUQuote'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; +import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions'; +import Text from './Text'; +import MultipleAvatars from './MultipleAvatars'; +import styles from '../styles/styles'; + +const personalDetailsPropTypes = PropTypes.shape({ + // This is either the user's full name, or their login if full name is an empty string + displayName: PropTypes.string.isRequired, +}); const propTypes = { // All the data of the action @@ -12,34 +23,139 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // The report currently being looked at - report: PropTypes.shape({ - - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }).isRequired, + /* Window Dimensions Props */ + ...windowDimensionsPropTypes, /* --- Onyx Props --- */ - // TODO: Will define IOUPropTypes // Active IOU Report for current report - // eslint-disable-next-line react/forbid-prop-types - iou: PropTypes.object.isRequired, + iou: PropTypes.shape({ + // Email address of the manager in this iou report + managerEmail: PropTypes.string, + + // Email address of the creator of this iou report + ownerEmail: PropTypes.string, + + // Outstanding amount of this transaction + cachedTotal: PropTypes.string, + }), + + // All of the personal details for everyone + personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired, + + // Session info for the currently logged in user. + session: PropTypes.shape({ + // Currently logged in user email + email: PropTypes.string, + }).isRequired, }; -const ReportActionItemIOUPreview = ({ - action, - isMostRecentIOUReport, - report, - iou, -}) => ( - -); +const defaultProps = { + iou: null, +}; + +class ReportActionItemIOUPreview extends React.Component { + /** + * Creates IOU preview pay button. + * + * @returns {View} + */ + createPayButton() { + return ( + + + Pay + + + ); + } + + /** + * Creates IOU preview box view if outstanding amount is not 0. + * + * @returns {View} + */ + createPreviewBox() { + const managerName = lodashGet( + this.props.personalDetails, + [this.props.iou.managerEmail, 'displayName'], + this.props.iou.managerEmail, + ); + const ownerName = lodashGet( + this.props.personalDetails, + [this.props.iou.ownerEmail, 'displayName'], + this.props.iou.ownerEmail, + ); + const managerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.managerEmail, 'avatar'], ''); + const ownerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.ownerEmail, 'avatar'], ''); + const sessionEmail = lodashGet(this.props.session, 'email', null); + const cachedTotal = this.props.iou.cachedTotal.replace(/[()]/g, ''); + const amount = Number(cachedTotal.substring(1)); + + if (amount === 0) { + return null; + } + + return ( + + + + {cachedTotal} + + {managerName} + {' owes '} + {ownerName} + + + + + {(this.props.iou.managerEmail === sessionEmail) ? ( + this.createPayButton() + ) + : null} + + ); + } + + render() { + return ( + + + {this.props.isMostRecentIOUReport && this.props.iou ? ( + this.createPreviewBox() + ) + : null} + + ); + } +} ReportActionItemIOUPreview.propTypes = propTypes; +ReportActionItemIOUPreview.defaultProps = defaultProps; ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview'; -export default withOnyx({ +export default withWindowDimensions(withOnyx({ iou: { - key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, + key: ({iouReportID}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportID}`, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS, + }, + session: { + key: ONYXKEYS.SESSION, }, -})(ReportActionItemIOUPreview); +})(ReportActionItemIOUPreview)); diff --git a/src/components/ReportActionItemIOUQuote.js b/src/components/ReportActionItemIOUQuote.js index a190309d6c94..60be313f80f4 100644 --- a/src/components/ReportActionItemIOUQuote.js +++ b/src/components/ReportActionItemIOUQuote.js @@ -9,19 +9,18 @@ import RenderHTML from './RenderHTML'; const propTypes = { // All the data of the action action: PropTypes.shape(ReportActionPropTypes).isRequired, - }; + const ReportActionItemIOUQuote = ({action}) => ( {_.map(_.compact(action.message), (fragment, index) => { - const viewDetails = '
View Details'; + const viewDetails = '
View Details'; const html = `
${fragment.text}${viewDetails}
`; return ( - + ); })}
- ); ReportActionItemIOUQuote.propTypes = propTypes; diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index e8b6ec02e254..06ba787dc679 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -124,14 +124,14 @@ class ReportActionItem extends Component { ? ( ) : ( )} diff --git a/src/pages/home/report/ReportActionItemGrouped.js b/src/pages/home/report/ReportActionItemGrouped.js index f31683039d28..fd9942eaa2dd 100644 --- a/src/pages/home/report/ReportActionItemGrouped.js +++ b/src/pages/home/report/ReportActionItemGrouped.js @@ -13,21 +13,21 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // The report currently being looked at - report: PropTypes.shape({ + // IOU report ID associated with current report + iouReportID: PropTypes.number, +}; - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }).isRequired, +const defaultProps = { + iouReportID: null, }; -const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( +const ReportActionItemGrouped = ({action, iouReportID, isMostRecentIOUReport}) => ( {action.actionName === 'IOU' ? ( @@ -38,4 +38,5 @@ const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( ); ReportActionItemGrouped.propTypes = propTypes; +ReportActionItemGrouped.defaultProps = defaultProps; export default ReportActionItemGrouped; diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 1e894ab2a07a..e920565afc45 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -18,15 +18,15 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // The report currently being looked at - report: PropTypes.shape({ + // IOU report ID associated with current report + iouReportID: PropTypes.number, +}; - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }).isRequired, +const defaultProps = { + iouReportID: null, }; -const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { +const ReportActionItemSingle = ({action, iouReportID, isMostRecentIOUReport}) => { const avatarUrl = action.automatic ? `${CONST.CLOUDFRONT_URL}/images/icons/concierge_2019.svg` : action.avatar; @@ -52,7 +52,7 @@ const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { {action.actionName === 'IOU' ? ( @@ -64,4 +64,5 @@ const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { }; ReportActionItemSingle.propTypes = propTypes; +ReportActionItemSingle.defaultProps = defaultProps; export default ReportActionItemSingle; diff --git a/src/styles/styles.js b/src/styles/styles.js index 22b13cd5e8db..149f9204146e 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -128,6 +128,9 @@ const styles = { buttonSmallText: { fontSize: variables.fontSizeSmall, lineHeight: 16, + fontFamily: fontFamily.GTA_BOLD, + fontWeight: fontWeightBold, + textAlign: 'center', }, buttonSuccess: { @@ -1256,6 +1259,18 @@ const styles = { fontSize: variables.iouAmountTextSize, }, 0), + iouPreviewBox: { + borderColor: themeColors.border, + borderWidth: 1, + borderRadius: variables.componentBorderRadiusNormal, + padding: 15, + marginTop: 15, + }, + + normalRadius: { + borderRadius: variables.componentBorderRadius, + }, + noScrollbars: { scrollbarWidth: 'none', }, From 5f68df7f1c5b6290714daac104f6bbfdfd0e2e70 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Wed, 31 Mar 2021 21:52:01 +0100 Subject: [PATCH 08/32] Fixed live update issues and addressing comments --- src/components/ReportActionItemIOUPreview.js | 45 ++++++++++--------- src/libs/actions/Report.js | 1 + src/pages/home/report/ReportActionItem.js | 7 +-- .../home/report/ReportActionItemGrouped.js | 15 +++---- .../home/report/ReportActionItemSingle.js | 15 +++---- src/styles/styles.js | 5 +++ 6 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index 481de53c26e9..09bd6f9128de 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -11,11 +11,6 @@ import Text from './Text'; import MultipleAvatars from './MultipleAvatars'; import styles from '../styles/styles'; -const personalDetailsPropTypes = PropTypes.shape({ - // This is either the user's full name, or their login if full name is an empty string - displayName: PropTypes.string.isRequired, -}); - const propTypes = { // All the data of the action action: PropTypes.shape(ReportActionPropTypes).isRequired, @@ -23,6 +18,16 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, + // The report currently being looked at + report: PropTypes.shape({ + + // IOU report ID associated with current report + iouReportID: PropTypes.number, + + // Whether there is an outstanding amount in IOU + hasOutstandingIOU: PropTypes.bool, + }).isRequired, + /* Window Dimensions Props */ ...windowDimensionsPropTypes, @@ -40,7 +45,11 @@ const propTypes = { }), // All of the personal details for everyone - personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired, + personalDetails: PropTypes.objectOf(PropTypes.shape({ + + // This is either the user's full name, or their login if full name is an empty string + displayName: PropTypes.string.isRequired, + })).isRequired, // Session info for the currently logged in user. session: PropTypes.shape({ @@ -50,7 +59,7 @@ const propTypes = { }; const defaultProps = { - iou: null, + iou: {}, }; class ReportActionItemIOUPreview extends React.Component { @@ -96,11 +105,6 @@ class ReportActionItemIOUPreview extends React.Component { const ownerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.ownerEmail, 'avatar'], ''); const sessionEmail = lodashGet(this.props.session, 'email', null); const cachedTotal = this.props.iou.cachedTotal.replace(/[()]/g, ''); - const amount = Number(cachedTotal.substring(1)); - - if (amount === 0) { - return null; - } return ( @@ -115,12 +119,7 @@ class ReportActionItemIOUPreview extends React.Component { {(this.props.iou.managerEmail === sessionEmail) ? ( @@ -135,9 +134,11 @@ class ReportActionItemIOUPreview extends React.Component { return ( - {this.props.isMostRecentIOUReport && this.props.iou ? ( - this.createPreviewBox() - ) + {this.props.isMostRecentIOUReport + && this.props.report.hasOutstandingIOU + && this.props.iou ? ( + this.createPreviewBox() + ) : null} ); @@ -150,7 +151,7 @@ ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview'; export default withWindowDimensions(withOnyx({ iou: { - key: ({iouReportID}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportID}`, + key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, }, personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index f06689613080..094e6513a71c 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -308,6 +308,7 @@ function fetchChatReportsByIDs(chatList) { simplifiedReports[reportKey].iouReportID = iouReportObject.reportID; simplifiedReports[reportKey].hasOutstandingIOU = iouReportObject.stateNum === 1 && iouReportObject.total !== 0; + Onyx.merge(iouReportKey, iouReportObject); }); // We use mergeCollection such that it updates the collection in one go. diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 06ba787dc679..46e6037de479 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -68,7 +68,8 @@ class ReportActionItem extends Component { shouldComponentUpdate(nextProps, nextState) { return this.state.isPopoverVisible !== nextState.isPopoverVisible || this.props.displayAsGroup !== nextProps.displayAsGroup - || !_.isEqual(this.props.action, nextProps.action); + || !_.isEqual(this.props.action, nextProps.action) + || this.props.isMostRecentIOUReport !== nextProps.isMostRecentIOUReport; } /** @@ -124,14 +125,14 @@ class ReportActionItem extends Component { ? ( ) : ( )} diff --git a/src/pages/home/report/ReportActionItemGrouped.js b/src/pages/home/report/ReportActionItemGrouped.js index fd9942eaa2dd..f31683039d28 100644 --- a/src/pages/home/report/ReportActionItemGrouped.js +++ b/src/pages/home/report/ReportActionItemGrouped.js @@ -13,21 +13,21 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // IOU report ID associated with current report - iouReportID: PropTypes.number, -}; + // The report currently being looked at + report: PropTypes.shape({ -const defaultProps = { - iouReportID: null, + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, }; -const ReportActionItemGrouped = ({action, iouReportID, isMostRecentIOUReport}) => ( +const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( {action.actionName === 'IOU' ? ( @@ -38,5 +38,4 @@ const ReportActionItemGrouped = ({action, iouReportID, isMostRecentIOUReport}) = ); ReportActionItemGrouped.propTypes = propTypes; -ReportActionItemGrouped.defaultProps = defaultProps; export default ReportActionItemGrouped; diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index e920565afc45..1e894ab2a07a 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -18,15 +18,15 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReport: PropTypes.bool.isRequired, - // IOU report ID associated with current report - iouReportID: PropTypes.number, -}; + // The report currently being looked at + report: PropTypes.shape({ -const defaultProps = { - iouReportID: null, + // IOU report ID associated with current report + iouReportID: PropTypes.number, + }).isRequired, }; -const ReportActionItemSingle = ({action, iouReportID, isMostRecentIOUReport}) => { +const ReportActionItemSingle = ({action, report, isMostRecentIOUReport}) => { const avatarUrl = action.automatic ? `${CONST.CLOUDFRONT_URL}/images/icons/concierge_2019.svg` : action.avatar; @@ -52,7 +52,7 @@ const ReportActionItemSingle = ({action, iouReportID, isMostRecentIOUReport}) => {action.actionName === 'IOU' ? ( @@ -64,5 +64,4 @@ const ReportActionItemSingle = ({action, iouReportID, isMostRecentIOUReport}) => }; ReportActionItemSingle.propTypes = propTypes; -ReportActionItemSingle.defaultProps = defaultProps; export default ReportActionItemSingle; diff --git a/src/styles/styles.js b/src/styles/styles.js index 149f9204146e..081b1034ca51 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -894,6 +894,11 @@ const styles = { borderColor: 'transparent', }, + secondAvatarInline: { + bottom: -3, + right: -25, + }, + avatarNormal: { height: variables.componentSizeNormal, width: variables.componentSizeNormal, From 0c1e7f67ba4b7038cfdf2626bb72077d35e4c594 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Mon, 5 Apr 2021 21:57:48 +0100 Subject: [PATCH 09/32] Update chat report real time on IOU report changes --- src/components/ReportActionItemIOUPreview.js | 2 +- src/libs/actions/Report.js | 70 +++++++++++++++++++- src/pages/home/report/ReportActionItem.js | 3 +- src/styles/styles.js | 3 + 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index 09bd6f9128de..f9b1b8558045 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -119,7 +119,7 @@ class ReportActionItemIOUPreview extends React.Component { {(this.props.iou.managerEmail === sessionEmail) ? ( diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 094e6513a71c..e7251ccd7d0e 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -293,8 +293,24 @@ function fetchChatReportsByIDs(chatList) { // personal details of all the participants and even link up their avatars to report icons. const reportIOUData = {}; _.each(fetchedReports, (report) => { - const simplifiedReport = getSimplifiedReportObject(report); - simplifiedReports[`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`] = simplifiedReport; + // Do not store IOU reports as 'report_' Onyx keys. + if (lodashGet(report, 'reportNameValuePairs.type') === 'chat') { + const simplifiedReport = getSimplifiedReportObject(report); + simplifiedReports[`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`] = simplifiedReport; + } else if (lodashGet(report, 'reportNameValuePairs.type') === 'iou') { + // If there's a new IOU report, find corresponding chat report and link them + findChatReportID([report.ownerEmail, report.managerEmail]).then((chatReportID) => { + const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.reportID}`; + const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; + Onyx.merge(iouReportKey, getSimplifiedIOUReport(report, chatReportID)); + const chatReportObject = {}; + chatReportObject.iouReportID = report.reportID; + chatReportObject.hasOutstandingIOU = report.stateNum === 1 + && report.total !== 0; + Onyx.merge(reportKey, chatReportObject); + + }); + } }); _.each(iouReportObjects, (iouReportObject) => { @@ -308,7 +324,6 @@ function fetchChatReportsByIDs(chatList) { simplifiedReports[reportKey].iouReportID = iouReportObject.reportID; simplifiedReports[reportKey].hasOutstandingIOU = iouReportObject.stateNum === 1 && iouReportObject.total !== 0; - Onyx.merge(iouReportKey, iouReportObject); }); // We use mergeCollection such that it updates the collection in one go. @@ -324,6 +339,22 @@ function fetchChatReportsByIDs(chatList) { }); } +/** + * Update chat report for given IOU report + * + * @param {Object} iouReportObject + * @return {void} + */ + function updateChatReportDetails(iouReportObject) { + if (!iouReportObject.participants) { + return; + } + findChatReportID([iouReportObject.participants[0], currentUserEmail]) + .then((chatReportID) => { + fetchChatReportsByIDs([chatReportID]); + }); +} + /** * Update the lastRead actionID and timestamp in local memory and Onyx * @@ -417,6 +448,11 @@ function updateReportWithNewAction(reportID, reportAction) { Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, reportActionsToMerge); + // If chat report receives an action with IOU, update IOU object + if (reportAction.actionName === 'IOU') { + fetchChatReportsByIDs([reportID]); + } + if (!ActiveClientManager.isClientTheLeader()) { console.debug('[LOCAL_NOTIFICATION] Skipping notification because this client is not the leader'); return; @@ -603,6 +639,29 @@ function fetchOrCreateChatReport(participants) { }); } +/** + * Get the report ID for a chat report for a specific + * set of participants. + * + * @param {String[]} participants + * @returns {Promise} chatReportID + */ + function findChatReportID(participants) { + if (participants.length < 2) { + throw new Error('fetchOrCreateChatReport() must have at least two participants'); + } + + return API.CreateChatReport({ + emailList: participants.join(','), + }) + .then((data) => { + if (data.jsonCode !== 200) { + throw new Error(data.message); + } + return data.reportID; + }); +} + /** * Get all chat reports and provide the proper report name * by fetching sharedReportList and personalDetails @@ -873,6 +932,11 @@ function handleReportChanged(report) { fetchChatReportsByIDs([report.reportID]); } + // If this is a brand new IOU report, find and link corresponding chat report ID + if (report.reportName === CONST.REPORT.ACTIONS.TYPE.IOU && report.chatReportID === undefined) { + updateChatReportDetails(report); + } + // Store the max sequence number for each report reportMaxSequenceNumbers[report.reportID] = report.maxSequenceNumber; diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 46e6037de479..da9d557085f2 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -69,7 +69,8 @@ class ReportActionItem extends Component { return this.state.isPopoverVisible !== nextState.isPopoverVisible || this.props.displayAsGroup !== nextProps.displayAsGroup || !_.isEqual(this.props.action, nextProps.action) - || this.props.isMostRecentIOUReport !== nextProps.isMostRecentIOUReport; + || this.props.isMostRecentIOUReport !== nextProps.isMostRecentIOUReport + || !_.isEqual(this.props.report, nextProps.report); } /** diff --git a/src/styles/styles.js b/src/styles/styles.js index 081b1034ca51..6beaf6408c09 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -897,6 +897,9 @@ const styles = { secondAvatarInline: { bottom: -3, right: -25, + borderWidth: 3, + borderRadius: 18, + borderColor: themeColors.componentBG, }, avatarNormal: { From 051fd09a241a91ecc7f13fcb7c3a730f1bfca033 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Mon, 5 Apr 2021 22:10:29 +0100 Subject: [PATCH 10/32] Fix linter errors --- src/libs/actions/Report.js | 52 ++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 04f237e5d9e0..f025fe54afcc 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -265,6 +265,29 @@ function updateIOUReportData(chatReport) { }); } +/** + * Get the report ID for a chat report for a specific + * set of participants. + * + * @param {String[]} participants + * @returns {Promise} chatReportID + */ +function findChatReportID(participants) { + if (participants.length < 2) { + throw new Error('fetchOrCreateChatReport() must have at least two participants'); + } + + return API.CreateChatReport({ + emailList: participants.join(','), + }) + .then((data) => { + if (data.jsonCode !== 200) { + throw new Error(data.message); + } + return data.reportID; + }); +} + /** * Fetches chat reports when provided a list of * chat report IDs @@ -302,13 +325,12 @@ function fetchChatReportsByIDs(chatList) { findChatReportID([report.ownerEmail, report.managerEmail]).then((chatReportID) => { const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.reportID}`; const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; - Onyx.merge(iouReportKey, getSimplifiedIOUReport(report, chatReportID)); + Onyx.merge(iouReportKey, getSimplifiedIOUReport(report, chatReportID)); const chatReportObject = {}; chatReportObject.iouReportID = report.reportID; chatReportObject.hasOutstandingIOU = report.stateNum === 1 && report.total !== 0; Onyx.merge(reportKey, chatReportObject); - }); } }); @@ -324,7 +346,6 @@ function fetchChatReportsByIDs(chatList) { simplifiedReports[reportKey].iouReportID = iouReportObject.reportID; simplifiedReports[reportKey].hasOutstandingIOU = iouReportObject.stateNum === 1 && iouReportObject.total !== 0; - Onyx.merge(iouReportKey, iouReportObject); }); // We use mergeCollection such that it updates the collection in one go. @@ -346,7 +367,7 @@ function fetchChatReportsByIDs(chatList) { * @param {Object} iouReportObject * @return {void} */ - function updateChatReportDetails(iouReportObject) { +function updateChatReportDetails(iouReportObject) { if (!iouReportObject.participants) { return; } @@ -640,29 +661,6 @@ function fetchOrCreateChatReport(participants) { }); } -/** - * Get the report ID for a chat report for a specific - * set of participants. - * - * @param {String[]} participants - * @returns {Promise} chatReportID - */ - function findChatReportID(participants) { - if (participants.length < 2) { - throw new Error('fetchOrCreateChatReport() must have at least two participants'); - } - - return API.CreateChatReport({ - emailList: participants.join(','), - }) - .then((data) => { - if (data.jsonCode !== 200) { - throw new Error(data.message); - } - return data.reportID; - }); -} - /** * Get all chat reports and provide the proper report name * by fetching sharedReportList and personalDetails From 3da3fb4de1e66b062c7781ad4bc1cdce73b4fc05 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Thu, 8 Apr 2021 16:27:38 +0100 Subject: [PATCH 11/32] Addressing comments and styling changes --- src/components/ReportActionItemIOUPreview.js | 24 +++++++++----------- src/libs/actions/Report.js | 2 +- src/pages/home/report/ReportActionCompose.js | 3 ++- src/pages/home/report/ReportActionItem.js | 3 ++- src/styles/styles.js | 13 +++++++---- src/styles/variables.js | 1 + 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index f9b1b8558045..c9a7e71b9337 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -6,7 +6,6 @@ import lodashGet from 'lodash/get'; import ONYXKEYS from '../ONYXKEYS'; import ReportActionItemIOUQuote from './ReportActionItemIOUQuote'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; -import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions'; import Text from './Text'; import MultipleAvatars from './MultipleAvatars'; import styles from '../styles/styles'; @@ -28,9 +27,6 @@ const propTypes = { hasOutstandingIOU: PropTypes.bool, }).isRequired, - /* Window Dimensions Props */ - ...windowDimensionsPropTypes, - /* --- Onyx Props --- */ // Active IOU Report for current report iou: PropTypes.shape({ @@ -104,11 +100,11 @@ class ReportActionItemIOUPreview extends React.Component { const managerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.managerEmail, 'avatar'], ''); const ownerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.ownerEmail, 'avatar'], ''); const sessionEmail = lodashGet(this.props.session, 'email', null); - const cachedTotal = this.props.iou.cachedTotal.replace(/[()]/g, ''); + const cachedTotal = this.props.iou.cachedTotal ? this.props.iou.cachedTotal.replace(/[()]/g, '') : ''; return ( - - + + {cachedTotal} @@ -117,10 +113,12 @@ class ReportActionItemIOUPreview extends React.Component { {ownerName} - + + + {(this.props.iou.managerEmail === sessionEmail) ? ( this.createPayButton() @@ -149,7 +147,7 @@ ReportActionItemIOUPreview.propTypes = propTypes; ReportActionItemIOUPreview.defaultProps = defaultProps; ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview'; -export default withWindowDimensions(withOnyx({ +export default withOnyx({ iou: { key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, }, @@ -159,4 +157,4 @@ export default withWindowDimensions(withOnyx({ session: { key: ONYXKEYS.SESSION, }, -})(ReportActionItemIOUPreview)); +})(ReportActionItemIOUPreview); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index f025fe54afcc..0fc4948f2417 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -274,7 +274,7 @@ function updateIOUReportData(chatReport) { */ function findChatReportID(participants) { if (participants.length < 2) { - throw new Error('fetchOrCreateChatReport() must have at least two participants'); + throw new Error('findChatReportID() must have at least two participants.'); } return API.CreateChatReport({ diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 85eb443286c1..6b327c840546 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -40,7 +40,7 @@ const propTypes = { // participants associated with current report participants: PropTypes.arrayOf(PropTypes.string), - }).isRequired, + }), ...windowDimensionsPropTypes, }; @@ -48,6 +48,7 @@ const propTypes = { const defaultProps = { comment: '', modal: {}, + report: {}, }; class ReportActionCompose extends React.Component { diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index da9d557085f2..0a62672aa05f 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -39,11 +39,12 @@ const propTypes = { // IOU report ID associated with current report iouReportID: PropTypes.number, - }).isRequired, + }), }; const defaultProps = { betas: {}, + report: {}, }; class ReportActionItem extends Component { diff --git a/src/styles/styles.js b/src/styles/styles.js index 6beaf6408c09..102edfa561cd 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -118,6 +118,7 @@ const styles = { }, buttonSmall: { + borderRadius: variables.componentBorderRadiusNormal, height: variables.componentSizeSmall, paddingTop: 6, paddingRight: 10, @@ -1270,13 +1271,15 @@ const styles = { iouPreviewBox: { borderColor: themeColors.border, borderWidth: 1, - borderRadius: variables.componentBorderRadiusNormal, - padding: 15, - marginTop: 15, + borderRadius: variables.componentBorderRadiusCard, + padding: 20, + marginTop: 16, + maxWidth: 400, + width: '100%', }, - normalRadius: { - borderRadius: variables.componentBorderRadius, + iouPreviewBoxAvatar: { + marginRight: -10, }, noScrollbars: { diff --git a/src/styles/variables.js b/src/styles/variables.js index 9b70c5d5b072..fff0f2fd0991 100644 --- a/src/styles/variables.js +++ b/src/styles/variables.js @@ -6,6 +6,7 @@ export default { componentBorderRadius: 8, componentBorderRadiusSmall: 4, componentBorderRadiusNormal: 8, + componentBorderRadiusCard: 12, avatarSizeNormal: 40, avatarSizeSmall: 28, fontSizeSmall: 11, From 75d0302319c03ddedb0290a8e2e31ba810a017b3 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Thu, 8 Apr 2021 17:18:52 +0100 Subject: [PATCH 12/32] Fixing merge issues --- src/pages/home/report/ReportActionItem.js | 9 +++------ src/pages/home/report/ReportActionItemSingle.js | 7 ++++++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 70f703dc3378..d9a584edef75 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -2,6 +2,8 @@ import _ from 'underscore'; import React, {Component} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; +import ONYXKEYS from '../../../ONYXKEYS'; import ReportActionPropTypes from './ReportActionPropTypes'; import { getReportActionItemStyle, @@ -28,8 +30,6 @@ const propTypes = { isMostRecentIOUReport: PropTypes.bool.isRequired, /* --- Onyx Props --- */ - // List of betas for the current user. - betas: PropTypes.arrayOf(PropTypes.string), // The report currently being looked at report: PropTypes.shape({ @@ -40,7 +40,6 @@ const propTypes = { }; const defaultProps = { - betas: {}, report: {}, }; @@ -162,10 +161,8 @@ class ReportActionItem extends Component { } ReportActionItem.propTypes = propTypes; +ReportActionItem.defaultProps = defaultProps; export default withOnyx({ - betas: { - key: ONYXKEYS.BETAS, - }, report: { key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, }, diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 8b1b12959e39..f6d1d51fc33c 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -32,7 +32,12 @@ const propTypes = { }).isRequired, }; -const ReportActionItemSingle = ({action, report, isMostRecentIOUReport, personalDetails}) => { +const ReportActionItemSingle = ({ + action, + report, + isMostRecentIOUReport, + personalDetails, +}) => { const {avatar, displayName} = personalDetails[action.actorEmail] || {}; const avatarUrl = action.automatic ? `${CONST.CLOUDFRONT_URL}/images/icons/concierge_2019.svg` From cdbaaff56fec5ffa99975b2e23e3099740712237 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Thu, 8 Apr 2021 23:58:03 +0100 Subject: [PATCH 13/32] Create a separate function for updateIOUAndChatReportData --- src/libs/actions/Report.js | 79 +++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 0fc4948f2417..1b5d41b4d261 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -320,18 +320,6 @@ function fetchChatReportsByIDs(chatList) { if (lodashGet(report, 'reportNameValuePairs.type') === 'chat') { const simplifiedReport = getSimplifiedReportObject(report); simplifiedReports[`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`] = simplifiedReport; - } else if (lodashGet(report, 'reportNameValuePairs.type') === 'iou') { - // If there's a new IOU report, find corresponding chat report and link them - findChatReportID([report.ownerEmail, report.managerEmail]).then((chatReportID) => { - const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.reportID}`; - const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; - Onyx.merge(iouReportKey, getSimplifiedIOUReport(report, chatReportID)); - const chatReportObject = {}; - chatReportObject.iouReportID = report.reportID; - chatReportObject.hasOutstandingIOU = report.stateNum === 1 - && report.total !== 0; - Onyx.merge(reportKey, chatReportObject); - }); } }); @@ -361,6 +349,63 @@ function fetchChatReportsByIDs(chatList) { }); } +/** + * Updates chat and IOU data in Onyx with data from API + * for given chat or IOU report ID. + * + * @param {Number} reportID + */ +function updateIOUAndChatReportData(reportID) { + API.Get({ + returnValueList: 'reportStuff', + reportIDList: reportID, + shouldLoadOptionalKeys: true, + includePinnedReports: true, + }) + .then(({reports}) => { + if (reports.length === 0) { + return; + } + const report = Object.values(reports)[0]; + if (lodashGet(report, 'reportNameValuePairs.type') === 'chat') { + // This is a chat report, find corresponding IOU report and link them + updateIOUReportData(report).then((iouReportObject) => { + let chatReportObject = {}; + if (iouReportObject) { + const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportObject.reportID}`; + Onyx.merge(iouReportKey, iouReportObject); + chatReportObject = { + iouReportID: iouReportObject.reportID, + hasOutstandingIOU: iouReportObject.stateNum === 1 + && iouReportObject.total !== 0, + }; + } else { + chatReportObject = { + iouReportID: undefined, + hasOutstandingIOU: false, + }; + } + const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`; + Onyx.merge(reportKey, chatReportObject); + }); + } else if (lodashGet(report, 'reportNameValuePairs.type') === 'iou') { + // If this is an IOU report, find corresponding chat report and link them + findChatReportID([report.ownerEmail, report.managerEmail]).then((chatReportID) => { + const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.reportID}`; + const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; + const simplifiedReport = { + iouReportID: report.reportID, + hasOutstandingIOU: report.stateNum === 1 + && report.total !== 0, + }; + const iouReportObject = getSimplifiedIOUReport(report, chatReportID); + Onyx.merge(iouReportKey, iouReportObject); + Onyx.merge(reportKey, simplifiedReport); + }); + } + }); +} + /** * Update chat report for given IOU report * @@ -372,9 +417,7 @@ function updateChatReportDetails(iouReportObject) { return; } findChatReportID([iouReportObject.participants[0], currentUserEmail]) - .then((chatReportID) => { - fetchChatReportsByIDs([chatReportID]); - }); + .then(chatReportID => updateIOUAndChatReportData(chatReportID)); } /** @@ -471,8 +514,8 @@ function updateReportWithNewAction(reportID, reportAction) { Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, reportActionsToMerge); // If chat report receives an action with IOU, update IOU object - if (reportAction.actionName === 'IOU') { - fetchChatReportsByIDs([reportID]); + if (reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) { + updateIOUAndChatReportData(reportID); } if (!ActiveClientManager.isClientTheLeader()) { @@ -928,7 +971,7 @@ function handleReportChanged(report) { // A report can be missing a name if a comment is received via pusher event // and the report does not yet exist in Onyx (eg. a new DM created with the logged in person) if (report.reportID && report.reportName === undefined) { - fetchChatReportsByIDs([report.reportID]); + updateIOUAndChatReportData(report.reportID); } // If this is a brand new IOU report, find and link corresponding chat report ID From d4be1b54c7e7d4fddd705b3b89498b1a2f1e8795 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Fri, 9 Apr 2021 21:10:16 +0100 Subject: [PATCH 14/32] Addressing comments --- src/CONST.js | 4 + src/components/ReportActionItemIOUPreview.js | 143 +++++++--------- src/components/ReportActionItemIOUQuote.js | 2 +- src/libs/actions/Report.js | 158 ++++++++---------- src/pages/NewChatPage.js | 4 +- src/pages/NewGroupPage.js | 4 +- src/pages/SearchPage.js | 4 +- src/pages/home/report/ReportActionItem.js | 23 ++- .../home/report/ReportActionItemGrouped.js | 28 +--- .../home/report/ReportActionItemSingle.js | 26 +-- src/pages/home/report/ReportActionsView.js | 12 +- src/styles/styles.js | 2 +- 12 files changed, 173 insertions(+), 237 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index f7dcbaa26ff6..e4b2e681667f 100644 --- a/src/CONST.js +++ b/src/CONST.js @@ -31,6 +31,10 @@ const CONST = { IOU: 'IOU', }, }, + TYPE: { + CHAT: 'chat', + IOU: 'iou', + }, }, MODAL: { MODAL_TYPE: { diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index c9a7e71b9337..c4ec11a4ed51 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -15,7 +15,7 @@ const propTypes = { action: PropTypes.shape(ReportActionPropTypes).isRequired, // Is this the most recent IOU Action? - isMostRecentIOUReport: PropTypes.bool.isRequired, + isMostRecentIOUReportAction: PropTypes.bool.isRequired, // The report currently being looked at report: PropTypes.shape({ @@ -58,90 +58,65 @@ const defaultProps = { iou: {}, }; -class ReportActionItemIOUPreview extends React.Component { - /** - * Creates IOU preview pay button. - * - * @returns {View} - */ - createPayButton() { - return ( - - - Pay - - - ); - } - - /** - * Creates IOU preview box view if outstanding amount is not 0. - * - * @returns {View} - */ - createPreviewBox() { - const managerName = lodashGet( - this.props.personalDetails, - [this.props.iou.managerEmail, 'displayName'], - this.props.iou.managerEmail, - ); - const ownerName = lodashGet( - this.props.personalDetails, - [this.props.iou.ownerEmail, 'displayName'], - this.props.iou.ownerEmail, - ); - const managerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.managerEmail, 'avatar'], ''); - const ownerAvatar = lodashGet(this.props.personalDetails, [this.props.iou.ownerEmail, 'avatar'], ''); - const sessionEmail = lodashGet(this.props.session, 'email', null); - const cachedTotal = this.props.iou.cachedTotal ? this.props.iou.cachedTotal.replace(/[()]/g, '') : ''; - - return ( - - - - {cachedTotal} - - {managerName} - {' owes '} - {ownerName} - - - - - - - {(this.props.iou.managerEmail === sessionEmail) ? ( - this.createPayButton() +const ReportActionItemIOUPreview = ({ + action, + isMostRecentIOUReportAction, + report, + iou, + personalDetails, + session, +}) => { + const managerName = lodashGet(personalDetails, [iou.managerEmail, 'displayName'], iou.managerEmail); + const ownerName = lodashGet(personalDetails, [iou.ownerEmail, 'displayName'], iou.ownerEmail); + const managerAvatar = lodashGet(personalDetails, [iou.managerEmail, 'avatar'], ''); + const ownerAvatar = lodashGet(personalDetails, [iou.ownerEmail, 'avatar'], ''); + const sessionEmail = lodashGet(session, 'email', null); + const cachedTotal = iou.cachedTotal ? iou.cachedTotal.replace(/[()]/g, '') : ''; + + return ( + + + {isMostRecentIOUReportAction + && report.hasOutstandingIOU + && iou ? ( + + + + {cachedTotal} + + {managerName} + {' owes '} + {ownerName} + + + + + + + {(iou.managerEmail === sessionEmail) ? ( + + + Pay + + + ) + : null} + ) - : null} - - ); - } - - render() { - return ( - - - {this.props.isMostRecentIOUReport - && this.props.report.hasOutstandingIOU - && this.props.iou ? ( - this.createPreviewBox() - ) - : null} - - ); - } -} + : null} + + ); +}; ReportActionItemIOUPreview.propTypes = propTypes; ReportActionItemIOUPreview.defaultProps = defaultProps; diff --git a/src/components/ReportActionItemIOUQuote.js b/src/components/ReportActionItemIOUQuote.js index 60be313f80f4..bf56ed9d243e 100644 --- a/src/components/ReportActionItemIOUQuote.js +++ b/src/components/ReportActionItemIOUQuote.js @@ -13,7 +13,7 @@ const propTypes = { const ReportActionItemIOUQuote = ({action}) => ( - {_.map(_.compact(action.message), (fragment, index) => { + {_.map(action.message, (fragment, index) => { const viewDetails = '
View Details'; const html = `
${fragment.text}${viewDetails}
`; return ( diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 1b5d41b4d261..5602bf85693a 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -44,6 +44,12 @@ Onyx.connect({ callback: val => myPersonalDetails = val, }); +const allIOUReports = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT_IOUS, + callback: val => allIOUReports[val.reportID] = val, +}); + const typingWatchTimers = {}; // Keeps track of the max sequence number for each report @@ -316,11 +322,8 @@ function fetchChatReportsByIDs(chatList) { // personal details of all the participants and even link up their avatars to report icons. const reportIOUData = {}; _.each(fetchedReports, (report) => { - // Do not store IOU reports as 'report_' Onyx keys. - if (lodashGet(report, 'reportNameValuePairs.type') === 'chat') { - const simplifiedReport = getSimplifiedReportObject(report); - simplifiedReports[`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`] = simplifiedReport; - } + const simplifiedReport = getSimplifiedReportObject(report); + simplifiedReports[`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`] = simplifiedReport; }); _.each(iouReportObjects, (iouReportObject) => { @@ -349,6 +352,52 @@ function fetchChatReportsByIDs(chatList) { }); } +/** + * Update stored IOU object for given chat report + * + * @param {Object} report + */ +function updateIOUReportDataForChatReport(report) { + updateIOUReportData(report).then((iouReportObject) => { + let chatReportObject = {}; + if (iouReportObject) { + const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportObject.reportID}`; + Onyx.merge(iouReportKey, iouReportObject); + chatReportObject = { + iouReportID: iouReportObject.reportID, + hasOutstandingIOU: iouReportObject.stateNum === 1 + && iouReportObject.total !== 0, + }; + } else { + chatReportObject = { + hasOutstandingIOU: false, + }; + } + const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`; + Onyx.merge(reportKey, chatReportObject); + }); +} + +/** + * Update stored chat report object for given IOU report + * + * @param {Object} report + */ +function updateChatReportDataForIOUReport(report) { + findChatReportID([report.ownerEmail, report.managerEmail]).then((chatReportID) => { + const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.reportID}`; + const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; + const simplifiedReport = { + iouReportID: report.reportID, + hasOutstandingIOU: report.stateNum === 1 + && report.total !== 0, + }; + const iouReportObject = getSimplifiedIOUReport(report, chatReportID); + Onyx.merge(iouReportKey, iouReportObject); + Onyx.merge(reportKey, simplifiedReport); + }); +} + /** * Updates chat and IOU data in Onyx with data from API * for given chat or IOU report ID. @@ -363,63 +412,16 @@ function updateIOUAndChatReportData(reportID) { includePinnedReports: true, }) .then(({reports}) => { - if (reports.length === 0) { - return; - } - const report = Object.values(reports)[0]; - if (lodashGet(report, 'reportNameValuePairs.type') === 'chat') { - // This is a chat report, find corresponding IOU report and link them - updateIOUReportData(report).then((iouReportObject) => { - let chatReportObject = {}; - if (iouReportObject) { - const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportObject.reportID}`; - Onyx.merge(iouReportKey, iouReportObject); - chatReportObject = { - iouReportID: iouReportObject.reportID, - hasOutstandingIOU: iouReportObject.stateNum === 1 - && iouReportObject.total !== 0, - }; - } else { - chatReportObject = { - iouReportID: undefined, - hasOutstandingIOU: false, - }; - } - const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`; - Onyx.merge(reportKey, chatReportObject); - }); - } else if (lodashGet(report, 'reportNameValuePairs.type') === 'iou') { - // If this is an IOU report, find corresponding chat report and link them - findChatReportID([report.ownerEmail, report.managerEmail]).then((chatReportID) => { - const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.reportID}`; - const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; - const simplifiedReport = { - iouReportID: report.reportID, - hasOutstandingIOU: report.stateNum === 1 - && report.total !== 0, - }; - const iouReportObject = getSimplifiedIOUReport(report, chatReportID); - Onyx.merge(iouReportKey, iouReportObject); - Onyx.merge(reportKey, simplifiedReport); - }); + const report = _.values(reports)[0]; + const reportType = lodashGet(report, 'reportNameValuePairs.type'); + if (reportType === CONST.REPORT.TYPE.CHAT) { + updateIOUReportDataForChatReport(report); + } else if (reportType === CONST.REPORT.TYPE.IOU) { + updateChatReportDataForIOUReport(report); } }); } -/** - * Update chat report for given IOU report - * - * @param {Object} iouReportObject - * @return {void} - */ -function updateChatReportDetails(iouReportObject) { - if (!iouReportObject.participants) { - return; - } - findChatReportID([iouReportObject.participants[0], currentUserEmail]) - .then(chatReportID => updateIOUAndChatReportData(chatReportID)); -} - /** * Update the lastRead actionID and timestamp in local memory and Onyx * @@ -682,26 +684,14 @@ function unsubscribeFromReportChannel(reportID) { * * @param {String[]} participants */ -function fetchOrCreateChatReport(participants) { - if (participants.length < 2) { - throw new Error('fetchOrCreateChatReport() must have at least two participants'); - } - - API.CreateChatReport({ - emailList: participants.join(','), - }) - .then((data) => { - if (data.jsonCode !== 200) { - throw new Error(data.message); - } +function fetchOrCreateChatReportAndRedirect(participants) { + findChatReportID(participants).then((reportID) => { + // Merge report into Onyx + Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {reportID}); - // Merge report into Onyx - const reportID = data.reportID; - Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {reportID}); - - // Redirect the logged in person to the new report - Navigation.navigate(ROUTES.getReportRoute(reportID)); - }); + // Redirect the logged in person to the new report + Navigation.navigate(ROUTES.getReportRoute(reportID)); + }); } /** @@ -724,7 +714,7 @@ function fetchChatReports() { // The string cast here is necessary as Get rvl='chatList' may return an int fetchChatReportsByIDs(String(response.chatList).split(',')); } else { - fetchOrCreateChatReport([currentUserEmail, 'concierge@expensify.com']); + fetchOrCreateChatReportAndRedirect([currentUserEmail, 'concierge@expensify.com']); } return response.chatList; @@ -968,17 +958,15 @@ function handleReportChanged(report) { return; } + const iouReport = lodashGet(allIOUReports, report.reportID); + // A report can be missing a name if a comment is received via pusher event // and the report does not yet exist in Onyx (eg. a new DM created with the logged in person) - if (report.reportID && report.reportName === undefined) { + // However, do not call update function if this report is an IOU report. + if (report.reportID && report.reportName === undefined && !iouReport) { updateIOUAndChatReportData(report.reportID); } - // If this is a brand new IOU report, find and link corresponding chat report ID - if (report.reportName === CONST.REPORT.ACTIONS.TYPE.IOU && report.chatReportID === undefined) { - updateChatReportDetails(report); - } - // Store the max sequence number for each report reportMaxSequenceNumbers[report.reportID] = report.maxSequenceNumber; @@ -1006,7 +994,7 @@ NetworkConnection.onReconnect(() => { export { fetchAll, fetchActions, - fetchOrCreateChatReport, + fetchOrCreateChatReportAndRedirect, addAction, updateLastReadActionID, subscribeToReportCommentEvents, diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index e3cc6be6027c..583f9aed2a09 100644 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -6,7 +6,7 @@ import OptionsSelector from '../components/OptionsSelector'; import {getNewChatOptions, getHeaderMessage} from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; -import {fetchOrCreateChatReport} from '../libs/actions/Report'; +import {fetchOrCreateChatReportAndRedirect} from '../libs/actions/Report'; import KeyboardSpacer from '../components/KeyboardSpacer'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; @@ -97,7 +97,7 @@ class NewChatPage extends Component { * @param {Object} option */ createNewChat(option) { - fetchOrCreateChatReport([ + fetchOrCreateChatReportAndRedirect([ this.props.session.email, option.login, ]); diff --git a/src/pages/NewGroupPage.js b/src/pages/NewGroupPage.js index 3f7dc291be99..114e08a4eafe 100644 --- a/src/pages/NewGroupPage.js +++ b/src/pages/NewGroupPage.js @@ -7,7 +7,7 @@ import OptionsSelector from '../components/OptionsSelector'; import {getNewGroupOptions, getHeaderMessage} from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; -import {fetchOrCreateChatReport} from '../libs/actions/Report'; +import {fetchOrCreateChatReportAndRedirect} from '../libs/actions/Report'; import CONST from '../CONST'; import KeyboardSpacer from '../components/KeyboardSpacer'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; @@ -126,7 +126,7 @@ class NewGroupPage extends Component { if (userLogins.length < 1) { return; } - fetchOrCreateChatReport([this.props.session.email, ...userLogins]); + fetchOrCreateChatReportAndRedirect([this.props.session.email, ...userLogins]); } /** diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js index d0f4b0492a46..c84eb6aa2cfc 100644 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -10,7 +10,7 @@ import KeyboardSpacer from '../components/KeyboardSpacer'; import Navigation from '../libs/Navigation/Navigation'; import ROUTES from '../ROUTES'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; -import {fetchOrCreateChatReport} from '../libs/actions/Report'; +import {fetchOrCreateChatReportAndRedirect} from '../libs/actions/Report'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; import ScreenWrapper from '../components/ScreenWrapper'; import Timing from '../libs/actions/Timing'; @@ -121,7 +121,7 @@ class SearchPage extends Component { Navigation.navigate(ROUTES.getReportRoute(option.reportID)); }); } else { - fetchOrCreateChatReport([ + fetchOrCreateChatReportAndRedirect([ this.props.session.email, option.login, ]); diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index d9a584edef75..3725f3186247 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -15,6 +15,9 @@ import PopoverWithMeasuredContent from '../../../components/PopoverWithMeasuredC import ReportActionItemSingle from './ReportActionItemSingle'; import ReportActionItemGrouped from './ReportActionItemGrouped'; import ReportActionContextMenu from './ReportActionContextMenu'; +import ReportActionItemIOUPreview from '../../../components/ReportActionItemIOUPreview'; +import ReportActionItemMessage from './ReportActionItemMessage'; + const propTypes = { // The ID of the report this action is on. @@ -27,7 +30,7 @@ const propTypes = { displayAsGroup: PropTypes.bool.isRequired, // Is this the most recent IOU Action? - isMostRecentIOUReport: PropTypes.bool.isRequired, + isMostRecentIOUReportAction: PropTypes.bool.isRequired, /* --- Onyx Props --- */ @@ -65,7 +68,7 @@ class ReportActionItem extends Component { return this.state.isPopoverVisible !== nextState.isPopoverVisible || this.props.displayAsGroup !== nextProps.displayAsGroup || !_.isEqual(this.props.action, nextProps.action) - || this.props.isMostRecentIOUReport !== nextProps.isMostRecentIOUReport + || this.props.isMostRecentIOUReportAction !== nextProps.isMostRecentIOUReportAction || !_.isEqual(this.props.report, nextProps.report); } @@ -100,6 +103,15 @@ class ReportActionItem extends Component { } render() { + const message = this.props.action.actionName === 'IOU' + ? ( + + ) + : ; return ( @@ -110,15 +122,12 @@ class ReportActionItem extends Component { ? ( ) : ( )}
diff --git a/src/pages/home/report/ReportActionItemGrouped.js b/src/pages/home/report/ReportActionItemGrouped.js index f31683039d28..828be219b53b 100644 --- a/src/pages/home/report/ReportActionItemGrouped.js +++ b/src/pages/home/report/ReportActionItemGrouped.js @@ -1,38 +1,18 @@ import React from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; -import ReportActionPropTypes from './ReportActionPropTypes'; -import ReportActionItemMessage from './ReportActionItemMessage'; import styles from '../../../styles/styles'; -import ReportActionItemIOUPreview from '../../../components/ReportActionItemIOUPreview'; const propTypes = { - // All the data of the action - action: PropTypes.shape(ReportActionPropTypes).isRequired, - // Is this the most recent IOU Action? - isMostRecentIOUReport: PropTypes.bool.isRequired, - - // The report currently being looked at - report: PropTypes.shape({ - - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }).isRequired, + // Message view component for this action + message: PropTypes.element.isRequired, }; -const ReportActionItemGrouped = ({action, report, isMostRecentIOUReport}) => ( +const ReportActionItemGrouped = ({message}) => ( - {action.actionName === 'IOU' - ? ( - - ) - : } + {message} ); diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index f6d1d51fc33c..251b045540ed 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -4,13 +4,11 @@ import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import _ from 'underscore'; import ReportActionPropTypes from './ReportActionPropTypes'; -import ReportActionItemMessage from './ReportActionItemMessage'; import ReportActionItemFragment from './ReportActionItemFragment'; import styles from '../../../styles/styles'; import CONST from '../../../CONST'; import ReportActionItemDate from './ReportActionItemDate'; import Avatar from '../../../components/Avatar'; -import ReportActionItemIOUPreview from '../../../components/ReportActionItemIOUPreview'; import ONYXKEYS from '../../../ONYXKEYS'; import personalDetailsPropType from '../../personalDetailsPropType'; @@ -18,25 +16,17 @@ const propTypes = { // All the data of the action action: PropTypes.shape(ReportActionPropTypes).isRequired, - // Is this the most recent IOU Action? - isMostRecentIOUReport: PropTypes.bool.isRequired, - // All of the personalDetails personalDetails: PropTypes.objectOf(personalDetailsPropType).isRequired, - // The report currently being looked at - report: PropTypes.shape({ - - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }).isRequired, + // Message view component for this action + message: PropTypes.element.isRequired, }; const ReportActionItemSingle = ({ action, - report, - isMostRecentIOUReport, personalDetails, + message, }) => { const {avatar, displayName} = personalDetails[action.actorEmail] || {}; const avatarUrl = action.automatic @@ -68,15 +58,7 @@ const ReportActionItemSingle = ({ ))}
- {action.actionName === 'IOU' - ? ( - - ) - : } + {message}
); diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 418dfaa5240e..3691a4967c92 100644 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -279,18 +279,15 @@ class ReportActionsView extends React.Component { } /** - * Checks whether given sequence number belongs to the most recent IOU Report + * Finds and updates most recent IOU report action number * - * @param {Number} actionSequenceNumber - * @returns {Boolean} */ - isMostRecentIOUReport(actionSequenceNumber) { - const mostRecentIOUReportSequenceNumber = _.chain(this.props.reportActions) + updateMostRecentIOUReportActionNumber() { + this.mostRecentIOUReportSequenceNumber = _.chain(this.props.reportActions) .sortBy('sequenceNumber') .filter(action => action.actionName === 'IOU') .max(action => action.sequenceNumber) .value().sequenceNumber; - return actionSequenceNumber === mostRecentIOUReportSequenceNumber; } /** @@ -359,7 +356,7 @@ class ReportActionsView extends React.Component { displayAsGroup={this.isConsecutiveActionMadeByPreviousActor(index)} onLayout={onLayout} needsLayoutCalculation={needsLayoutCalculation} - isMostRecentIOUReport={this.isMostRecentIOUReport(item.action.sequenceNumber)} + isMostRecentIOUReportAction={item.action.sequenceNumber === this.mostRecentIOUReportSequenceNumber} />
); @@ -382,6 +379,7 @@ class ReportActionsView extends React.Component { this.setUpUnreadActionIndicator(); this.updateSortedReportActions(); + this.updateMostRecentIOUReportActionNumber(); return ( this.actionListElement = el} diff --git a/src/styles/styles.js b/src/styles/styles.js index fd34c39061aa..2ec78b22fd6e 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1273,7 +1273,7 @@ const styles = { borderRadius: variables.componentBorderRadiusCard, padding: 20, marginTop: 16, - maxWidth: 400, + maxWidth: 300, width: '100%', }, From 61cb1e4cc9f7b1d04c9e2f779a00169d6af687af Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Wed, 14 Apr 2021 18:47:02 +0100 Subject: [PATCH 15/32] Updating Report.js to work with fixed push notifications --- src/components/ReportActionItemIOUPreview.js | 28 +++- src/libs/actions/Report.js | 146 ++++++++++--------- src/pages/NewChatPage.js | 4 +- src/pages/NewGroupPage.js | 4 +- src/pages/SearchPage.js | 4 +- src/pages/home/report/ReportActionItem.js | 1 - src/pages/home/report/ReportActionsView.js | 9 +- 7 files changed, 105 insertions(+), 91 deletions(-) diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index c4ec11a4ed51..6c4187007203 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -2,7 +2,9 @@ import React from 'react'; import {View, TouchableOpacity} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; +import _ from 'underscore'; import lodashGet from 'lodash/get'; +import Str from 'expensify-common/lib/str'; import ONYXKEYS from '../ONYXKEYS'; import ReportActionItemIOUQuote from './ReportActionItemIOUQuote'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; @@ -66,19 +68,31 @@ const ReportActionItemIOUPreview = ({ personalDetails, session, }) => { - const managerName = lodashGet(personalDetails, [iou.managerEmail, 'displayName'], iou.managerEmail); - const ownerName = lodashGet(personalDetails, [iou.ownerEmail, 'displayName'], iou.ownerEmail); + const managerName = lodashGet( + personalDetails, + [iou.managerEmail, 'displayName'], + iou.managerEmail ? Str.removeSMSDomain(iou.managerEmail) : '', + ); + const ownerName = lodashGet( + personalDetails, + [iou.ownerEmail, 'displayName'], + iou.ownerEmail ? Str.removeSMSDomain(iou.ownerEmail) : '', + ); const managerAvatar = lodashGet(personalDetails, [iou.managerEmail, 'avatar'], ''); const ownerAvatar = lodashGet(personalDetails, [iou.ownerEmail, 'avatar'], ''); const sessionEmail = lodashGet(session, 'email', null); const cachedTotal = iou.cachedTotal ? iou.cachedTotal.replace(/[()]/g, '') : ''; + // Pay button should be visible to manager person in the report + // Check if the currently logged in user is the manager. + const isPayButtonVisible = iou.managerEmail === sessionEmail; + return ( {isMostRecentIOUReportAction && report.hasOutstandingIOU - && iou ? ( + && !_.isEmpty(iou) && ( @@ -96,7 +110,7 @@ const ReportActionItemIOUPreview = ({ /> - {(iou.managerEmail === sessionEmail) ? ( + {isPayButtonVisible && ( @@ -109,11 +123,9 @@ const ReportActionItemIOUPreview = ({ Pay
- ) - : null} + )} - ) - : null} + )} ); }; diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 5602bf85693a..8fcb119c5b37 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -44,10 +44,10 @@ Onyx.connect({ callback: val => myPersonalDetails = val, }); -const allIOUReports = {}; +const allReports = {}; Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT_IOUS, - callback: val => allIOUReports[val.reportID] = val, + key: ONYXKEYS.COLLECTION.REPORT, + callback: val => allReports[val.reportID] = val, }); const typingWatchTimers = {}; @@ -208,7 +208,7 @@ function getSimplifiedIOUReport(reportData, chatReportID) { * @param {Number} chatReport.reportID * @return {Promise} */ -function updateIOUReportData(chatReport) { +function fetchIOUReportData(chatReport) { const reportActionList = chatReport.reportActionList || []; const containsIOUAction = _.any(reportActionList, reportAction => reportAction.action === CONST.REPORT.ACTIONS.TYPE.IOU); @@ -272,8 +272,7 @@ function updateIOUReportData(chatReport) { } /** - * Get the report ID for a chat report for a specific - * set of participants. + * Get the report ID for a chat report for a specific set of participants. * * @param {String[]} participants * @returns {Promise} chatReportID @@ -313,7 +312,7 @@ function fetchChatReportsByIDs(chatList) { .then(({reports}) => { Log.info('[Report] successfully fetched report data', true); fetchedReports = reports; - return Promise.all(_.map(fetchedReports, updateIOUReportData)); + return Promise.all(_.map(fetchedReports, fetchIOUReportData)); }) .then((iouReportObjects) => { // Process the reports and store them in Onyx. At the same time we'll save the simplified reports in this @@ -353,73 +352,79 @@ function fetchChatReportsByIDs(chatList) { } /** - * Update stored IOU object for given chat report + * Update stored IOU object for given IOU and chat report ID * - * @param {Object} report + * @param {Number} iouReportID + * @param {Number} chatReportID */ -function updateIOUReportDataForChatReport(report) { - updateIOUReportData(report).then((iouReportObject) => { - let chatReportObject = {}; - if (iouReportObject) { - const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportObject.reportID}`; - Onyx.merge(iouReportKey, iouReportObject); - chatReportObject = { - iouReportID: iouReportObject.reportID, - hasOutstandingIOU: iouReportObject.stateNum === 1 - && iouReportObject.total !== 0, - }; - } else { - chatReportObject = { - hasOutstandingIOU: false, - }; +function updateIOUReportData(iouReportID, chatReportID) { + API.Get({ + returnValueList: 'reportStuff', + reportIDList: iouReportID, + shouldLoadOptionalKeys: true, + includePinnedReports: true, + }).then((response) => { + if (!response) { + return; } - const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`; - Onyx.merge(reportKey, chatReportObject); - }); -} -/** - * Update stored chat report object for given IOU report - * - * @param {Object} report - */ -function updateChatReportDataForIOUReport(report) { - findChatReportID([report.ownerEmail, report.managerEmail]).then((chatReportID) => { - const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.reportID}`; - const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; - const simplifiedReport = { - iouReportID: report.reportID, - hasOutstandingIOU: report.stateNum === 1 - && report.total !== 0, + if (response.jsonCode !== 200) { + throw new Error(response.message); + } + + const iouReportData = response.reports[iouReportID]; + if (!iouReportData) { + throw new Error(`No iouReportData found for reportID ${iouReportID}`); + } + const iouReportObject = getSimplifiedIOUReport(iouReportData, chatReportID); + const chatReportObject = { + hasOutstandingIOU: iouReportObject.stateNum === 1 + && iouReportObject.total !== 0, + iouReportID, }; - const iouReportObject = getSimplifiedIOUReport(report, chatReportID); + if (!chatReportObject.hasOutstandingIOU) { + chatReportObject.iouReportID = null; + } + const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportObject.reportID}`; + const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; Onyx.merge(iouReportKey, iouReportObject); - Onyx.merge(reportKey, simplifiedReport); + Onyx.merge(reportKey, chatReportObject); }); } /** - * Updates chat and IOU data in Onyx with data from API - * for given chat or IOU report ID. + * Update stored IOU object for given chat report ID * - * @param {Number} reportID + * @param {Number} chatReportID */ -function updateIOUAndChatReportData(reportID) { - API.Get({ - returnValueList: 'reportStuff', - reportIDList: reportID, - shouldLoadOptionalKeys: true, - includePinnedReports: true, - }) - .then(({reports}) => { - const report = _.values(reports)[0]; - const reportType = lodashGet(report, 'reportNameValuePairs.type'); - if (reportType === CONST.REPORT.TYPE.CHAT) { - updateIOUReportDataForChatReport(report); - } else if (reportType === CONST.REPORT.TYPE.IOU) { - updateChatReportDataForIOUReport(report); - } - }); +function updateIOUReportDataForChatReport(chatReportID) { + const chatReport = lodashGet(allReports, chatReportID); + let iouReportID = lodashGet(chatReport, 'iouReportID'); + + if (iouReportID) { + updateIOUReportData(iouReportID, chatReportID); + return; + } + + const participants = chatReport.participants; + if (participants.length !== 1) { + throw new Error('chatReport doesn\'t have any participant.'); + } + API.GetIOUReport({ + debtorEmail: participants[0], + }).then((response) => { + iouReportID = response.reportID || 0; + if (response.jsonCode !== 200) { + throw new Error(response.message); + } else if (iouReportID === 0) { + // If there is no IOU report for this user then we will assume it has been paid and do nothing here. + // All reports are initialized with hasOutstandingIOU: false. Since the IOU report we were looking for has + // been settled then there's nothing more to do. + console.debug('GetIOUReport returned a reportID of 0, not fetching IOU report data'); + return; + } + updateIOUReportData(iouReportID, chatReportID); + }); } /** @@ -517,7 +522,7 @@ function updateReportWithNewAction(reportID, reportAction) { // If chat report receives an action with IOU, update IOU object if (reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) { - updateIOUAndChatReportData(reportID); + updateIOUReportDataForChatReport(reportID); } if (!ActiveClientManager.isClientTheLeader()) { @@ -680,11 +685,11 @@ function unsubscribeFromReportChannel(reportID) { /** * Get the report ID for a chat report for a specific - * set of participants and redirect to it. + * set of participants and navigate to it. * * @param {String[]} participants */ -function fetchOrCreateChatReportAndRedirect(participants) { +function fetchOrCreateChatReportAndNavigate(participants) { findChatReportID(participants).then((reportID) => { // Merge report into Onyx Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {reportID}); @@ -714,7 +719,7 @@ function fetchChatReports() { // The string cast here is necessary as Get rvl='chatList' may return an int fetchChatReportsByIDs(String(response.chatList).split(',')); } else { - fetchOrCreateChatReportAndRedirect([currentUserEmail, 'concierge@expensify.com']); + fetchOrCreateChatReportAndNavigate([currentUserEmail, 'concierge@expensify.com']); } return response.chatList; @@ -958,13 +963,10 @@ function handleReportChanged(report) { return; } - const iouReport = lodashGet(allIOUReports, report.reportID); - // A report can be missing a name if a comment is received via pusher event // and the report does not yet exist in Onyx (eg. a new DM created with the logged in person) - // However, do not call update function if this report is an IOU report. - if (report.reportID && report.reportName === undefined && !iouReport) { - updateIOUAndChatReportData(report.reportID); + if (report.reportID && report.reportName === undefined) { + fetchChatReportsByIDs([report.reportID]); } // Store the max sequence number for each report @@ -994,7 +996,7 @@ NetworkConnection.onReconnect(() => { export { fetchAll, fetchActions, - fetchOrCreateChatReportAndRedirect, + fetchOrCreateChatReportAndNavigate, addAction, updateLastReadActionID, subscribeToReportCommentEvents, diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index 583f9aed2a09..a2940be4dd81 100644 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -6,7 +6,7 @@ import OptionsSelector from '../components/OptionsSelector'; import {getNewChatOptions, getHeaderMessage} from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; -import {fetchOrCreateChatReportAndRedirect} from '../libs/actions/Report'; +import {fetchOrCreateChatReportAndNavigate} from '../libs/actions/Report'; import KeyboardSpacer from '../components/KeyboardSpacer'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; @@ -97,7 +97,7 @@ class NewChatPage extends Component { * @param {Object} option */ createNewChat(option) { - fetchOrCreateChatReportAndRedirect([ + fetchOrCreateChatReportAndNavigate([ this.props.session.email, option.login, ]); diff --git a/src/pages/NewGroupPage.js b/src/pages/NewGroupPage.js index 114e08a4eafe..fda042e6b09f 100644 --- a/src/pages/NewGroupPage.js +++ b/src/pages/NewGroupPage.js @@ -7,7 +7,7 @@ import OptionsSelector from '../components/OptionsSelector'; import {getNewGroupOptions, getHeaderMessage} from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; -import {fetchOrCreateChatReportAndRedirect} from '../libs/actions/Report'; +import {fetchOrCreateChatReportAndNavigate} from '../libs/actions/Report'; import CONST from '../CONST'; import KeyboardSpacer from '../components/KeyboardSpacer'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; @@ -126,7 +126,7 @@ class NewGroupPage extends Component { if (userLogins.length < 1) { return; } - fetchOrCreateChatReportAndRedirect([this.props.session.email, ...userLogins]); + fetchOrCreateChatReportAndNavigate([this.props.session.email, ...userLogins]); } /** diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js index c84eb6aa2cfc..52e8265cc572 100644 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -10,7 +10,7 @@ import KeyboardSpacer from '../components/KeyboardSpacer'; import Navigation from '../libs/Navigation/Navigation'; import ROUTES from '../ROUTES'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; -import {fetchOrCreateChatReportAndRedirect} from '../libs/actions/Report'; +import {fetchOrCreateChatReportAndNavigate} from '../libs/actions/Report'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; import ScreenWrapper from '../components/ScreenWrapper'; import Timing from '../libs/actions/Timing'; @@ -121,7 +121,7 @@ class SearchPage extends Component { Navigation.navigate(ROUTES.getReportRoute(option.reportID)); }); } else { - fetchOrCreateChatReportAndRedirect([ + fetchOrCreateChatReportAndNavigate([ this.props.session.email, option.login, ]); diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 3725f3186247..d7163fc0460b 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -18,7 +18,6 @@ import ReportActionContextMenu from './ReportActionContextMenu'; import ReportActionItemIOUPreview from '../../../components/ReportActionItemIOUPreview'; import ReportActionItemMessage from './ReportActionItemMessage'; - const propTypes = { // The ID of the report this action is on. reportID: PropTypes.number.isRequired, diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 270669416a0a..dee57fe0682a 100644 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -81,7 +81,7 @@ class ReportActionsView extends React.Component { }; this.updateSortedReportActions(props.reportActions); - this.updateMostRecentIOUReportActionNumber(); + this.updateMostRecentIOUReportActionNumber(props.reportActions); } componentDidMount() { @@ -97,7 +97,7 @@ class ReportActionsView extends React.Component { shouldComponentUpdate(nextProps, nextState) { if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) { this.updateSortedReportActions(nextProps.reportActions); - this.updateMostRecentIOUReportActionNumber(); + this.updateMostRecentIOUReportActionNumber(nextProps.reportActions); return true; } @@ -256,9 +256,10 @@ class ReportActionsView extends React.Component { /** * Finds and updates most recent IOU report action number * + * @param {Array<{sequenceNumber, actionName}>} reportActions */ - updateMostRecentIOUReportActionNumber() { - this.mostRecentIOUReportSequenceNumber = _.chain(this.props.reportActions) + updateMostRecentIOUReportActionNumber(reportActions) { + this.mostRecentIOUReportSequenceNumber = _.chain(reportActions) .sortBy('sequenceNumber') .filter(action => action.actionName === 'IOU') .max(action => action.sequenceNumber) From 975c0fc4bd158de51cf9e3c8e3fee2d91c5a81af Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Sun, 18 Apr 2021 14:24:15 +0100 Subject: [PATCH 16/32] Addressing comments --- src/components/ReportActionItemIOUPreview.js | 21 ++-- src/libs/actions/Report.js | 114 +++++++++--------- src/pages/NewChatPage.js | 4 +- src/pages/NewGroupPage.js | 4 +- src/pages/SearchPage.js | 4 +- src/pages/home/report/ReportActionItem.js | 46 +++---- .../home/report/ReportActionItemGrouped.js | 9 +- .../home/report/ReportActionItemSingle.js | 8 +- src/pages/home/report/ReportActionsView.js | 8 ++ 9 files changed, 107 insertions(+), 111 deletions(-) diff --git a/src/components/ReportActionItemIOUPreview.js b/src/components/ReportActionItemIOUPreview.js index 6c4187007203..aa3d3a0778ae 100644 --- a/src/components/ReportActionItemIOUPreview.js +++ b/src/components/ReportActionItemIOUPreview.js @@ -19,15 +19,8 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReportAction: PropTypes.bool.isRequired, - // The report currently being looked at - report: PropTypes.shape({ - - // IOU report ID associated with current report - iouReportID: PropTypes.number, - - // Whether there is an outstanding amount in IOU - hasOutstandingIOU: PropTypes.bool, - }).isRequired, + // Whether there is an outstanding amount in IOU + hasOutstandingIOU: PropTypes.bool.isRequired, /* --- Onyx Props --- */ // Active IOU Report for current report @@ -63,7 +56,7 @@ const defaultProps = { const ReportActionItemIOUPreview = ({ action, isMostRecentIOUReportAction, - report, + hasOutstandingIOU, iou, personalDetails, session, @@ -85,13 +78,13 @@ const ReportActionItemIOUPreview = ({ // Pay button should be visible to manager person in the report // Check if the currently logged in user is the manager. - const isPayButtonVisible = iou.managerEmail === sessionEmail; + const isCurrentUserManager = iou.managerEmail === sessionEmail; return ( {isMostRecentIOUReportAction - && report.hasOutstandingIOU + && hasOutstandingIOU && !_.isEmpty(iou) && ( @@ -110,7 +103,7 @@ const ReportActionItemIOUPreview = ({ /> - {isPayButtonVisible && ( + {isCurrentUserManager && ( @@ -136,7 +129,7 @@ ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview'; export default withOnyx({ iou: { - key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, + key: ({iouReportID}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportID}`, }, personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 8fcb119c5b37..08cb3492ef92 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -237,8 +237,10 @@ function fetchIOUReportData(chatReport) { }).then((response) => { iouReportID = response.reportID || 0; if (response.jsonCode !== 200) { - throw new Error(response.message); - } else if (iouReportID === 0) { + console.error(response.message); + return; + } + if (iouReportID === 0) { // If there is no IOU report for this user then we will assume it has been paid and do nothing here. // All reports are initialized with hasOutstandingIOU: false. Since the IOU report we were looking for has // been settled then there's nothing more to do. @@ -258,12 +260,14 @@ function fetchIOUReportData(chatReport) { } if (response.jsonCode !== 200) { - throw new Error(response.message); + console.error(response.message); + return; } const iouReportData = response.reports[iouReportID]; if (!iouReportData) { - throw new Error(`No iouReportData found for reportID ${iouReportID}`); + console.error(`No iouReportData found for reportID ${iouReportID}`); + return; } return getSimplifiedIOUReport(iouReportData, chatReport.reportID); }).catch((error) => { @@ -271,28 +275,6 @@ function fetchIOUReportData(chatReport) { }); } -/** - * Get the report ID for a chat report for a specific set of participants. - * - * @param {String[]} participants - * @returns {Promise} chatReportID - */ -function findChatReportID(participants) { - if (participants.length < 2) { - throw new Error('findChatReportID() must have at least two participants.'); - } - - return API.CreateChatReport({ - emailList: participants.join(','), - }) - .then((data) => { - if (data.jsonCode !== 200) { - throw new Error(data.message); - } - return data.reportID; - }); -} - /** * Fetches chat reports when provided a list of * chat report IDs @@ -352,7 +334,7 @@ function fetchChatReportsByIDs(chatList) { } /** - * Update stored IOU object for given IOU and chat report ID + * Given IOU and chat report ID fetches most recent IOU data from API and update stored data in Onyx. * * @param {Number} iouReportID * @param {Number} chatReportID @@ -369,12 +351,14 @@ function updateIOUReportData(iouReportID, chatReportID) { } if (response.jsonCode !== 200) { - throw new Error(response.message); + console.error(response.message); + return; } const iouReportData = response.reports[iouReportID]; if (!iouReportData) { - throw new Error(`No iouReportData found for reportID ${iouReportID}`); + console.error(`No iouReportData found for reportID ${iouReportID}`); + return; } const iouReportObject = getSimplifiedIOUReport(iouReportData, chatReportID); const chatReportObject = { @@ -393,37 +377,34 @@ function updateIOUReportData(iouReportID, chatReportID) { } /** - * Update stored IOU object for given chat report ID + * Given chat report ID finds active IOU report ID via GetIOUReport API call * * @param {Number} chatReportID + * @returns {Promise} */ -function updateIOUReportDataForChatReport(chatReportID) { +function fetchIOUReportID(chatReportID) { const chatReport = lodashGet(allReports, chatReportID); - let iouReportID = lodashGet(chatReport, 'iouReportID'); - - if (iouReportID) { - updateIOUReportData(iouReportID, chatReportID); - return; - } - const participants = chatReport.participants; if (participants.length !== 1) { - throw new Error('chatReport doesn\'t have any participant.'); + console.error('chatReport doesn\'t have any participant.'); + return; } - API.GetIOUReport({ + return API.GetIOUReport({ debtorEmail: participants[0], }).then((response) => { - iouReportID = response.reportID || 0; + const iouReportID = response.reportID || 0; if (response.jsonCode !== 200) { - throw new Error(response.message); - } else if (iouReportID === 0) { + console.error(response.message); + return; + } + if (iouReportID === 0) { // If there is no IOU report for this user then we will assume it has been paid and do nothing here. // All reports are initialized with hasOutstandingIOU: false. Since the IOU report we were looking for has // been settled then there's nothing more to do. console.debug('GetIOUReport returned a reportID of 0, not fetching IOU report data'); return; } - updateIOUReportData(iouReportID, chatReportID); + return iouReportID; }); } @@ -522,7 +503,13 @@ function updateReportWithNewAction(reportID, reportAction) { // If chat report receives an action with IOU, update IOU object if (reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) { - updateIOUReportDataForChatReport(reportID); + const chatReport = lodashGet(allReports, reportID); + const iouReportID = lodashGet(chatReport, 'iouReportID'); + if (iouReportID) { + updateIOUReportData(iouReportID, reportID); + } else { + fetchIOUReportID(reportID).then(iouID => updateIOUReportData(iouID, reportID)); + } } if (!ActiveClientManager.isClientTheLeader()) { @@ -685,18 +672,35 @@ function unsubscribeFromReportChannel(reportID) { /** * Get the report ID for a chat report for a specific - * set of participants and navigate to it. + * set of participants and navigate to it if wanted. * * @param {String[]} participants + * @param {Boolean} shouldNavigate + * @returns {Promise} */ -function fetchOrCreateChatReportAndNavigate(participants) { - findChatReportID(participants).then((reportID) => { - // Merge report into Onyx - Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {reportID}); +function fetchOrCreateChatReport(participants, shouldNavigate = true) { + if (participants.length < 2) { + throw new Error('fetchOrCreateChatReport() must have at least two participants.'); + } - // Redirect the logged in person to the new report - Navigation.navigate(ROUTES.getReportRoute(reportID)); - }); + return API.CreateChatReport({ + emailList: participants.join(','), + }) + .then((data) => { + if (data.jsonCode !== 200) { + console.error(data.message); + return; + } + + // Merge report into Onyx + Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${data.reportID}`, {reportID: data.reportID}); + + if (shouldNavigate) { + // Redirect the logged in person to the new report + Navigation.navigate(ROUTES.getReportRoute(data.reportID)); + } + return data.reportID; + }); } /** @@ -719,7 +723,7 @@ function fetchChatReports() { // The string cast here is necessary as Get rvl='chatList' may return an int fetchChatReportsByIDs(String(response.chatList).split(',')); } else { - fetchOrCreateChatReportAndNavigate([currentUserEmail, 'concierge@expensify.com']); + fetchOrCreateChatReport([currentUserEmail, 'concierge@expensify.com']); } return response.chatList; @@ -996,7 +1000,7 @@ NetworkConnection.onReconnect(() => { export { fetchAll, fetchActions, - fetchOrCreateChatReportAndNavigate, + fetchOrCreateChatReport, addAction, updateLastReadActionID, subscribeToReportCommentEvents, diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index 75ffd4b24169..f0aa0160c889 100644 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -6,7 +6,7 @@ import OptionsSelector from '../components/OptionsSelector'; import {getNewChatOptions, getHeaderMessage} from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; -import {fetchOrCreateChatReportAndNavigate} from '../libs/actions/Report'; +import {fetchOrCreateChatReport} from '../libs/actions/Report'; import KeyboardSpacer from '../components/KeyboardSpacer'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; @@ -97,7 +97,7 @@ class NewChatPage extends Component { * @param {Object} option */ createNewChat(option) { - fetchOrCreateChatReportAndNavigate([ + fetchOrCreateChatReport([ this.props.session.email, option.login, ]); diff --git a/src/pages/NewGroupPage.js b/src/pages/NewGroupPage.js index 3e2949b30405..c9bbb2365724 100644 --- a/src/pages/NewGroupPage.js +++ b/src/pages/NewGroupPage.js @@ -7,7 +7,7 @@ import OptionsSelector from '../components/OptionsSelector'; import {getNewGroupOptions, getHeaderMessage} from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; -import {fetchOrCreateChatReportAndNavigate} from '../libs/actions/Report'; +import {fetchOrCreateChatReport} from '../libs/actions/Report'; import CONST from '../CONST'; import KeyboardSpacer from '../components/KeyboardSpacer'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; @@ -126,7 +126,7 @@ class NewGroupPage extends Component { if (userLogins.length < 1) { return; } - fetchOrCreateChatReportAndNavigate([this.props.session.email, ...userLogins]); + fetchOrCreateChatReport([this.props.session.email, ...userLogins]); } /** diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js index 9915c4461e7c..339b4cfe28bf 100644 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -10,7 +10,7 @@ import KeyboardSpacer from '../components/KeyboardSpacer'; import Navigation from '../libs/Navigation/Navigation'; import ROUTES from '../ROUTES'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; -import {fetchOrCreateChatReportAndNavigate} from '../libs/actions/Report'; +import {fetchOrCreateChatReport} from '../libs/actions/Report'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; import ScreenWrapper from '../components/ScreenWrapper'; import Timing from '../libs/actions/Timing'; @@ -121,7 +121,7 @@ class SearchPage extends Component { Navigation.navigate(ROUTES.getReportRoute(option.reportID)); }); } else { - fetchOrCreateChatReportAndNavigate([ + fetchOrCreateChatReport([ this.props.session.email, option.login, ]); diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 750bc0aa4acb..1b48e2ee749e 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -2,8 +2,6 @@ import _ from 'underscore'; import React, {Component} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; -import {withOnyx} from 'react-native-onyx'; -import ONYXKEYS from '../../../ONYXKEYS'; import ReportActionPropTypes from './ReportActionPropTypes'; import { getReportActionItemStyle, @@ -32,21 +30,18 @@ const propTypes = { // Is this the most recent IOU Action? isMostRecentIOUReportAction: PropTypes.bool.isRequired, - // Should we display the new indicator on top of the comment? - shouldDisplayNewIndicator: PropTypes.bool.isRequired, - - /* --- Onyx Props --- */ + // Whether there is an outstanding amount in IOU + hasOutstandingIOU: PropTypes.bool.isRequired, - // The report currently being looked at - report: PropTypes.shape({ + // IOU report ID associated with current report + iouReportID: PropTypes.number, - // IOU report ID associated with current report - iouReportID: PropTypes.number, - }), + // Should we display the new indicator on top of the comment? + shouldDisplayNewIndicator: PropTypes.bool.isRequired, }; const defaultProps = { - report: {}, + iouReportID: undefined, }; class ReportActionItem extends Component { @@ -71,7 +66,8 @@ class ReportActionItem extends Component { return this.state.isPopoverVisible !== nextState.isPopoverVisible || this.props.displayAsGroup !== nextProps.displayAsGroup || this.props.isMostRecentIOUReportAction !== nextProps.isMostRecentIOUReportAction - || !_.isEqual(this.props.report, nextProps.report) + || this.props.hasOutstandingIOU !== nextProps.hasOutstandingIOU + || this.props.iouReportID !== nextProps.iouReportID || (this.props.shouldDisplayNewIndicator !== nextProps.shouldDisplayNewIndicator) || !_.isEqual(this.props.action, nextProps.action); } @@ -107,10 +103,11 @@ class ReportActionItem extends Component { } render() { - const message = this.props.action.actionName === 'IOU' + const children = this.props.action.actionName === 'IOU' ? ( @@ -127,15 +124,14 @@ class ReportActionItem extends Component { {!this.props.displayAsGroup ? ( - + + {children} + ) : ( - + + {children} + )} @@ -178,8 +174,4 @@ class ReportActionItem extends Component { ReportActionItem.propTypes = propTypes; ReportActionItem.defaultProps = defaultProps; -export default withOnyx({ - report: { - key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, - }, -})(ReportActionItem); +export default ReportActionItem; diff --git a/src/pages/home/report/ReportActionItemGrouped.js b/src/pages/home/report/ReportActionItemGrouped.js index 828be219b53b..bfc1dda2c14f 100644 --- a/src/pages/home/report/ReportActionItemGrouped.js +++ b/src/pages/home/report/ReportActionItemGrouped.js @@ -4,15 +4,14 @@ import PropTypes from 'prop-types'; import styles from '../../../styles/styles'; const propTypes = { - - // Message view component for this action - message: PropTypes.element.isRequired, + // Children view component for this action item + children: PropTypes.node.isRequired, }; -const ReportActionItemGrouped = ({message}) => ( +const ReportActionItemGrouped = ({children}) => ( - {message} + {children} ); diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 251b045540ed..09ed283e315e 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -19,14 +19,14 @@ const propTypes = { // All of the personalDetails personalDetails: PropTypes.objectOf(personalDetailsPropType).isRequired, - // Message view component for this action - message: PropTypes.element.isRequired, + // Children view component for this action item + children: PropTypes.node.isRequired, }; const ReportActionItemSingle = ({ action, personalDetails, - message, + children, }) => { const {avatar, displayName} = personalDetails[action.actorEmail] || {}; const avatarUrl = action.automatic @@ -58,7 +58,7 @@ const ReportActionItemSingle = ({ ))} - {message} + {children} ); diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index da3703d8ec0d..4b0ffcecd885 100644 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -40,6 +40,12 @@ const propTypes = { // The largest sequenceNumber on this report maxSequenceNumber: PropTypes.number, + + // Whether there is an outstanding amount in IOU + hasOutstandingIOU: PropTypes.bool.isRequired, + + // IOU report ID associated with current report + iouReportID: PropTypes.number, }), // Array of report actions for this report @@ -302,6 +308,8 @@ class ReportActionsView extends React.Component { shouldDisplayNewIndicator={this.initialNewMarkerPosition > 0 && item.action.sequenceNumber === this.initialNewMarkerPosition} isMostRecentIOUReportAction={item.action.sequenceNumber === this.mostRecentIOUReportSequenceNumber} + iouReportID={this.props.report.iouReportID} + hasOutstandingIOU={this.props.report.hasOutstandingIOU} /> ); } From 103e1d1199032986013995515dede56c02a08f31 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Tue, 20 Apr 2021 01:49:42 +0100 Subject: [PATCH 17/32] Simplify Report.js --- src/libs/actions/Report.js | 170 ++++++++------------- src/pages/home/report/ReportActionsView.js | 8 +- 2 files changed, 74 insertions(+), 104 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 90321208218f..15f64e850809 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -201,14 +201,72 @@ function getSimplifiedIOUReport(reportData, chatReportID) { } /** - * Fetches the updated data for an IOU Report and updates the IOU collection in Onyx + * Given IOU and chat report ID fetches most recent IOU data from API. + * + * @param {Number} iouReportID + * @param {Number} chatReportID + * @returns {Promise} + */ +function fetchIOUReport(iouReportID, chatReportID) { + return API.Get({ + returnValueList: 'reportStuff', + reportIDList: iouReportID, + shouldLoadOptionalKeys: true, + includePinnedReports: true, + }).then((response) => { + if (!response) { + return; + } + if (response.jsonCode !== 200) { + console.error(response.message); + return; + } + const iouReportData = response.reports[iouReportID]; + if (!iouReportData) { + console.error(`No iouReportData found for reportID ${iouReportID}`); + return; + } + return getSimplifiedIOUReport(iouReportData, chatReportID); + }).catch((error) => { + console.debug(`[Report] Failed to populate IOU Collection: ${error.message}`); + }); +} + +/** + * Given debtorEmail finds active IOU report ID via GetIOUReport API call + * + * @param {String} debtorEmail + * @returns {Promise} + */ +function fetchIOUReportID(debtorEmail) { + return API.GetIOUReport({ + debtorEmail, + }).then((response) => { + const iouReportID = response.reportID || 0; + if (response.jsonCode !== 200) { + console.error(response.message); + return; + } + if (iouReportID === 0) { + // If there is no IOU report for this user then we will assume it has been paid and do nothing here. + // All reports are initialized with hasOutstandingIOU: false. Since the IOU report we were looking for has + // been settled then there's nothing more to do. + console.debug('GetIOUReport returned a reportID of 0, not fetching IOU report data'); + return; + } + return iouReportID; + }); +} + +/** + * Given chatReport object, fetches the updated data for an IOU Report if there is an active IOU report * * @param {Object} chatReport * @param {Object[]} chatReport.reportActionList * @param {Number} chatReport.reportID * @return {Promise} */ -function fetchIOUReportData(chatReport) { +function fetchIOUReportDataForChatReport(chatReport) { const reportActionList = chatReport.reportActionList || []; const containsIOUAction = _.any(reportActionList, reportAction => reportAction.action === CONST.REPORT.ACTIONS.TYPE.IOU); @@ -228,51 +286,8 @@ function fetchIOUReportData(chatReport) { return; } - // Since the Chat and the IOU are different reports with different reportIDs, and GetIOUReport only returns the - // IOU's reportID, keep track of the IOU's reportID so we can use it to get the IOUReport data via `GetReportStuff`. - // Note: GetIOUReport does not return IOU reports that have been settled. - let iouReportID = 0; - return API.GetIOUReport({ - debtorEmail: participants[0], - }).then((response) => { - iouReportID = response.reportID || 0; - if (response.jsonCode !== 200) { - console.error(response.message); - return; - } - if (iouReportID === 0) { - // If there is no IOU report for this user then we will assume it has been paid and do nothing here. - // All reports are initialized with hasOutstandingIOU: false. Since the IOU report we were looking for has - // been settled then there's nothing more to do. - console.debug('GetIOUReport returned a reportID of 0, not fetching IOU report data'); - return; - } - - return API.Get({ - returnValueList: 'reportStuff', - reportIDList: iouReportID, - shouldLoadOptionalKeys: true, - includePinnedReports: true, - }); - }).then((response) => { - if (!response) { - return; - } - - if (response.jsonCode !== 200) { - console.error(response.message); - return; - } - - const iouReportData = response.reports[iouReportID]; - if (!iouReportData) { - console.error(`No iouReportData found for reportID ${iouReportID}`); - return; - } - return getSimplifiedIOUReport(iouReportData, chatReport.reportID); - }).catch((error) => { - console.debug(`[Report] Failed to populate IOU Collection: ${error.message}`); - }); + return fetchIOUReportID(participants[0]) + .then(iouReportID => fetchIOUReport(iouReportID, chatReport.reportID)); } /** @@ -294,7 +309,7 @@ function fetchChatReportsByIDs(chatList) { .then(({reports}) => { Log.info('[Report] successfully fetched report data', true); fetchedReports = reports; - return Promise.all(_.map(fetchedReports, fetchIOUReportData)); + return Promise.all(_.map(fetchedReports, fetchIOUReportDataForChatReport)); }) .then((iouReportObjects) => { // Process the reports and store them in Onyx. At the same time we'll save the simplified reports in this @@ -340,27 +355,7 @@ function fetchChatReportsByIDs(chatList) { * @param {Number} chatReportID */ function updateIOUReportData(iouReportID, chatReportID) { - API.Get({ - returnValueList: 'reportStuff', - reportIDList: iouReportID, - shouldLoadOptionalKeys: true, - includePinnedReports: true, - }).then((response) => { - if (!response) { - return; - } - - if (response.jsonCode !== 200) { - console.error(response.message); - return; - } - - const iouReportData = response.reports[iouReportID]; - if (!iouReportData) { - console.error(`No iouReportData found for reportID ${iouReportID}`); - return; - } - const iouReportObject = getSimplifiedIOUReport(iouReportData, chatReportID); + fetchIOUReport(iouReportID, chatReportID).then((iouReportObject) => { const chatReportObject = { hasOutstandingIOU: iouReportObject.stateNum === 1 && iouReportObject.total !== 0, @@ -376,38 +371,6 @@ function updateIOUReportData(iouReportID, chatReportID) { }); } -/** - * Given chat report ID finds active IOU report ID via GetIOUReport API call - * - * @param {Number} chatReportID - * @returns {Promise} - */ -function fetchIOUReportID(chatReportID) { - const chatReport = lodashGet(allReports, chatReportID); - const participants = chatReport.participants; - if (participants.length !== 1) { - console.error('chatReport doesn\'t have any participant.'); - return; - } - return API.GetIOUReport({ - debtorEmail: participants[0], - }).then((response) => { - const iouReportID = response.reportID || 0; - if (response.jsonCode !== 200) { - console.error(response.message); - return; - } - if (iouReportID === 0) { - // If there is no IOU report for this user then we will assume it has been paid and do nothing here. - // All reports are initialized with hasOutstandingIOU: false. Since the IOU report we were looking for has - // been settled then there's nothing more to do. - console.debug('GetIOUReport returned a reportID of 0, not fetching IOU report data'); - return; - } - return iouReportID; - }); -} - /** * Update the lastRead actionID and timestamp in local memory and Onyx * @@ -507,8 +470,9 @@ function updateReportWithNewAction(reportID, reportAction) { const iouReportID = lodashGet(chatReport, 'iouReportID'); if (iouReportID) { updateIOUReportData(iouReportID, reportID); - } else { - fetchIOUReportID(reportID).then(iouID => updateIOUReportData(iouID, reportID)); + } else if (!chatReport || chatReport.participants.length === 1) { + fetchIOUReportID(chatReport ? chatReport.participants[0] : reportAction.actorEmail) + .then(iouID => updateIOUReportData(iouID, reportID)); } } diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 4b0ffcecd885..398fd16bb734 100644 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -42,7 +42,7 @@ const propTypes = { maxSequenceNumber: PropTypes.number, // Whether there is an outstanding amount in IOU - hasOutstandingIOU: PropTypes.bool.isRequired, + hasOutstandingIOU: PropTypes.bool, // IOU report ID associated with current report iouReportID: PropTypes.number, @@ -62,6 +62,7 @@ const defaultProps = { report: { unreadActionCount: 0, maxSequenceNumber: 0, + hasOutstandingIOU: false, }, reportActions: {}, session: {}, @@ -112,6 +113,11 @@ class ReportActionsView extends React.Component { return true; } + if (this.props.report.hasOutstandingIOU !== nextProps.report.hasOutstandingIOU + || this.props.report.iouReportID !== nextProps.report.iouReportID) { + return true; + } + return false; } From 70522c4e53f55433f9738dd726def8ef6730ac3c Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Wed, 21 Apr 2021 01:03:50 +0100 Subject: [PATCH 18/32] Another set of refactoring in Report.js --- src/libs/actions/Report.js | 98 +++++++++++------------ src/pages/home/report/ReportActionItem.js | 3 +- 2 files changed, 47 insertions(+), 54 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 15f64e850809..9cda60415d3e 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -47,7 +47,7 @@ Onyx.connect({ const allReports = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT, - callback: val => allReports[val.reportID] = val, + callback: val => val ? allReports[val.reportID] = val: {}, }); const typingWatchTimers = {}; @@ -258,38 +258,6 @@ function fetchIOUReportID(debtorEmail) { }); } -/** - * Given chatReport object, fetches the updated data for an IOU Report if there is an active IOU report - * - * @param {Object} chatReport - * @param {Object[]} chatReport.reportActionList - * @param {Number} chatReport.reportID - * @return {Promise} - */ -function fetchIOUReportDataForChatReport(chatReport) { - const reportActionList = chatReport.reportActionList || []; - const containsIOUAction = _.any(reportActionList, - reportAction => reportAction.action === CONST.REPORT.ACTIONS.TYPE.IOU); - - // If there aren't any IOU actions, we don't need to fetch any additional data - if (!containsIOUAction) { - return; - } - - // If we don't have one participant (other than the current user), this is not an IOU - const participants = getParticipantEmailsFromReport(chatReport); - if (participants.length !== 1) { - Log.alert('[Report] Report with IOU action has more than 2 participants', true, { - reportID: chatReport.reportID, - participants, - }); - return; - } - - return fetchIOUReportID(participants[0]) - .then(iouReportID => fetchIOUReport(iouReportID, chatReport.reportID)); -} - /** * Fetches chat reports when provided a list of * chat report IDs @@ -309,7 +277,29 @@ function fetchChatReportsByIDs(chatList) { .then(({reports}) => { Log.info('[Report] successfully fetched report data', true); fetchedReports = reports; - return Promise.all(_.map(fetchedReports, fetchIOUReportDataForChatReport)); + return Promise.all(_.map(fetchedReports, (chatReport) => { + const reportActionList = chatReport.reportActionList || []; + const containsIOUAction = _.any(reportActionList, + reportAction => reportAction.action === CONST.REPORT.ACTIONS.TYPE.IOU); + + // If there aren't any IOU actions, we don't need to fetch any additional data + if (!containsIOUAction) { + return; + } + + // If we don't have one participant (other than the current user), this is not an IOU + const participants = getParticipantEmailsFromReport(chatReport); + if (participants.length !== 1) { + Log.alert('[Report] Report with IOU action has more than 2 participants', true, { + reportID: chatReport.reportID, + participants, + }); + return; + } + + return fetchIOUReportID(participants[0]) + .then(iouReportID => fetchIOUReport(iouReportID, chatReport.reportID)); + })); }) .then((iouReportObjects) => { // Process the reports and store them in Onyx. At the same time we'll save the simplified reports in this @@ -349,26 +339,26 @@ function fetchChatReportsByIDs(chatList) { } /** - * Given IOU and chat report ID fetches most recent IOU data from API and update stored data in Onyx. + * Given IOU object and chat report ID save the data to Onyx. * - * @param {Number} iouReportID + * @param {Object} iouReportObject + * @param {Number} iouReportObject.stateNum + * @param {Number} iouReportObject.total + * @param {Number} iouReportObject.reportID * @param {Number} chatReportID */ -function updateIOUReportData(iouReportID, chatReportID) { - fetchIOUReport(iouReportID, chatReportID).then((iouReportObject) => { - const chatReportObject = { - hasOutstandingIOU: iouReportObject.stateNum === 1 - && iouReportObject.total !== 0, - iouReportID, - }; - if (!chatReportObject.hasOutstandingIOU) { - chatReportObject.iouReportID = null; - } - const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportObject.reportID}`; - const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; - Onyx.merge(iouReportKey, iouReportObject); - Onyx.merge(reportKey, chatReportObject); - }); +function setLocalIOUReportData(iouReportObject, chatReportID) { + const chatReportObject = { + hasOutstandingIOU: iouReportObject.stateNum === 1 && iouReportObject.total !== 0, + iouReportID: iouReportObject.reportID, + }; + if (!chatReportObject.hasOutstandingIOU) { + chatReportObject.iouReportID = null; + } + const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportObject.reportID}`; + const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`; + Onyx.merge(iouReportKey, iouReportObject); + Onyx.merge(reportKey, chatReportObject); } /** @@ -469,10 +459,12 @@ function updateReportWithNewAction(reportID, reportAction) { const chatReport = lodashGet(allReports, reportID); const iouReportID = lodashGet(chatReport, 'iouReportID'); if (iouReportID) { - updateIOUReportData(iouReportID, reportID); + fetchIOUReport(iouReportID, reportID) + .then(iouReportObject => setLocalIOUReportData(iouReportObject, reportID)); } else if (!chatReport || chatReport.participants.length === 1) { fetchIOUReportID(chatReport ? chatReport.participants[0] : reportAction.actorEmail) - .then(iouID => updateIOUReportData(iouID, reportID)); + .then(iouID => fetchIOUReport(iouID, reportID)) + .then(iouReportObject => setLocalIOUReportData(iouReportObject, reportID)); } } diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 7497bfc65195..b6f9e4ec3f09 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -31,7 +31,7 @@ const propTypes = { isMostRecentIOUReportAction: PropTypes.bool.isRequired, // Whether there is an outstanding amount in IOU - hasOutstandingIOU: PropTypes.bool.isRequired, + hasOutstandingIOU: PropTypes.bool, // IOU report ID associated with current report iouReportID: PropTypes.number, @@ -42,6 +42,7 @@ const propTypes = { const defaultProps = { iouReportID: undefined, + hasOutstandingIOU: false, }; class ReportActionItem extends Component { From f2fceb951dbcb3812524bdc1157b833aed2aeb33 Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Wed, 21 Apr 2021 01:12:20 +0100 Subject: [PATCH 19/32] Fixed lint error --- src/libs/actions/Report.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 1c7d8c0709a2..32ce8c8e4fd4 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -47,7 +47,11 @@ Onyx.connect({ const allReports = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT, - callback: val => val ? allReports[val.reportID] = val: {}, + callback: (val) => { + if (val && val.reportID) { + allReports[val.reportID] = val; + } + }, }); const typingWatchTimers = {}; From fb44a6fc5c77b458f5b3478693fa3ee7e29b1b93 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Wed, 21 Apr 2021 10:06:29 -1000 Subject: [PATCH 20/32] Move changes to new PR Give personalDetails default to prevent breaking on sign in Reorganize initial API calls a bit fix comment --- src/libs/actions/Report.js | 83 +++++++++---------- .../home/report/ReportActionItemSingle.js | 7 +- src/pages/home/sidebar/SidebarLinks.js | 12 +++ 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index cd3e7cfbe6fe..4be2bbaec676 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -315,7 +315,6 @@ function fetchChatReportsByIDs(chatList) { // than updating props for each report and re-rendering had merge been used. Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT_IOUS, reportIOUData); Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, simplifiedReports); - Onyx.set(ONYXKEYS.INITIAL_REPORT_DATA_LOADED, true); // Fetch the personal details if there are any PersonalDetails.getFromReportParticipants(Object.values(simplifiedReports)); @@ -580,13 +579,14 @@ function unsubscribeFromReportChannel(reportID) { * set of participants and redirect to it. * * @param {String[]} participants + * @returns {Promise} */ function fetchOrCreateChatReport(participants) { if (participants.length < 2) { throw new Error('fetchOrCreateChatReport() must have at least two participants'); } - API.CreateChatReport({ + return API.CreateChatReport({ emailList: participants.join(','), }) .then((data) => { @@ -603,33 +603,6 @@ function fetchOrCreateChatReport(participants) { }); } -/** - * Get all chat reports and provide the proper report name - * by fetching sharedReportList and personalDetails - * - * @returns {Promise} only used internally when fetchAll() is called - */ -function fetchChatReports() { - return API.Get({ - returnValueList: 'chatList', - }) - .then((response) => { - if (response.jsonCode !== 200) { - return; - } - - // Get all the chat reports if they have any, otherwise create one with concierge - if (lodashGet(response, 'chatList', []).length) { - // The string cast here is necessary as Get rvl='chatList' may return an int - fetchChatReportsByIDs(String(response.chatList).split(',')); - } else { - fetchOrCreateChatReport([currentUserEmail, 'concierge@expensify.com']); - } - - return response.chatList; - }); -} - /** * Get the actions of a report * @@ -676,28 +649,50 @@ function fetchActions(reportID, offset) { * @param {Boolean} shouldRecordHomePageTiming whether or not performance timing should be measured */ function fetchAll(shouldRedirectToReport = true, shouldRecordHomePageTiming = false) { - fetchChatReports() - .then((reportIDs) => { - if (shouldRedirectToReport) { - // Update currentlyViewedReportID to be our first reportID from our report collection if we don't have - // one already. - if (lastViewedReportID) { - return; - } + let reportIDs = []; - const firstReportID = _.first(reportIDs); - const currentReportID = firstReportID ? String(firstReportID) : ''; - Onyx.merge(ONYXKEYS.CURRENTLY_VIEWED_REPORTID, currentReportID); + API.Get({ + returnValueList: 'chatList', + }) + .then((response) => { + if (response.jsonCode !== 200) { + return; } - Log.info('[Report] Fetching report actions for reports', true, {reportIDs}); - _.each(reportIDs, (reportID) => { - fetchActions(reportID); - }); + // The string cast here is necessary as Get rvl='chatList' may return an int + reportIDs = String(response.chatList).split(','); + + // Get all the chat reports if they have any, otherwise create one with concierge + if (reportIDs.length) { + return fetchChatReportsByIDs(reportIDs); + } + + return fetchOrCreateChatReport([currentUserEmail, 'concierge@expensify.com']); + }) + .then(() => { + Onyx.set(ONYXKEYS.INITIAL_REPORT_DATA_LOADED, true); if (shouldRecordHomePageTiming) { Timing.end(CONST.TIMING.HOMEPAGE_REPORTS_LOADED); } + + // Delay fetching report history as it significantly increases sign in to interactive time + setTimeout(() => { + Log.info('[Report] Fetching report actions for reports', true, {reportIDs}); + _.each(reportIDs, (reportID) => { + fetchActions(reportID); + }); + }, 8000); + + // Update currentlyViewedReportID to be our first reportID from our report collection if we don't have + // one already. + if (!shouldRedirectToReport || lastViewedReportID) { + return; + } + + const firstReportID = _.first(reportIDs); + const currentReportID = firstReportID ? String(firstReportID) : ''; + Onyx.merge(ONYXKEYS.CURRENTLY_VIEWED_REPORTID, currentReportID); }); } diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index e9cc33f9d085..dca3f3d14ebb 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -18,7 +18,11 @@ const propTypes = { action: PropTypes.shape(ReportActionPropTypes).isRequired, // All of the personalDetails - personalDetails: PropTypes.objectOf(personalDetailsPropType).isRequired, + personalDetails: PropTypes.objectOf(personalDetailsPropType), +}; + +const defaultProps = { + personalDetails: {}, }; const ReportActionItemSingle = ({action, personalDetails}) => { @@ -59,6 +63,7 @@ const ReportActionItemSingle = ({action, personalDetails}) => { }; ReportActionItemSingle.propTypes = propTypes; +ReportActionItemSingle.defaultProps = defaultProps; export default withOnyx({ personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 7f24fa96180e..c42f2e4a4e03 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -68,6 +68,9 @@ const propTypes = { // The chat priority mode priorityMode: PropTypes.string, + + // Whether we have the necessary report data to load the sidebar + initialReportDataLoaded: PropTypes.bool, }; const defaultProps = { @@ -80,6 +83,7 @@ const defaultProps = { network: null, currentlyViewedReportID: '', priorityMode: CONST.PRIORITY_MODE.DEFAULT, + initialReportDataLoaded: false, }; class SidebarLinks extends React.Component { @@ -88,6 +92,11 @@ class SidebarLinks extends React.Component { } render() { + // Wait until the reports are actually loaded before displaying the LHN + if (!this.props.initialReportDataLoaded) { + return null; + } + const activeReportID = parseInt(this.props.currentlyViewedReportID, 10); const {recentReports} = getSidebarOptions( @@ -184,5 +193,8 @@ export default compose( priorityMode: { key: ONYXKEYS.NVP_PRIORITY_MODE, }, + initialReportDataLoaded: { + key: ONYXKEYS.INITIAL_REPORT_DATA_LOADED, + }, }), )(SidebarLinks); From 1ab7855f983474c1939501a19ff3f8c8333d01fd Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Thu, 22 Apr 2021 00:58:54 +0100 Subject: [PATCH 21/32] Updated comment and pod install --- ios/ExpensifyCash.xcodeproj/project.pbxproj | 38 ++ ios/Podfile.lock | 580 ++++++++++---------- src/libs/actions/Report.js | 9 +- 3 files changed, 345 insertions(+), 282 deletions(-) diff --git a/ios/ExpensifyCash.xcodeproj/project.pbxproj b/ios/ExpensifyCash.xcodeproj/project.pbxproj index 27ca296fa44c..4a105bffbdda 100644 --- a/ios/ExpensifyCash.xcodeproj/project.pbxproj +++ b/ios/ExpensifyCash.xcodeproj/project.pbxproj @@ -208,6 +208,7 @@ 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, F2B8013B9E9ECAB2B509E702 /* [CP] Copy Pods Resources */, + B6C8E0BF2CC222D8992DC951 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -232,6 +233,7 @@ C9071365B664DE0D85DC5195 /* [CP] Copy Pods Resources */, CF6259710B5A341870372EA2 /* [CP-User] [RNFB] Core Configuration */, ED5B8E90A3384FC6A128FB95 /* [CP-User] [RNFB] Crashlytics Configuration */, + F937A3C3A673918386E1BA72 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -371,6 +373,24 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + B6C8E0BF2CC222D8992DC951 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; C9071365B664DE0D85DC5195 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -647,6 +667,24 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; + F937A3C3A673918386E1BA72 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; FD10A7F022414F080027D42C /* Start Packager */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b1af438affe9..80e725272f40 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -13,16 +13,15 @@ PODS: - Airship/Core - boost-for-react-native (1.63.0) - CocoaAsyncSocket (7.6.5) - - CocoaLibEvent (1.0.0) - DoubleConversion (1.1.6) - - FBLazyVector (0.63.3) - - FBReactNativeSpec (0.63.3): - - Folly (= 2020.01.13.00) - - RCTRequired (= 0.63.3) - - RCTTypeSafety (= 0.63.3) - - React-Core (= 0.63.3) - - React-jsi (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) + - FBLazyVector (0.64.0) + - FBReactNativeSpec (0.64.0): + - RCT-Folly (= 2020.01.13.00) + - RCTRequired (= 0.64.0) + - RCTTypeSafety (= 0.64.0) + - React-Core (= 0.64.0) + - React-jsi (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) - Firebase/Analytics (6.34.0): - Firebase/Core - Firebase/Core (6.34.0): @@ -62,61 +61,52 @@ PODS: - GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/UserDefaults (~> 6.7) - PromisesObjC (~> 1.2) - - Flipper (0.54.0): - - Flipper-Folly (~> 2.2) - - Flipper-RSocket (~> 1.1) + - Flipper (0.75.1): + - Flipper-Folly (~> 2.5) + - Flipper-RSocket (~> 1.3) - Flipper-DoubleConversion (1.1.7) - - Flipper-Folly (2.3.0): + - Flipper-Folly (2.5.1): - boost-for-react-native - - CocoaLibEvent (~> 1.0) - Flipper-DoubleConversion - Flipper-Glog - - OpenSSL-Universal (= 1.0.2.20) + - libevent (~> 2.1.12) + - OpenSSL-Universal (= 1.1.180) - Flipper-Glog (0.3.6) - Flipper-PeerTalk (0.0.4) - - Flipper-RSocket (1.1.0): - - Flipper-Folly (~> 2.2) - - FlipperKit (0.54.0): - - FlipperKit/Core (= 0.54.0) - - FlipperKit/Core (0.54.0): - - Flipper (~> 0.54.0) + - Flipper-RSocket (1.3.1): + - Flipper-Folly (~> 2.5) + - FlipperKit (0.75.1): + - FlipperKit/Core (= 0.75.1) + - FlipperKit/Core (0.75.1): + - Flipper (~> 0.75.1) - FlipperKit/CppBridge - FlipperKit/FBCxxFollyDynamicConvert - FlipperKit/FBDefines - FlipperKit/FKPortForwarding - - FlipperKit/CppBridge (0.54.0): - - Flipper (~> 0.54.0) - - FlipperKit/FBCxxFollyDynamicConvert (0.54.0): - - Flipper-Folly (~> 2.2) - - FlipperKit/FBDefines (0.54.0) - - FlipperKit/FKPortForwarding (0.54.0): + - FlipperKit/CppBridge (0.75.1): + - Flipper (~> 0.75.1) + - FlipperKit/FBCxxFollyDynamicConvert (0.75.1): + - Flipper-Folly (~> 2.5) + - FlipperKit/FBDefines (0.75.1) + - FlipperKit/FKPortForwarding (0.75.1): - CocoaAsyncSocket (~> 7.6) - Flipper-PeerTalk (~> 0.0.4) - - FlipperKit/FlipperKitHighlightOverlay (0.54.0) - - FlipperKit/FlipperKitLayoutPlugin (0.54.0): + - FlipperKit/FlipperKitHighlightOverlay (0.75.1) + - FlipperKit/FlipperKitLayoutPlugin (0.75.1): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutTextSearchable - YogaKit (~> 1.18) - - FlipperKit/FlipperKitLayoutTextSearchable (0.54.0) - - FlipperKit/FlipperKitNetworkPlugin (0.54.0): + - FlipperKit/FlipperKitLayoutTextSearchable (0.75.1) + - FlipperKit/FlipperKitNetworkPlugin (0.75.1): - FlipperKit/Core - - FlipperKit/FlipperKitReactPlugin (0.54.0): + - FlipperKit/FlipperKitReactPlugin (0.75.1): - FlipperKit/Core - - FlipperKit/FlipperKitUserDefaultsPlugin (0.54.0): + - FlipperKit/FlipperKitUserDefaultsPlugin (0.75.1): - FlipperKit/Core - - FlipperKit/SKIOSNetworkPlugin (0.54.0): + - FlipperKit/SKIOSNetworkPlugin (0.75.1): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - - Folly (2020.01.13.00): - - boost-for-react-native - - DoubleConversion - - Folly/Default (= 2020.01.13.00) - - glog - - Folly/Default (2020.01.13.00): - - boost-for-react-native - - DoubleConversion - - glog - glog (0.3.5) - GoogleAppMeasurement (6.9.0): - GoogleUtilities/AppDelegateSwizzler (~> 6.7) @@ -145,181 +135,207 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (6.7.2): - GoogleUtilities/Logger + - libevent (2.1.12) - nanopb (1.30906.0): - nanopb/decode (= 1.30906.0) - nanopb/encode (= 1.30906.0) - nanopb/decode (1.30906.0) - nanopb/encode (1.30906.0) - - OpenSSL-Universal (1.0.2.20): - - OpenSSL-Universal/Static (= 1.0.2.20) - - OpenSSL-Universal/Static (1.0.2.20) + - OpenSSL-Universal (1.1.180) - PromisesObjC (1.2.11) - - RCTRequired (0.63.3) - - RCTTypeSafety (0.63.3): - - FBLazyVector (= 0.63.3) - - Folly (= 2020.01.13.00) - - RCTRequired (= 0.63.3) - - React-Core (= 0.63.3) - - React (0.63.3): - - React-Core (= 0.63.3) - - React-Core/DevSupport (= 0.63.3) - - React-Core/RCTWebSocket (= 0.63.3) - - React-RCTActionSheet (= 0.63.3) - - React-RCTAnimation (= 0.63.3) - - React-RCTBlob (= 0.63.3) - - React-RCTImage (= 0.63.3) - - React-RCTLinking (= 0.63.3) - - React-RCTNetwork (= 0.63.3) - - React-RCTSettings (= 0.63.3) - - React-RCTText (= 0.63.3) - - React-RCTVibration (= 0.63.3) - - React-callinvoker (0.63.3) - - React-Core (0.63.3): - - Folly (= 2020.01.13.00) + - RCT-Folly (2020.01.13.00): + - boost-for-react-native + - DoubleConversion + - glog + - RCT-Folly/Default (= 2020.01.13.00) + - RCT-Folly/Default (2020.01.13.00): + - boost-for-react-native + - DoubleConversion + - glog + - RCTRequired (0.64.0) + - RCTTypeSafety (0.64.0): + - FBLazyVector (= 0.64.0) + - RCT-Folly (= 2020.01.13.00) + - RCTRequired (= 0.64.0) + - React-Core (= 0.64.0) + - React (0.64.0): + - React-Core (= 0.64.0) + - React-Core/DevSupport (= 0.64.0) + - React-Core/RCTWebSocket (= 0.64.0) + - React-RCTActionSheet (= 0.64.0) + - React-RCTAnimation (= 0.64.0) + - React-RCTBlob (= 0.64.0) + - React-RCTImage (= 0.64.0) + - React-RCTLinking (= 0.64.0) + - React-RCTNetwork (= 0.64.0) + - React-RCTSettings (= 0.64.0) + - React-RCTText (= 0.64.0) + - React-RCTVibration (= 0.64.0) + - React-callinvoker (0.64.0) + - React-Core (0.64.0): - glog - - React-Core/Default (= 0.63.3) - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - RCT-Folly (= 2020.01.13.00) + - React-Core/Default (= 0.64.0) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/CoreModulesHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/CoreModulesHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/Default (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/Default (0.64.0): - glog - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - RCT-Folly (= 2020.01.13.00) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/DevSupport (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/DevSupport (0.64.0): - glog - - React-Core/Default (= 0.63.3) - - React-Core/RCTWebSocket (= 0.63.3) - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) - - React-jsinspector (= 0.63.3) + - RCT-Folly (= 2020.01.13.00) + - React-Core/Default (= 0.64.0) + - React-Core/RCTWebSocket (= 0.64.0) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-jsinspector (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTActionSheetHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTActionSheetHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTAnimationHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTAnimationHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTBlobHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTBlobHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTImageHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTImageHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTLinkingHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTLinkingHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTNetworkHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTNetworkHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTSettingsHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTSettingsHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTTextHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTTextHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTVibrationHeaders (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTVibrationHeaders (0.64.0): - glog + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-Core/RCTWebSocket (0.63.3): - - Folly (= 2020.01.13.00) + - React-Core/RCTWebSocket (0.64.0): - glog - - React-Core/Default (= 0.63.3) - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsiexecutor (= 0.63.3) + - RCT-Folly (= 2020.01.13.00) + - React-Core/Default (= 0.64.0) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsiexecutor (= 0.64.0) + - React-perflogger (= 0.64.0) - Yoga - - React-CoreModules (0.63.3): - - FBReactNativeSpec (= 0.63.3) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.3) - - React-Core/CoreModulesHeaders (= 0.63.3) - - React-jsi (= 0.63.3) - - React-RCTImage (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) - - React-cxxreact (0.63.3): + - React-CoreModules (0.64.0): + - FBReactNativeSpec (= 0.64.0) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.0) + - React-Core/CoreModulesHeaders (= 0.64.0) + - React-jsi (= 0.64.0) + - React-RCTImage (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) + - React-cxxreact (0.64.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-callinvoker (= 0.63.3) - - React-jsinspector (= 0.63.3) - - React-jsi (0.63.3): + - RCT-Folly (= 2020.01.13.00) + - React-callinvoker (= 0.64.0) + - React-jsi (= 0.64.0) + - React-jsinspector (= 0.64.0) + - React-perflogger (= 0.64.0) + - React-runtimeexecutor (= 0.64.0) + - React-jsi (0.64.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-jsi/Default (= 0.63.3) - - React-jsi/Default (0.63.3): + - RCT-Folly (= 2020.01.13.00) + - React-jsi/Default (= 0.64.0) + - React-jsi/Default (0.64.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-jsiexecutor (0.63.3): + - RCT-Folly (= 2020.01.13.00) + - React-jsiexecutor (0.64.0): - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) - - React-jsinspector (0.63.3) + - RCT-Folly (= 2020.01.13.00) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-perflogger (= 0.64.0) + - React-jsinspector (0.64.0) - react-native-config (1.4.1): - react-native-config/App (= 1.4.1) - react-native-config/App (1.4.1): @@ -338,70 +354,72 @@ PODS: - React - react-native-safe-area-context (3.1.8): - React-Core - - React-RCTActionSheet (0.63.3): - - React-Core/RCTActionSheetHeaders (= 0.63.3) - - React-RCTAnimation (0.63.3): - - FBReactNativeSpec (= 0.63.3) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.3) - - React-Core/RCTAnimationHeaders (= 0.63.3) - - React-jsi (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) - - React-RCTBlob (0.63.3): - - FBReactNativeSpec (= 0.63.3) - - Folly (= 2020.01.13.00) - - React-Core/RCTBlobHeaders (= 0.63.3) - - React-Core/RCTWebSocket (= 0.63.3) - - React-jsi (= 0.63.3) - - React-RCTNetwork (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) - - React-RCTImage (0.63.3): - - FBReactNativeSpec (= 0.63.3) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.3) - - React-Core/RCTImageHeaders (= 0.63.3) - - React-jsi (= 0.63.3) - - React-RCTNetwork (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) - - React-RCTLinking (0.63.3): - - FBReactNativeSpec (= 0.63.3) - - React-Core/RCTLinkingHeaders (= 0.63.3) - - React-jsi (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) - - React-RCTNetwork (0.63.3): - - FBReactNativeSpec (= 0.63.3) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.3) - - React-Core/RCTNetworkHeaders (= 0.63.3) - - React-jsi (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) - - React-RCTSettings (0.63.3): - - FBReactNativeSpec (= 0.63.3) - - Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.63.3) - - React-Core/RCTSettingsHeaders (= 0.63.3) - - React-jsi (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) - - React-RCTText (0.63.3): - - React-Core/RCTTextHeaders (= 0.63.3) - - React-RCTVibration (0.63.3): - - FBReactNativeSpec (= 0.63.3) - - Folly (= 2020.01.13.00) - - React-Core/RCTVibrationHeaders (= 0.63.3) - - React-jsi (= 0.63.3) - - ReactCommon/turbomodule/core (= 0.63.3) - - ReactCommon/turbomodule/core (0.63.3): + - React-perflogger (0.64.0) + - React-RCTActionSheet (0.64.0): + - React-Core/RCTActionSheetHeaders (= 0.64.0) + - React-RCTAnimation (0.64.0): + - FBReactNativeSpec (= 0.64.0) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.0) + - React-Core/RCTAnimationHeaders (= 0.64.0) + - React-jsi (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) + - React-RCTBlob (0.64.0): + - FBReactNativeSpec (= 0.64.0) + - RCT-Folly (= 2020.01.13.00) + - React-Core/RCTBlobHeaders (= 0.64.0) + - React-Core/RCTWebSocket (= 0.64.0) + - React-jsi (= 0.64.0) + - React-RCTNetwork (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) + - React-RCTImage (0.64.0): + - FBReactNativeSpec (= 0.64.0) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.0) + - React-Core/RCTImageHeaders (= 0.64.0) + - React-jsi (= 0.64.0) + - React-RCTNetwork (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) + - React-RCTLinking (0.64.0): + - FBReactNativeSpec (= 0.64.0) + - React-Core/RCTLinkingHeaders (= 0.64.0) + - React-jsi (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) + - React-RCTNetwork (0.64.0): + - FBReactNativeSpec (= 0.64.0) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.0) + - React-Core/RCTNetworkHeaders (= 0.64.0) + - React-jsi (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) + - React-RCTSettings (0.64.0): + - FBReactNativeSpec (= 0.64.0) + - RCT-Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.64.0) + - React-Core/RCTSettingsHeaders (= 0.64.0) + - React-jsi (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) + - React-RCTText (0.64.0): + - React-Core/RCTTextHeaders (= 0.64.0) + - React-RCTVibration (0.64.0): + - FBReactNativeSpec (= 0.64.0) + - RCT-Folly (= 2020.01.13.00) + - React-Core/RCTVibrationHeaders (= 0.64.0) + - React-jsi (= 0.64.0) + - ReactCommon/turbomodule/core (= 0.64.0) + - React-runtimeexecutor (0.64.0): + - React-jsi (= 0.64.0) + - ReactCommon/turbomodule/core (0.64.0): - DoubleConversion - - Folly (= 2020.01.13.00) - glog - - React-callinvoker (= 0.63.3) - - React-Core (= 0.63.3) - - React-cxxreact (= 0.63.3) - - React-jsi (= 0.63.3) + - RCT-Folly (= 2020.01.13.00) + - React-callinvoker (= 0.64.0) + - React-Core (= 0.64.0) + - React-cxxreact (= 0.64.0) + - React-jsi (= 0.64.0) + - React-perflogger (= 0.64.0) - rn-fetch-blob (0.12.0): - React-Core - - RNBootSplash (3.2.0): - - React-Core - RNCAsyncStorage (1.12.1): - React-Core - RNCClipboard (1.5.1): @@ -439,28 +457,28 @@ PODS: DEPENDENCIES: - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) - - Flipper (~> 0.54.0) + - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) + - Flipper (~> 0.75.1) - Flipper-DoubleConversion (= 1.1.7) - - Flipper-Folly (~> 2.2) + - Flipper-Folly (~> 2.5) - Flipper-Glog (= 0.3.6) - Flipper-PeerTalk (~> 0.0.4) - - Flipper-RSocket (~> 1.1) - - FlipperKit (~> 0.54.0) - - FlipperKit/Core (~> 0.54.0) - - FlipperKit/CppBridge (~> 0.54.0) - - FlipperKit/FBCxxFollyDynamicConvert (~> 0.54.0) - - FlipperKit/FBDefines (~> 0.54.0) - - FlipperKit/FKPortForwarding (~> 0.54.0) - - FlipperKit/FlipperKitHighlightOverlay (~> 0.54.0) - - FlipperKit/FlipperKitLayoutPlugin (~> 0.54.0) - - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.54.0) - - FlipperKit/FlipperKitNetworkPlugin (~> 0.54.0) - - FlipperKit/FlipperKitReactPlugin (~> 0.54.0) - - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.54.0) - - FlipperKit/SKIOSNetworkPlugin (~> 0.54.0) - - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) + - Flipper-RSocket (~> 1.3) + - FlipperKit (~> 0.75.1) + - FlipperKit/Core (~> 0.75.1) + - FlipperKit/CppBridge (~> 0.75.1) + - FlipperKit/FBCxxFollyDynamicConvert (~> 0.75.1) + - FlipperKit/FBDefines (~> 0.75.1) + - FlipperKit/FKPortForwarding (~> 0.75.1) + - FlipperKit/FlipperKitHighlightOverlay (~> 0.75.1) + - FlipperKit/FlipperKitLayoutPlugin (~> 0.75.1) + - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.75.1) + - FlipperKit/FlipperKitNetworkPlugin (~> 0.75.1) + - FlipperKit/FlipperKitReactPlugin (~> 0.75.1) + - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.75.1) + - FlipperKit/SKIOSNetworkPlugin (~> 0.75.1) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) + - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - React (from `../node_modules/react-native/`) @@ -481,6 +499,7 @@ DEPENDENCIES: - "react-native-progress-bar-android (from `../node_modules/@react-native-community/progress-bar-android`)" - "react-native-progress-view (from `../node_modules/@react-native-community/progress-view`)" - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) + - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) @@ -490,9 +509,9 @@ DEPENDENCIES: - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) - React-RCTText (from `../node_modules/react-native/Libraries/Text`) - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) + - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - rn-fetch-blob (from `../node_modules/rn-fetch-blob`) - - RNBootSplash (from `../node_modules/react-native-bootsplash`) - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" @@ -512,7 +531,6 @@ SPEC REPOS: - Airship - boost-for-react-native - CocoaAsyncSocket - - CocoaLibEvent - Firebase - FirebaseAnalytics - FirebaseCore @@ -529,6 +547,7 @@ SPEC REPOS: - GoogleAppMeasurement - GoogleDataTransport - GoogleUtilities + - libevent - nanopb - OpenSSL-Universal - PromisesObjC @@ -540,11 +559,11 @@ EXTERNAL SOURCES: FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" FBReactNativeSpec: - :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" - Folly: - :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" + :path: "../node_modules/react-native/React/FBReactNativeSpec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" + RCT-Folly: + :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: :path: "../node_modules/react-native/Libraries/RCTRequired" RCTTypeSafety: @@ -581,6 +600,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/progress-view" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" + React-perflogger: + :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: :path: "../node_modules/react-native/Libraries/ActionSheetIOS" React-RCTAnimation: @@ -599,12 +620,12 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/Text" React-RCTVibration: :path: "../node_modules/react-native/Libraries/Vibration" + React-runtimeexecutor: + :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" ReactCommon: :path: "../node_modules/react-native/ReactCommon" rn-fetch-blob: :path: "../node_modules/rn-fetch-blob" - RNBootSplash: - :path: "../node_modules/react-native-bootsplash" RNCAsyncStorage: :path: "../node_modules/@react-native-community/async-storage" RNCClipboard: @@ -636,41 +657,41 @@ SPEC CHECKSUMS: Airship: 02ad73780f9eed21870e36b0aaab327acda6a102 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 - CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f DoubleConversion: cde416483dac037923206447da6e1454df403714 - FBLazyVector: 878b59e31113e289e275165efbe4b54fa614d43d - FBReactNativeSpec: 7da9338acfb98d4ef9e5536805a0704572d33c2f + FBLazyVector: 49cbe4b43e445b06bf29199b6ad2057649e4c8f5 + FBReactNativeSpec: 9fd67b7512e849d0c026842367e27e791bd7bba7 Firebase: c23a36d9e4cdf7877dfcba8dd0c58add66358999 FirebaseAnalytics: 3bb096873ee0d7fa4b6c70f5e9166b6da413cc7f FirebaseCore: d3a978a3cfa3240bf7e4ba7d137fdf5b22b628ec FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 FirebaseCrashlytics: 1a747c9cc084a24dc6d9511c991db1cd078154eb FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 - Flipper: be611d4b742d8c87fbae2ca5f44603a02539e365 + Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 - Flipper-Folly: e4493b013c02d9347d5e0cb4d128680239f6c78a + Flipper-Folly: f7a3caafbd74bda4827954fd7a6e000e36355489 Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 - Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7 - FlipperKit: ab353d41aea8aae2ea6daaf813e67496642f3d7d - Folly: b73c3869541e86821df3c387eb0af5f65addfab4 + Flipper-RSocket: 127954abe8b162fcaf68d2134d34dc2bd7076154 + FlipperKit: 8a20b5c5fcf9436cac58551dc049867247f64b00 glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 GoogleAppMeasurement: a6a3a066369828db64eda428cb2856dc1cdc7c4e GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 + libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc - OpenSSL-Universal: ff34003318d5e1163e9529b08470708e389ffcdd + OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f - RCTRequired: 48884c74035a0b5b76dbb7a998bd93bcfc5f2047 - RCTTypeSafety: edf4b618033c2f1c5b7bc3d90d8e085ed95ba2ab - React: f36e90f3ceb976546e97df3403e37d226f79d0e3 - React-callinvoker: 18874f621eb96625df7a24a7dc8d6e07391affcd - React-Core: ac3d816b8e3493970153f4aaf0cff18af0bb95e6 - React-CoreModules: 4016d3a4e518bcfc4f5a51252b5a05692ca6f0e1 - React-cxxreact: ffc9129013b87cb36cf3f30a86695a3c397b0f99 - React-jsi: df07aa95b39c5be3e41199921509bfa929ed2b9d - React-jsiexecutor: b56c03e61c0dd5f5801255f2160a815f4a53d451 - React-jsinspector: 8e68ffbfe23880d3ee9bafa8be2777f60b25cbe2 + RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c + RCTRequired: 2f8cb5b7533219bf4218a045f92768129cf7050a + RCTTypeSafety: 512728b73549e72ad7330b92f3d42936f2a4de5b + React: 98eac01574128a790f0bbbafe2d1a8607291ac24 + React-callinvoker: def3f7fae16192df68d9b69fd4bbb59092ee36bc + React-Core: 70a52aa5dbe9b83befae82038451a7df9fd54c5a + React-CoreModules: 052edef46117862e2570eb3a0f06d81c61d2c4b8 + React-cxxreact: c1dc71b30653cfb4770efdafcbdc0ad6d388baab + React-jsi: 74341196d9547cbcbcfa4b3bbbf03af56431d5a1 + React-jsiexecutor: 06a9c77b56902ae7ffcdd7a4905f664adc5d237b + React-jsinspector: 0ae35a37b20d5e031eb020a69cc5afdbd6406301 react-native-config: d8b45133fd13d4f23bd2064b72f6e2c08b2763ed react-native-document-picker: b3e78a8f7fef98b5cb069f20fc35797d55e68e28 react-native-image-picker: 32d1ad2c0024ca36161ae0d5c2117e2d6c441f11 @@ -679,18 +700,19 @@ SPEC CHECKSUMS: react-native-progress-bar-android: ce95a69f11ac580799021633071368d08aaf9ad8 react-native-progress-view: 5816e8a6be812c2b122c6225a2a3db82d9008640 react-native-safe-area-context: 01158a92c300895d79dee447e980672dc3fb85a6 - React-RCTActionSheet: 53ea72699698b0b47a6421cb1c8b4ab215a774aa - React-RCTAnimation: 1befece0b5183c22ae01b966f5583f42e69a83c2 - React-RCTBlob: 0b284339cbe4b15705a05e2313a51c6d8b51fa40 - React-RCTImage: d1756599ebd4dc2cb19d1682fe67c6b976658387 - React-RCTLinking: 9af0a51c6d6a4dd1674daadafffc6d03033a6d18 - React-RCTNetwork: 332c83929cc5eae0b3bbca4add1d668e1fc18bda - React-RCTSettings: d6953772cfd55f2c68ad72b7ef29efc7ec49f773 - React-RCTText: 65a6de06a7389098ce24340d1d3556015c38f746 - React-RCTVibration: 8e9fb25724a0805107fc1acc9075e26f814df454 - ReactCommon: 4167844018c9ed375cc01a843e9ee564399e53c3 + React-perflogger: 9c547d8f06b9bf00cb447f2b75e8d7f19b7e02af + React-RCTActionSheet: 3080b6e12e0e1a5b313c8c0050699b5c794a1b11 + React-RCTAnimation: 3f96f21a497ae7dabf4d2f150ee43f906aaf516f + React-RCTBlob: 283b8e5025e7f954176bc48164f846909002f3ed + React-RCTImage: 5088a484faac78f2d877e1b79125d3bb1ea94a16 + React-RCTLinking: 5e8fbb3e9a8bc2e4e3eb15b1eb8bda5fcac27b8c + React-RCTNetwork: 38ec277217b1e841d5e6a1fa78da65b9212ccb28 + React-RCTSettings: 242d6e692108c3de4f3bb74b7586a8799e9ab070 + React-RCTText: 8746736ac8eb5a4a74719aa695b7a236a93a83d2 + React-RCTVibration: 0fd6b21751a33cb72fce1a4a33ab9678416d307a + React-runtimeexecutor: cad74a1eaa53ee6e7a3620231939d8fe2c6afcf0 + ReactCommon: cfe2b7fd20e0dbd2d1185cd7d8f99633fbc5ff05 rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba - RNBootSplash: 3123ba68fe44d8be09a014e89cc8f0f55b68a521 RNCAsyncStorage: cb9a623793918c6699586281f0b51cbc38f046f9 RNCClipboard: 5e299c6df8e0c98f3d7416b86ae563d3a9f768a3 RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459 @@ -703,7 +725,7 @@ SPEC CHECKSUMS: RNScreens: b6c9607e6fe47c1b6e2f1910d2acd46dd7ecea3a RNSVG: ce9d996113475209013317e48b05c21ee988d42e urbanairship-react-native: dfb6dc22b2f41ccaadd636b73d51b448cd1b2bbc - Yoga: 7d13633d129fd179e01b8953d38d47be90db185a + Yoga: 8c8436d4171c87504c648ae23b1d81242bdf3bbf YogaKit: f782866e155069a2cca2517aafea43200b01fd5a PODFILE CHECKSUM: 41b806c7f131f87b716be1f1f9377532d6c9e43a diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 32ce8c8e4fd4..fcf0c52a1d36 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -291,10 +291,13 @@ function fetchChatReportsByIDs(chatList) { return; } - // If we don't have one participant (other than the current user), this is not an IOU + // Group chat reports cannot and should not be associated with a specific IOU report const participants = getParticipantEmailsFromReport(chatReport); - if (participants.length !== 1) { - Log.alert('[Report] Report with IOU action has more than 2 participants', true, { + if (participants.length > 1) { + return; + } + if (participants.length === 0) { + Log.alert('[Report] Report with IOU action but does not have any participant.', true, { reportID: chatReport.reportID, participants, }); From 67c4a3fee74cf3e5e1975cc3e4c41599a8b62d24 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Wed, 21 Apr 2021 14:09:32 -1000 Subject: [PATCH 22/32] Make less ugly --- src/libs/Navigation/AppNavigator/AuthScreens.js | 4 ++-- src/libs/actions/Report.js | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index 2269e198f9e5..ad3190e4f990 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -10,7 +10,7 @@ import CONST from '../../../CONST'; import compose from '../../compose'; import { subscribeToReportCommentEvents, - fetchAll as fetchAllReports, + fetchAllReports, } from '../../actions/Report'; import * as PersonalDetails from '../../actions/PersonalDetails'; import * as Pusher from '../../Pusher/pusher'; @@ -119,7 +119,7 @@ class AuthScreens extends React.Component { PersonalDetails.fetch(); User.getUserDetails(); User.getBetas(); - fetchAllReports(true, true); + fetchAllReports(true, true, 8000); fetchCountryCodeByRequestIP(); UnreadIndicatorUpdater.listenForReportChanges(); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 4be2bbaec676..ee114c6acf79 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -270,7 +270,7 @@ function updateIOUReportData(chatReport) { * chat report IDs * * @param {Array} chatList - * @return {Promise} only used internally when fetchAll() is called + * @return {Promise} only used internally when fetchAllReports() is called */ function fetchChatReportsByIDs(chatList) { let fetchedReports; @@ -647,8 +647,9 @@ function fetchActions(reportID, offset) { * * @param {Boolean} shouldRedirectToReport this is set to false when the network reconnect code runs * @param {Boolean} shouldRecordHomePageTiming whether or not performance timing should be measured + * @param {Number} fetchActionsDelay */ -function fetchAll(shouldRedirectToReport = true, shouldRecordHomePageTiming = false) { +function fetchAllReports(shouldRedirectToReport = true, shouldRecordHomePageTiming = false, fetchActionsDelay = 0) { let reportIDs = []; API.Get({ @@ -676,13 +677,13 @@ function fetchAll(shouldRedirectToReport = true, shouldRecordHomePageTiming = fa Timing.end(CONST.TIMING.HOMEPAGE_REPORTS_LOADED); } - // Delay fetching report history as it significantly increases sign in to interactive time - setTimeout(() => { + // Optionally delay fetching report history as it significantly increases sign in to interactive time + _.delay(() => { Log.info('[Report] Fetching report actions for reports', true, {reportIDs}); _.each(reportIDs, (reportID) => { fetchActions(reportID); }); - }, 8000); + }, fetchActionsDelay); // Update currentlyViewedReportID to be our first reportID from our report collection if we don't have // one already. @@ -889,11 +890,11 @@ Onyx.connect({ // When the app reconnects from being offline, fetch all of the reports and their actions NetworkConnection.onReconnect(() => { - fetchAll(false); + fetchAllReports(false); }); export { - fetchAll, + fetchAllReports, fetchActions, fetchOrCreateChatReport, addAction, From 184c68f3faff4a2dec102059a076c2712b46b197 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Thu, 22 Apr 2021 07:29:07 +0530 Subject: [PATCH 23/32] fix: offline messages are grayed out even if online --- src/pages/home/report/ReportActionItem.js | 17 +++++++++++++++-- .../home/report/ReportActionItemGrouped.js | 7 +++++-- .../home/report/ReportActionItemMessage.js | 7 +++++-- src/pages/home/report/ReportActionItemSingle.js | 7 +++++-- src/pages/home/report/ReportActionsView.js | 11 +++++++++++ 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 51a48e7dc3ea..6d3f9a6e0367 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -27,6 +27,9 @@ const propTypes = { // Should we display the new indicator on top of the comment? shouldDisplayNewIndicator: PropTypes.bool.isRequired, + + // Is the network currently offline or not + isOffline: PropTypes.bool.isRequired, }; class ReportActionItem extends Component { @@ -95,8 +98,18 @@ class ReportActionItem extends Component { )} {!this.props.displayAsGroup - ? - : } + ? ( + + ) + : ( + + )} ( +const ReportActionItemGrouped = ({action, isOffline}) => ( - + ); diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index 9b026c7db55c..3311fa47a20f 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -9,11 +9,14 @@ import ReportActionPropTypes from './ReportActionPropTypes'; const propTypes = { // The report action action: PropTypes.shape(ReportActionPropTypes).isRequired, + + // Is the network currently offline or not + isOffline: PropTypes.bool.isRequired, }; -const ReportActionItemMessage = ({action}) => { +const ReportActionItemMessage = ({action, isOffline}) => { // reportActionID is only present when the action is saved onto server. - const isUnsent = action.loading && !action.reportActionID; + const isUnsent = isOffline && action.loading && !action.reportActionID; return ( {_.map(_.compact(action.message), (fragment, index) => ( diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index e9cc33f9d085..4f3bf0ee800a 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -19,9 +19,12 @@ const propTypes = { // All of the personalDetails personalDetails: PropTypes.objectOf(personalDetailsPropType).isRequired, + + // Is the network currently offline or not + isOffline: PropTypes.bool.isRequired, }; -const ReportActionItemSingle = ({action, personalDetails}) => { +const ReportActionItemSingle = ({action, personalDetails, isOffline}) => { const {avatar, displayName} = personalDetails[action.actorEmail] || {}; const avatarUrl = action.automatic ? `${CONST.CLOUDFRONT_URL}/images/icons/concierge_2019.svg` @@ -52,7 +55,7 @@ const ReportActionItemSingle = ({action, personalDetails}) => { ))} - + ); diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 347dd3d5ee48..805ae828f177 100644 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -50,6 +50,12 @@ const propTypes = { // Email of the logged in person email: PropTypes.string, }), + + // Information about the network + network: PropTypes.shape({ + // Is the network currently offline or not + isOffline: PropTypes.bool, + }), }; const defaultProps = { @@ -59,6 +65,7 @@ const defaultProps = { }, reportActions: {}, session: {}, + network: {isOffline: false}, }; class ReportActionsView extends React.Component { @@ -283,6 +290,7 @@ class ReportActionsView extends React.Component { 0 && item.action.sequenceNumber === this.initialNewMarkerPosition} @@ -335,6 +343,9 @@ export default withOnyx({ key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, canEvict: false, }, + network: { + key: ONYXKEYS.NETWORK, + }, session: { key: ONYXKEYS.SESSION, }, From bfbdd8a6e475a6585a8d760baecb68feb3b7174f Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Thu, 22 Apr 2021 08:02:45 -1000 Subject: [PATCH 24/32] Add more comments --- src/libs/Navigation/AppNavigator/AuthScreens.js | 2 +- src/libs/actions/Report.js | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index ad3190e4f990..f983278e2490 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -119,7 +119,7 @@ class AuthScreens extends React.Component { PersonalDetails.fetch(); User.getUserDetails(); User.getBetas(); - fetchAllReports(true, true, 8000); + fetchAllReports(true, true, true); fetchCountryCodeByRequestIP(); UnreadIndicatorUpdater.listenForReportChanges(); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index ee114c6acf79..ee0b73307e49 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -647,9 +647,13 @@ function fetchActions(reportID, offset) { * * @param {Boolean} shouldRedirectToReport this is set to false when the network reconnect code runs * @param {Boolean} shouldRecordHomePageTiming whether or not performance timing should be measured - * @param {Number} fetchActionsDelay + * @param {Boolean} shouldDelayActionsFetch when the app loads we want to delay the fetching of additional actions */ -function fetchAllReports(shouldRedirectToReport = true, shouldRecordHomePageTiming = false, fetchActionsDelay = 0) { +function fetchAllReports( + shouldRedirectToReport = true, + shouldRecordHomePageTiming = false, + shouldDelayActionsFetch = false, +) { let reportIDs = []; API.Get({ @@ -683,7 +687,10 @@ function fetchAllReports(shouldRedirectToReport = true, shouldRecordHomePageTimi _.each(reportIDs, (reportID) => { fetchActions(reportID); }); - }, fetchActionsDelay); + + // We are waiting 8 seconds since this provides a good time window to allow the UI to finish loading before + // bogging it down with more requests and operations. + }, shouldDelayActionsFetch ? 8000 : 0); // Update currentlyViewedReportID to be our first reportID from our report collection if we don't have // one already. From f58df177755c1d11cadd79f03a475840a1d15abc Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Thu, 22 Apr 2021 13:46:27 -1000 Subject: [PATCH 25/32] Undo some bad changes --- src/ROUTES.js | 5 +++-- src/libs/Navigation/CustomActions.js | 6 +++++- src/libs/Navigation/Navigation.js | 4 ++-- src/libs/Url.js | 16 ---------------- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/ROUTES.js b/src/ROUTES.js index a6c60a4809d8..404b8c4cfddb 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -1,5 +1,5 @@ import lodashGet from 'lodash/get'; -import {wrapWithForwardSlash} from './libs/Url'; +import {addTrailingForwardSlash} from './libs/Url'; /** * This is a file containing constants for all of the routes we want to be able to go to @@ -43,13 +43,14 @@ export default { * @returns {Object} */ parseReportRouteParams: (route) => { - if (!route.startsWith(wrapWithForwardSlash(REPORT))) { + if (!route.startsWith(addTrailingForwardSlash(REPORT))) { return {}; } const pathSegments = route.split('/'); return { reportID: lodashGet(pathSegments, 1), + isParticipantsRoute: Boolean(lodashGet(pathSegments, 2)), }; }, }; diff --git a/src/libs/Navigation/CustomActions.js b/src/libs/Navigation/CustomActions.js index 74570a88edea..397f6f89dc47 100644 --- a/src/libs/Navigation/CustomActions.js +++ b/src/libs/Navigation/CustomActions.js @@ -14,8 +14,12 @@ import {CommonActions} from '@react-navigation/native'; */ function pushDrawerRoute(screenName, params) { return (state) => { + if (state.type !== 'drawer') { + return CommonActions.navigate(screenName, params); + } + const screenRoute = {type: 'route', name: screenName}; - const history = [...state.history].map(() => screenRoute); + const history = [...(state.history || [])].map(() => screenRoute); history.push(screenRoute); return CommonActions.reset({ ...state, diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index 30cce16a51ae..8a202271ebd2 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -48,8 +48,8 @@ function navigate(route = ROUTES.HOME) { return; } - const {reportID} = ROUTES.parseReportRouteParams(route); - if (reportID) { + const {reportID, isParticipantsRoute} = ROUTES.parseReportRouteParams(route); + if (reportID && !isParticipantsRoute) { navigationRef.current.dispatch(CustomActions.pushDrawerRoute(SCREENS.REPORT, {reportID})); return; } diff --git a/src/libs/Url.js b/src/libs/Url.js index 004e9c5fe173..e166c127a83f 100644 --- a/src/libs/Url.js +++ b/src/libs/Url.js @@ -10,23 +10,7 @@ function addTrailingForwardSlash(url) { return url; } -/** - * Add / to the beginning and end of any URL if not present - * @param {String} url - * @returns {String} - */ -function wrapWithForwardSlash(url) { - const newUrl = addTrailingForwardSlash(url); - if (newUrl.startsWith('/')) { - return newUrl; - } - - return `/${newUrl}`; -} - - export { // eslint-disable-next-line import/prefer-default-export addTrailingForwardSlash, - wrapWithForwardSlash, }; From 9b635631f91ed3938a5365842d95ea2199d28464 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Thu, 22 Apr 2021 14:02:27 -1000 Subject: [PATCH 26/32] add more comments --- src/libs/Navigation/CustomActions.js | 3 +++ src/libs/Navigation/Navigation.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/libs/Navigation/CustomActions.js b/src/libs/Navigation/CustomActions.js index 397f6f89dc47..d29cbed73b9f 100644 --- a/src/libs/Navigation/CustomActions.js +++ b/src/libs/Navigation/CustomActions.js @@ -14,6 +14,9 @@ import {CommonActions} from '@react-navigation/native'; */ function pushDrawerRoute(screenName, params) { return (state) => { + // Non Drawer navigators have routes and not history so we'll fallback to navigate() in the case where we are + // unable to push a new screen onto the history stack e.g. navigating to a ReportScreen via a modal screen. + // Note: One downside of this is that the history will be reset. if (state.type !== 'drawer') { return CommonActions.navigate(screenName, params); } diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index 8a202271ebd2..28dbfe330da4 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -48,6 +48,8 @@ function navigate(route = ROUTES.HOME) { return; } + // Navigate to the ReportScreen with a custom action so that we can preserve the history. We're looking to see if we + // have a participants route since those should go through linkTo() as they open a different screen. const {reportID, isParticipantsRoute} = ROUTES.parseReportRouteParams(route); if (reportID && !isParticipantsRoute) { navigationRef.current.dispatch(CustomActions.pushDrawerRoute(SCREENS.REPORT, {reportID})); From 6d3bfa341d9d5376d13a213c2dc4be64cad2a21f Mon Sep 17 00:00:00 2001 From: tugbadogan Date: Fri, 23 Apr 2021 17:22:00 +0100 Subject: [PATCH 27/32] Revert changes from pod install --- ios/ExpensifyCash.xcodeproj/project.pbxproj | 38 -- ios/Podfile.lock | 580 ++++++++++---------- 2 files changed, 279 insertions(+), 339 deletions(-) diff --git a/ios/ExpensifyCash.xcodeproj/project.pbxproj b/ios/ExpensifyCash.xcodeproj/project.pbxproj index 4a105bffbdda..27ca296fa44c 100644 --- a/ios/ExpensifyCash.xcodeproj/project.pbxproj +++ b/ios/ExpensifyCash.xcodeproj/project.pbxproj @@ -208,7 +208,6 @@ 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, F2B8013B9E9ECAB2B509E702 /* [CP] Copy Pods Resources */, - B6C8E0BF2CC222D8992DC951 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -233,7 +232,6 @@ C9071365B664DE0D85DC5195 /* [CP] Copy Pods Resources */, CF6259710B5A341870372EA2 /* [CP-User] [RNFB] Core Configuration */, ED5B8E90A3384FC6A128FB95 /* [CP-User] [RNFB] Crashlytics Configuration */, - F937A3C3A673918386E1BA72 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -373,24 +371,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - B6C8E0BF2CC222D8992DC951 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; C9071365B664DE0D85DC5195 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -667,24 +647,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - F937A3C3A673918386E1BA72 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; FD10A7F022414F080027D42C /* Start Packager */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 80e725272f40..b1af438affe9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -13,15 +13,16 @@ PODS: - Airship/Core - boost-for-react-native (1.63.0) - CocoaAsyncSocket (7.6.5) + - CocoaLibEvent (1.0.0) - DoubleConversion (1.1.6) - - FBLazyVector (0.64.0) - - FBReactNativeSpec (0.64.0): - - RCT-Folly (= 2020.01.13.00) - - RCTRequired (= 0.64.0) - - RCTTypeSafety (= 0.64.0) - - React-Core (= 0.64.0) - - React-jsi (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) + - FBLazyVector (0.63.3) + - FBReactNativeSpec (0.63.3): + - Folly (= 2020.01.13.00) + - RCTRequired (= 0.63.3) + - RCTTypeSafety (= 0.63.3) + - React-Core (= 0.63.3) + - React-jsi (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) - Firebase/Analytics (6.34.0): - Firebase/Core - Firebase/Core (6.34.0): @@ -61,52 +62,61 @@ PODS: - GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/UserDefaults (~> 6.7) - PromisesObjC (~> 1.2) - - Flipper (0.75.1): - - Flipper-Folly (~> 2.5) - - Flipper-RSocket (~> 1.3) + - Flipper (0.54.0): + - Flipper-Folly (~> 2.2) + - Flipper-RSocket (~> 1.1) - Flipper-DoubleConversion (1.1.7) - - Flipper-Folly (2.5.1): + - Flipper-Folly (2.3.0): - boost-for-react-native + - CocoaLibEvent (~> 1.0) - Flipper-DoubleConversion - Flipper-Glog - - libevent (~> 2.1.12) - - OpenSSL-Universal (= 1.1.180) + - OpenSSL-Universal (= 1.0.2.20) - Flipper-Glog (0.3.6) - Flipper-PeerTalk (0.0.4) - - Flipper-RSocket (1.3.1): - - Flipper-Folly (~> 2.5) - - FlipperKit (0.75.1): - - FlipperKit/Core (= 0.75.1) - - FlipperKit/Core (0.75.1): - - Flipper (~> 0.75.1) + - Flipper-RSocket (1.1.0): + - Flipper-Folly (~> 2.2) + - FlipperKit (0.54.0): + - FlipperKit/Core (= 0.54.0) + - FlipperKit/Core (0.54.0): + - Flipper (~> 0.54.0) - FlipperKit/CppBridge - FlipperKit/FBCxxFollyDynamicConvert - FlipperKit/FBDefines - FlipperKit/FKPortForwarding - - FlipperKit/CppBridge (0.75.1): - - Flipper (~> 0.75.1) - - FlipperKit/FBCxxFollyDynamicConvert (0.75.1): - - Flipper-Folly (~> 2.5) - - FlipperKit/FBDefines (0.75.1) - - FlipperKit/FKPortForwarding (0.75.1): + - FlipperKit/CppBridge (0.54.0): + - Flipper (~> 0.54.0) + - FlipperKit/FBCxxFollyDynamicConvert (0.54.0): + - Flipper-Folly (~> 2.2) + - FlipperKit/FBDefines (0.54.0) + - FlipperKit/FKPortForwarding (0.54.0): - CocoaAsyncSocket (~> 7.6) - Flipper-PeerTalk (~> 0.0.4) - - FlipperKit/FlipperKitHighlightOverlay (0.75.1) - - FlipperKit/FlipperKitLayoutPlugin (0.75.1): + - FlipperKit/FlipperKitHighlightOverlay (0.54.0) + - FlipperKit/FlipperKitLayoutPlugin (0.54.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutTextSearchable - YogaKit (~> 1.18) - - FlipperKit/FlipperKitLayoutTextSearchable (0.75.1) - - FlipperKit/FlipperKitNetworkPlugin (0.75.1): + - FlipperKit/FlipperKitLayoutTextSearchable (0.54.0) + - FlipperKit/FlipperKitNetworkPlugin (0.54.0): - FlipperKit/Core - - FlipperKit/FlipperKitReactPlugin (0.75.1): + - FlipperKit/FlipperKitReactPlugin (0.54.0): - FlipperKit/Core - - FlipperKit/FlipperKitUserDefaultsPlugin (0.75.1): + - FlipperKit/FlipperKitUserDefaultsPlugin (0.54.0): - FlipperKit/Core - - FlipperKit/SKIOSNetworkPlugin (0.75.1): + - FlipperKit/SKIOSNetworkPlugin (0.54.0): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin + - Folly (2020.01.13.00): + - boost-for-react-native + - DoubleConversion + - Folly/Default (= 2020.01.13.00) + - glog + - Folly/Default (2020.01.13.00): + - boost-for-react-native + - DoubleConversion + - glog - glog (0.3.5) - GoogleAppMeasurement (6.9.0): - GoogleUtilities/AppDelegateSwizzler (~> 6.7) @@ -135,207 +145,181 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (6.7.2): - GoogleUtilities/Logger - - libevent (2.1.12) - nanopb (1.30906.0): - nanopb/decode (= 1.30906.0) - nanopb/encode (= 1.30906.0) - nanopb/decode (1.30906.0) - nanopb/encode (1.30906.0) - - OpenSSL-Universal (1.1.180) + - OpenSSL-Universal (1.0.2.20): + - OpenSSL-Universal/Static (= 1.0.2.20) + - OpenSSL-Universal/Static (1.0.2.20) - PromisesObjC (1.2.11) - - RCT-Folly (2020.01.13.00): - - boost-for-react-native - - DoubleConversion - - glog - - RCT-Folly/Default (= 2020.01.13.00) - - RCT-Folly/Default (2020.01.13.00): - - boost-for-react-native - - DoubleConversion - - glog - - RCTRequired (0.64.0) - - RCTTypeSafety (0.64.0): - - FBLazyVector (= 0.64.0) - - RCT-Folly (= 2020.01.13.00) - - RCTRequired (= 0.64.0) - - React-Core (= 0.64.0) - - React (0.64.0): - - React-Core (= 0.64.0) - - React-Core/DevSupport (= 0.64.0) - - React-Core/RCTWebSocket (= 0.64.0) - - React-RCTActionSheet (= 0.64.0) - - React-RCTAnimation (= 0.64.0) - - React-RCTBlob (= 0.64.0) - - React-RCTImage (= 0.64.0) - - React-RCTLinking (= 0.64.0) - - React-RCTNetwork (= 0.64.0) - - React-RCTSettings (= 0.64.0) - - React-RCTText (= 0.64.0) - - React-RCTVibration (= 0.64.0) - - React-callinvoker (0.64.0) - - React-Core (0.64.0): + - RCTRequired (0.63.3) + - RCTTypeSafety (0.63.3): + - FBLazyVector (= 0.63.3) + - Folly (= 2020.01.13.00) + - RCTRequired (= 0.63.3) + - React-Core (= 0.63.3) + - React (0.63.3): + - React-Core (= 0.63.3) + - React-Core/DevSupport (= 0.63.3) + - React-Core/RCTWebSocket (= 0.63.3) + - React-RCTActionSheet (= 0.63.3) + - React-RCTAnimation (= 0.63.3) + - React-RCTBlob (= 0.63.3) + - React-RCTImage (= 0.63.3) + - React-RCTLinking (= 0.63.3) + - React-RCTNetwork (= 0.63.3) + - React-RCTSettings (= 0.63.3) + - React-RCTText (= 0.63.3) + - React-RCTVibration (= 0.63.3) + - React-callinvoker (0.63.3) + - React-Core (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-Core/Default (= 0.64.0) - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-Core/Default (= 0.63.3) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/CoreModulesHeaders (0.64.0): + - React-Core/CoreModulesHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/Default (0.64.0): + - React-Core/Default (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/DevSupport (0.64.0): + - React-Core/DevSupport (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-Core/Default (= 0.64.0) - - React-Core/RCTWebSocket (= 0.64.0) - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-jsinspector (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-Core/Default (= 0.63.3) + - React-Core/RCTWebSocket (= 0.63.3) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) + - React-jsinspector (= 0.63.3) - Yoga - - React-Core/RCTActionSheetHeaders (0.64.0): + - React-Core/RCTActionSheetHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTAnimationHeaders (0.64.0): + - React-Core/RCTAnimationHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTBlobHeaders (0.64.0): + - React-Core/RCTBlobHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTImageHeaders (0.64.0): + - React-Core/RCTImageHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTLinkingHeaders (0.64.0): + - React-Core/RCTLinkingHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTNetworkHeaders (0.64.0): + - React-Core/RCTNetworkHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTSettingsHeaders (0.64.0): + - React-Core/RCTSettingsHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTTextHeaders (0.64.0): + - React-Core/RCTTextHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTVibrationHeaders (0.64.0): + - React-Core/RCTVibrationHeaders (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - React-Core/Default - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-Core/RCTWebSocket (0.64.0): + - React-Core/RCTWebSocket (0.63.3): + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-Core/Default (= 0.64.0) - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsiexecutor (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-Core/Default (= 0.63.3) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsiexecutor (= 0.63.3) - Yoga - - React-CoreModules (0.64.0): - - FBReactNativeSpec (= 0.64.0) - - RCT-Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.64.0) - - React-Core/CoreModulesHeaders (= 0.64.0) - - React-jsi (= 0.64.0) - - React-RCTImage (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) - - React-cxxreact (0.64.0): + - React-CoreModules (0.63.3): + - FBReactNativeSpec (= 0.63.3) + - Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.63.3) + - React-Core/CoreModulesHeaders (= 0.63.3) + - React-jsi (= 0.63.3) + - React-RCTImage (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) + - React-cxxreact (0.63.3): - boost-for-react-native (= 1.63.0) - DoubleConversion + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-callinvoker (= 0.64.0) - - React-jsi (= 0.64.0) - - React-jsinspector (= 0.64.0) - - React-perflogger (= 0.64.0) - - React-runtimeexecutor (= 0.64.0) - - React-jsi (0.64.0): + - React-callinvoker (= 0.63.3) + - React-jsinspector (= 0.63.3) + - React-jsi (0.63.3): - boost-for-react-native (= 1.63.0) - DoubleConversion + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-jsi/Default (= 0.64.0) - - React-jsi/Default (0.64.0): + - React-jsi/Default (= 0.63.3) + - React-jsi/Default (0.63.3): - boost-for-react-native (= 1.63.0) - DoubleConversion + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-jsiexecutor (0.64.0): + - React-jsiexecutor (0.63.3): - DoubleConversion + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-perflogger (= 0.64.0) - - React-jsinspector (0.64.0) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) + - React-jsinspector (0.63.3) - react-native-config (1.4.1): - react-native-config/App (= 1.4.1) - react-native-config/App (1.4.1): @@ -354,72 +338,70 @@ PODS: - React - react-native-safe-area-context (3.1.8): - React-Core - - React-perflogger (0.64.0) - - React-RCTActionSheet (0.64.0): - - React-Core/RCTActionSheetHeaders (= 0.64.0) - - React-RCTAnimation (0.64.0): - - FBReactNativeSpec (= 0.64.0) - - RCT-Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.64.0) - - React-Core/RCTAnimationHeaders (= 0.64.0) - - React-jsi (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) - - React-RCTBlob (0.64.0): - - FBReactNativeSpec (= 0.64.0) - - RCT-Folly (= 2020.01.13.00) - - React-Core/RCTBlobHeaders (= 0.64.0) - - React-Core/RCTWebSocket (= 0.64.0) - - React-jsi (= 0.64.0) - - React-RCTNetwork (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) - - React-RCTImage (0.64.0): - - FBReactNativeSpec (= 0.64.0) - - RCT-Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.64.0) - - React-Core/RCTImageHeaders (= 0.64.0) - - React-jsi (= 0.64.0) - - React-RCTNetwork (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) - - React-RCTLinking (0.64.0): - - FBReactNativeSpec (= 0.64.0) - - React-Core/RCTLinkingHeaders (= 0.64.0) - - React-jsi (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) - - React-RCTNetwork (0.64.0): - - FBReactNativeSpec (= 0.64.0) - - RCT-Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.64.0) - - React-Core/RCTNetworkHeaders (= 0.64.0) - - React-jsi (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) - - React-RCTSettings (0.64.0): - - FBReactNativeSpec (= 0.64.0) - - RCT-Folly (= 2020.01.13.00) - - RCTTypeSafety (= 0.64.0) - - React-Core/RCTSettingsHeaders (= 0.64.0) - - React-jsi (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) - - React-RCTText (0.64.0): - - React-Core/RCTTextHeaders (= 0.64.0) - - React-RCTVibration (0.64.0): - - FBReactNativeSpec (= 0.64.0) - - RCT-Folly (= 2020.01.13.00) - - React-Core/RCTVibrationHeaders (= 0.64.0) - - React-jsi (= 0.64.0) - - ReactCommon/turbomodule/core (= 0.64.0) - - React-runtimeexecutor (0.64.0): - - React-jsi (= 0.64.0) - - ReactCommon/turbomodule/core (0.64.0): + - React-RCTActionSheet (0.63.3): + - React-Core/RCTActionSheetHeaders (= 0.63.3) + - React-RCTAnimation (0.63.3): + - FBReactNativeSpec (= 0.63.3) + - Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.63.3) + - React-Core/RCTAnimationHeaders (= 0.63.3) + - React-jsi (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) + - React-RCTBlob (0.63.3): + - FBReactNativeSpec (= 0.63.3) + - Folly (= 2020.01.13.00) + - React-Core/RCTBlobHeaders (= 0.63.3) + - React-Core/RCTWebSocket (= 0.63.3) + - React-jsi (= 0.63.3) + - React-RCTNetwork (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) + - React-RCTImage (0.63.3): + - FBReactNativeSpec (= 0.63.3) + - Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.63.3) + - React-Core/RCTImageHeaders (= 0.63.3) + - React-jsi (= 0.63.3) + - React-RCTNetwork (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) + - React-RCTLinking (0.63.3): + - FBReactNativeSpec (= 0.63.3) + - React-Core/RCTLinkingHeaders (= 0.63.3) + - React-jsi (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) + - React-RCTNetwork (0.63.3): + - FBReactNativeSpec (= 0.63.3) + - Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.63.3) + - React-Core/RCTNetworkHeaders (= 0.63.3) + - React-jsi (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) + - React-RCTSettings (0.63.3): + - FBReactNativeSpec (= 0.63.3) + - Folly (= 2020.01.13.00) + - RCTTypeSafety (= 0.63.3) + - React-Core/RCTSettingsHeaders (= 0.63.3) + - React-jsi (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) + - React-RCTText (0.63.3): + - React-Core/RCTTextHeaders (= 0.63.3) + - React-RCTVibration (0.63.3): + - FBReactNativeSpec (= 0.63.3) + - Folly (= 2020.01.13.00) + - React-Core/RCTVibrationHeaders (= 0.63.3) + - React-jsi (= 0.63.3) + - ReactCommon/turbomodule/core (= 0.63.3) + - ReactCommon/turbomodule/core (0.63.3): - DoubleConversion + - Folly (= 2020.01.13.00) - glog - - RCT-Folly (= 2020.01.13.00) - - React-callinvoker (= 0.64.0) - - React-Core (= 0.64.0) - - React-cxxreact (= 0.64.0) - - React-jsi (= 0.64.0) - - React-perflogger (= 0.64.0) + - React-callinvoker (= 0.63.3) + - React-Core (= 0.63.3) + - React-cxxreact (= 0.63.3) + - React-jsi (= 0.63.3) - rn-fetch-blob (0.12.0): - React-Core + - RNBootSplash (3.2.0): + - React-Core - RNCAsyncStorage (1.12.1): - React-Core - RNCClipboard (1.5.1): @@ -457,28 +439,28 @@ PODS: DEPENDENCIES: - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) - - Flipper (~> 0.75.1) + - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) + - Flipper (~> 0.54.0) - Flipper-DoubleConversion (= 1.1.7) - - Flipper-Folly (~> 2.5) + - Flipper-Folly (~> 2.2) - Flipper-Glog (= 0.3.6) - Flipper-PeerTalk (~> 0.0.4) - - Flipper-RSocket (~> 1.3) - - FlipperKit (~> 0.75.1) - - FlipperKit/Core (~> 0.75.1) - - FlipperKit/CppBridge (~> 0.75.1) - - FlipperKit/FBCxxFollyDynamicConvert (~> 0.75.1) - - FlipperKit/FBDefines (~> 0.75.1) - - FlipperKit/FKPortForwarding (~> 0.75.1) - - FlipperKit/FlipperKitHighlightOverlay (~> 0.75.1) - - FlipperKit/FlipperKitLayoutPlugin (~> 0.75.1) - - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.75.1) - - FlipperKit/FlipperKitNetworkPlugin (~> 0.75.1) - - FlipperKit/FlipperKitReactPlugin (~> 0.75.1) - - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.75.1) - - FlipperKit/SKIOSNetworkPlugin (~> 0.75.1) + - Flipper-RSocket (~> 1.1) + - FlipperKit (~> 0.54.0) + - FlipperKit/Core (~> 0.54.0) + - FlipperKit/CppBridge (~> 0.54.0) + - FlipperKit/FBCxxFollyDynamicConvert (~> 0.54.0) + - FlipperKit/FBDefines (~> 0.54.0) + - FlipperKit/FKPortForwarding (~> 0.54.0) + - FlipperKit/FlipperKitHighlightOverlay (~> 0.54.0) + - FlipperKit/FlipperKitLayoutPlugin (~> 0.54.0) + - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.54.0) + - FlipperKit/FlipperKitNetworkPlugin (~> 0.54.0) + - FlipperKit/FlipperKitReactPlugin (~> 0.54.0) + - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.54.0) + - FlipperKit/SKIOSNetworkPlugin (~> 0.54.0) + - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - React (from `../node_modules/react-native/`) @@ -499,7 +481,6 @@ DEPENDENCIES: - "react-native-progress-bar-android (from `../node_modules/@react-native-community/progress-bar-android`)" - "react-native-progress-view (from `../node_modules/@react-native-community/progress-view`)" - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) @@ -509,9 +490,9 @@ DEPENDENCIES: - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) - React-RCTText (from `../node_modules/react-native/Libraries/Text`) - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - rn-fetch-blob (from `../node_modules/rn-fetch-blob`) + - RNBootSplash (from `../node_modules/react-native-bootsplash`) - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" @@ -531,6 +512,7 @@ SPEC REPOS: - Airship - boost-for-react-native - CocoaAsyncSocket + - CocoaLibEvent - Firebase - FirebaseAnalytics - FirebaseCore @@ -547,7 +529,6 @@ SPEC REPOS: - GoogleAppMeasurement - GoogleDataTransport - GoogleUtilities - - libevent - nanopb - OpenSSL-Universal - PromisesObjC @@ -559,11 +540,11 @@ EXTERNAL SOURCES: FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" FBReactNativeSpec: - :path: "../node_modules/react-native/React/FBReactNativeSpec" + :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" + Folly: + :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" - RCT-Folly: - :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: :path: "../node_modules/react-native/Libraries/RCTRequired" RCTTypeSafety: @@ -600,8 +581,6 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/progress-view" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" - React-perflogger: - :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: :path: "../node_modules/react-native/Libraries/ActionSheetIOS" React-RCTAnimation: @@ -620,12 +599,12 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/Text" React-RCTVibration: :path: "../node_modules/react-native/Libraries/Vibration" - React-runtimeexecutor: - :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" ReactCommon: :path: "../node_modules/react-native/ReactCommon" rn-fetch-blob: :path: "../node_modules/rn-fetch-blob" + RNBootSplash: + :path: "../node_modules/react-native-bootsplash" RNCAsyncStorage: :path: "../node_modules/@react-native-community/async-storage" RNCClipboard: @@ -657,41 +636,41 @@ SPEC CHECKSUMS: Airship: 02ad73780f9eed21870e36b0aaab327acda6a102 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 + CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f DoubleConversion: cde416483dac037923206447da6e1454df403714 - FBLazyVector: 49cbe4b43e445b06bf29199b6ad2057649e4c8f5 - FBReactNativeSpec: 9fd67b7512e849d0c026842367e27e791bd7bba7 + FBLazyVector: 878b59e31113e289e275165efbe4b54fa614d43d + FBReactNativeSpec: 7da9338acfb98d4ef9e5536805a0704572d33c2f Firebase: c23a36d9e4cdf7877dfcba8dd0c58add66358999 FirebaseAnalytics: 3bb096873ee0d7fa4b6c70f5e9166b6da413cc7f FirebaseCore: d3a978a3cfa3240bf7e4ba7d137fdf5b22b628ec FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 FirebaseCrashlytics: 1a747c9cc084a24dc6d9511c991db1cd078154eb FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 - Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021 + Flipper: be611d4b742d8c87fbae2ca5f44603a02539e365 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 - Flipper-Folly: f7a3caafbd74bda4827954fd7a6e000e36355489 + Flipper-Folly: e4493b013c02d9347d5e0cb4d128680239f6c78a Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 - Flipper-RSocket: 127954abe8b162fcaf68d2134d34dc2bd7076154 - FlipperKit: 8a20b5c5fcf9436cac58551dc049867247f64b00 + Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7 + FlipperKit: ab353d41aea8aae2ea6daaf813e67496642f3d7d + Folly: b73c3869541e86821df3c387eb0af5f65addfab4 glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 GoogleAppMeasurement: a6a3a066369828db64eda428cb2856dc1cdc7c4e GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 - libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc - OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b + OpenSSL-Universal: ff34003318d5e1163e9529b08470708e389ffcdd PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f - RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c - RCTRequired: 2f8cb5b7533219bf4218a045f92768129cf7050a - RCTTypeSafety: 512728b73549e72ad7330b92f3d42936f2a4de5b - React: 98eac01574128a790f0bbbafe2d1a8607291ac24 - React-callinvoker: def3f7fae16192df68d9b69fd4bbb59092ee36bc - React-Core: 70a52aa5dbe9b83befae82038451a7df9fd54c5a - React-CoreModules: 052edef46117862e2570eb3a0f06d81c61d2c4b8 - React-cxxreact: c1dc71b30653cfb4770efdafcbdc0ad6d388baab - React-jsi: 74341196d9547cbcbcfa4b3bbbf03af56431d5a1 - React-jsiexecutor: 06a9c77b56902ae7ffcdd7a4905f664adc5d237b - React-jsinspector: 0ae35a37b20d5e031eb020a69cc5afdbd6406301 + RCTRequired: 48884c74035a0b5b76dbb7a998bd93bcfc5f2047 + RCTTypeSafety: edf4b618033c2f1c5b7bc3d90d8e085ed95ba2ab + React: f36e90f3ceb976546e97df3403e37d226f79d0e3 + React-callinvoker: 18874f621eb96625df7a24a7dc8d6e07391affcd + React-Core: ac3d816b8e3493970153f4aaf0cff18af0bb95e6 + React-CoreModules: 4016d3a4e518bcfc4f5a51252b5a05692ca6f0e1 + React-cxxreact: ffc9129013b87cb36cf3f30a86695a3c397b0f99 + React-jsi: df07aa95b39c5be3e41199921509bfa929ed2b9d + React-jsiexecutor: b56c03e61c0dd5f5801255f2160a815f4a53d451 + React-jsinspector: 8e68ffbfe23880d3ee9bafa8be2777f60b25cbe2 react-native-config: d8b45133fd13d4f23bd2064b72f6e2c08b2763ed react-native-document-picker: b3e78a8f7fef98b5cb069f20fc35797d55e68e28 react-native-image-picker: 32d1ad2c0024ca36161ae0d5c2117e2d6c441f11 @@ -700,19 +679,18 @@ SPEC CHECKSUMS: react-native-progress-bar-android: ce95a69f11ac580799021633071368d08aaf9ad8 react-native-progress-view: 5816e8a6be812c2b122c6225a2a3db82d9008640 react-native-safe-area-context: 01158a92c300895d79dee447e980672dc3fb85a6 - React-perflogger: 9c547d8f06b9bf00cb447f2b75e8d7f19b7e02af - React-RCTActionSheet: 3080b6e12e0e1a5b313c8c0050699b5c794a1b11 - React-RCTAnimation: 3f96f21a497ae7dabf4d2f150ee43f906aaf516f - React-RCTBlob: 283b8e5025e7f954176bc48164f846909002f3ed - React-RCTImage: 5088a484faac78f2d877e1b79125d3bb1ea94a16 - React-RCTLinking: 5e8fbb3e9a8bc2e4e3eb15b1eb8bda5fcac27b8c - React-RCTNetwork: 38ec277217b1e841d5e6a1fa78da65b9212ccb28 - React-RCTSettings: 242d6e692108c3de4f3bb74b7586a8799e9ab070 - React-RCTText: 8746736ac8eb5a4a74719aa695b7a236a93a83d2 - React-RCTVibration: 0fd6b21751a33cb72fce1a4a33ab9678416d307a - React-runtimeexecutor: cad74a1eaa53ee6e7a3620231939d8fe2c6afcf0 - ReactCommon: cfe2b7fd20e0dbd2d1185cd7d8f99633fbc5ff05 + React-RCTActionSheet: 53ea72699698b0b47a6421cb1c8b4ab215a774aa + React-RCTAnimation: 1befece0b5183c22ae01b966f5583f42e69a83c2 + React-RCTBlob: 0b284339cbe4b15705a05e2313a51c6d8b51fa40 + React-RCTImage: d1756599ebd4dc2cb19d1682fe67c6b976658387 + React-RCTLinking: 9af0a51c6d6a4dd1674daadafffc6d03033a6d18 + React-RCTNetwork: 332c83929cc5eae0b3bbca4add1d668e1fc18bda + React-RCTSettings: d6953772cfd55f2c68ad72b7ef29efc7ec49f773 + React-RCTText: 65a6de06a7389098ce24340d1d3556015c38f746 + React-RCTVibration: 8e9fb25724a0805107fc1acc9075e26f814df454 + ReactCommon: 4167844018c9ed375cc01a843e9ee564399e53c3 rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba + RNBootSplash: 3123ba68fe44d8be09a014e89cc8f0f55b68a521 RNCAsyncStorage: cb9a623793918c6699586281f0b51cbc38f046f9 RNCClipboard: 5e299c6df8e0c98f3d7416b86ae563d3a9f768a3 RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459 @@ -725,7 +703,7 @@ SPEC CHECKSUMS: RNScreens: b6c9607e6fe47c1b6e2f1910d2acd46dd7ecea3a RNSVG: ce9d996113475209013317e48b05c21ee988d42e urbanairship-react-native: dfb6dc22b2f41ccaadd636b73d51b448cd1b2bbc - Yoga: 8c8436d4171c87504c648ae23b1d81242bdf3bbf + Yoga: 7d13633d129fd179e01b8953d38d47be90db185a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a PODFILE CHECKSUM: 41b806c7f131f87b716be1f1f9377532d6c9e43a From 24fb4141c797e9fb06dcb5cc3880c0bdae75cb00 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Fri, 23 Apr 2021 22:22:27 +0530 Subject: [PATCH 28/32] refactor offline messages code --- src/pages/home/report/ReportActionItem.js | 24 +++++++++++++++++----- src/pages/home/report/ReportActionsView.js | 11 ---------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 6d3f9a6e0367..45846c2ae28e 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -2,6 +2,8 @@ import _ from 'underscore'; import React, {Component} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; +import ONYXKEYS from '../../../ONYXKEYS'; import ReportActionPropTypes from './ReportActionPropTypes'; import { getReportActionItemStyle, @@ -28,8 +30,15 @@ const propTypes = { // Should we display the new indicator on top of the comment? shouldDisplayNewIndicator: PropTypes.bool.isRequired, - // Is the network currently offline or not - isOffline: PropTypes.bool.isRequired, + // Information about the network + network: PropTypes.shape({ + // Is the network currently offline or not + isOffline: PropTypes.bool, + }), +}; + +const defaultProps = { + network: {isOffline: false}, }; class ReportActionItem extends Component { @@ -101,13 +110,13 @@ class ReportActionItem extends Component { ? ( ) : ( )} @@ -151,5 +160,10 @@ class ReportActionItem extends Component { } ReportActionItem.propTypes = propTypes; +ReportActionItem.defaultProps = defaultProps; -export default ReportActionItem; +export default withOnyx({ + network: { + key: ONYXKEYS.NETWORK, + }, +})(ReportActionItem); diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 805ae828f177..347dd3d5ee48 100644 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -50,12 +50,6 @@ const propTypes = { // Email of the logged in person email: PropTypes.string, }), - - // Information about the network - network: PropTypes.shape({ - // Is the network currently offline or not - isOffline: PropTypes.bool, - }), }; const defaultProps = { @@ -65,7 +59,6 @@ const defaultProps = { }, reportActions: {}, session: {}, - network: {isOffline: false}, }; class ReportActionsView extends React.Component { @@ -290,7 +283,6 @@ class ReportActionsView extends React.Component { 0 && item.action.sequenceNumber === this.initialNewMarkerPosition} @@ -343,9 +335,6 @@ export default withOnyx({ key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, canEvict: false, }, - network: { - key: ONYXKEYS.NETWORK, - }, session: { key: ONYXKEYS.SESSION, }, From ca509c8faddd1ceccf0cbda1ddf28c60ed947438 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Fri, 23 Apr 2021 18:19:32 +0000 Subject: [PATCH 29/32] Update version to 1.0.30-0 --- android/app/build.gradle | 4 ++-- ios/ExpensifyCash/Info.plist | 4 ++-- ios/ExpensifyCashTests/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 678c40309eb7..641ca5127311 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -148,8 +148,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001002903 - versionName "1.0.29-3" + versionCode 1001003000 + versionName "1.0.30-0" } splits { abi { diff --git a/ios/ExpensifyCash/Info.plist b/ios/ExpensifyCash/Info.plist index c359b2f37c56..dc900273a697 100644 --- a/ios/ExpensifyCash/Info.plist +++ b/ios/ExpensifyCash/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.29 + 1.0.30 CFBundleSignature ???? CFBundleURLTypes @@ -30,7 +30,7 @@ CFBundleVersion - 1.0.29.3 + 1.0.30.0 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/ExpensifyCashTests/Info.plist b/ios/ExpensifyCashTests/Info.plist index c16db31b438e..393b760c5c18 100644 --- a/ios/ExpensifyCashTests/Info.plist +++ b/ios/ExpensifyCashTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.0.29 + 1.0.30 CFBundleSignature ???? CFBundleVersion - 1.0.29.3 + 1.0.30.0 diff --git a/package-lock.json b/package-lock.json index 992c0db7754e..2a4124873939 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "expensify.cash", - "version": "1.0.29-3", + "version": "1.0.30-0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 889046cfb9b3..d558f375b27c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "expensify.cash", - "version": "1.0.29-3", + "version": "1.0.30-0", "author": "Expensify, Inc.", "homepage": "https://expensify.cash", "description": "Expensify.cash is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 590dc0ac8806be3b5cb87b0d8e7612fa8c310132 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Sat, 24 Apr 2021 00:34:39 +0530 Subject: [PATCH 30/32] refactor --- src/pages/home/report/ReportActionItem.js | 33 ++----------------- .../home/report/ReportActionItemMessage.js | 24 +++++++++++--- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 45846c2ae28e..51a48e7dc3ea 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -2,8 +2,6 @@ import _ from 'underscore'; import React, {Component} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; -import {withOnyx} from 'react-native-onyx'; -import ONYXKEYS from '../../../ONYXKEYS'; import ReportActionPropTypes from './ReportActionPropTypes'; import { getReportActionItemStyle, @@ -29,16 +27,6 @@ const propTypes = { // Should we display the new indicator on top of the comment? shouldDisplayNewIndicator: PropTypes.bool.isRequired, - - // Information about the network - network: PropTypes.shape({ - // Is the network currently offline or not - isOffline: PropTypes.bool, - }), -}; - -const defaultProps = { - network: {isOffline: false}, }; class ReportActionItem extends Component { @@ -107,18 +95,8 @@ class ReportActionItem extends Component { )} {!this.props.displayAsGroup - ? ( - - ) - : ( - - )} + ? + : } { +const defaultProps = { + network: {isOffline: false}, +}; + +const ReportActionItemMessage = ({action, network}) => { // reportActionID is only present when the action is saved onto server. - const isUnsent = isOffline && action.loading && !action.reportActionID; + const isUnsent = network.isOffline && action.loading && !action.reportActionID; return ( {_.map(_.compact(action.message), (fragment, index) => ( @@ -32,6 +41,11 @@ const ReportActionItemMessage = ({action, isOffline}) => { }; ReportActionItemMessage.propTypes = propTypes; +ReportActionItemMessage.defaultProps = defaultProps; ReportActionItemMessage.displayName = 'ReportActionItemMessage'; -export default ReportActionItemMessage; +export default withOnyx({ + network: { + key: ONYXKEYS.NETWORK, + }, +})(ReportActionItemMessage); From 960233b1162a8990505b0dff590661a776de5a5b Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Sat, 24 Apr 2021 01:14:32 +0530 Subject: [PATCH 31/32] removed unnecessay check --- src/pages/home/report/ReportActionItemMessage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index 27aa621ad534..fe28b1a3868e 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -24,8 +24,7 @@ const defaultProps = { }; const ReportActionItemMessage = ({action, network}) => { - // reportActionID is only present when the action is saved onto server. - const isUnsent = network.isOffline && action.loading && !action.reportActionID; + const isUnsent = network.isOffline && action.loading; return ( {_.map(_.compact(action.message), (fragment, index) => ( From 3b5f6a78af283a9187b1e8b0342305fee2a67ef0 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 26 Apr 2021 10:49:10 +0000 Subject: [PATCH 32/32] Update version to 1.0.30-1 --- android/app/build.gradle | 4 ++-- ios/ExpensifyCash/Info.plist | 2 +- ios/ExpensifyCashTests/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 641ca5127311..e1bfcab211be 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -148,8 +148,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001003000 - versionName "1.0.30-0" + versionCode 1001003001 + versionName "1.0.30-1" } splits { abi { diff --git a/ios/ExpensifyCash/Info.plist b/ios/ExpensifyCash/Info.plist index dc900273a697..5e856bc6679d 100644 --- a/ios/ExpensifyCash/Info.plist +++ b/ios/ExpensifyCash/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.0.30.0 + 1.0.30.1 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/ExpensifyCashTests/Info.plist b/ios/ExpensifyCashTests/Info.plist index 393b760c5c18..67c1c8a7a78a 100644 --- a/ios/ExpensifyCashTests/Info.plist +++ b/ios/ExpensifyCashTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.0.30.0 + 1.0.30.1 diff --git a/package-lock.json b/package-lock.json index 2a4124873939..3e0c29630721 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "expensify.cash", - "version": "1.0.30-0", + "version": "1.0.30-1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d558f375b27c..965588985150 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "expensify.cash", - "version": "1.0.30-0", + "version": "1.0.30-1", "author": "Expensify, Inc.", "homepage": "https://expensify.cash", "description": "Expensify.cash is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",