From fd5bd2d90d68808be87d1820ba25745632c65c83 Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Wed, 26 Jul 2023 14:16:51 -0700 Subject: [PATCH 01/39] Separate DistanceRequestPage to pass transactionID --- src/pages/iou/DistanceRequestPage.js | 87 ++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/pages/iou/DistanceRequestPage.js diff --git a/src/pages/iou/DistanceRequestPage.js b/src/pages/iou/DistanceRequestPage.js new file mode 100644 index 000000000000..ee65787050bc --- /dev/null +++ b/src/pages/iou/DistanceRequestPage.js @@ -0,0 +1,87 @@ +import React, {useEffect} from 'react'; +import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; +import * as IOU from '../../libs/actions/IOU'; +import ONYXKEYS from '../../ONYXKEYS'; +import DistanceRequest from '../../components/DistanceRequest'; +import CONST from '../../CONST'; +import reportPropTypes from '../reportPropTypes'; + +const propTypes = { + /** The transactionID of this request */ + transactionID: PropTypes.string, + + /** Route params */ + route: PropTypes.shape({ + params: PropTypes.shape({ + iouType: PropTypes.string, + reportID: PropTypes.string, + }), + }), + + /** The report on which the request is initiated on */ + report: reportPropTypes, + + /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ + iou: PropTypes.shape({ + id: PropTypes.string, + amount: PropTypes.number, + currency: PropTypes.string, + participants: PropTypes.arrayOf( + PropTypes.shape({ + accountID: PropTypes.number, + login: PropTypes.string, + isPolicyExpenseChat: PropTypes.bool, + isOwnPolicyExpenseChat: PropTypes.bool, + selected: PropTypes.bool, + }), + ), + transactionID: PropTypes.string, + }), +}; + +const defaultProps = { + transactionID: '', + route: { + params: { + iouType: '', + reportID: '', + }, + }, + report: {}, + iou: { + id: '', + amount: 0, + currency: CONST.CURRENCY.USD, + participants: [], + transactionID: '', + }, +}; + +function DistanceRequestPage({route, report, iou, transactionID}) { + useEffect(() => { + if (transactionID) { + return; + } + IOU.createEmptyTransaction(); + }, [transactionID]); + + + return ( + + ); +} + +DistanceRequestPage.displayName = 'DistanceRequestPage'; +DistanceRequestPage.propTypes = propTypes; +DistanceRequestPage.defaultProps = defaultProps; +export default withOnyx({ + // We must provide a default value for transactionID here, otherwise the component won't mount + // because withOnyx returns null until all the keys are defined + transactionID: {key: ONYXKEYS.IOU, selector: (iou) => iou && iou.transactionID || ''}, +})(DistanceRequestPage); From ed1677ad3d230378e66899b37cb02c40f820c2c2 Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Wed, 26 Jul 2023 14:19:43 -0700 Subject: [PATCH 02/39] Action to create initial waypoints --- src/libs/actions/Transaction.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/libs/actions/Transaction.js diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js new file mode 100644 index 000000000000..7566f950d728 --- /dev/null +++ b/src/libs/actions/Transaction.js @@ -0,0 +1,11 @@ +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '../../ONYXKEYS'; + +function createInitialWaypoints(transactionID) { + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { + 'waypoint0': {}, + 'waypoint1': {}, + }); +} + +export default createInitialWaypoints; \ No newline at end of file From 18bf82c8659f128af81e13ceda7364a3bde5fe50 Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Wed, 26 Jul 2023 14:20:26 -0700 Subject: [PATCH 03/39] Connect to transaction and create waypoints --- src/components/DistanceRequest.js | 31 ++++++++++++++++++++++++------- src/libs/actions/IOU.js | 2 +- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 7b8333ab3ae3..4d10e6db93bd 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,33 +1,50 @@ import React, {useEffect} from 'react'; import {View} from 'react-native'; +import lodashGet from 'lodash/get'; +import _ from 'underscore'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import Text from './Text'; -import * as IOU from '../libs/actions/IOU'; import styles from '../styles/styles'; import ONYXKEYS from '../ONYXKEYS'; +import createInitialWaypoints from '../libs/actions/Transaction'; const propTypes = { /** The transactionID of this request */ transactionID: PropTypes.string, + + /** The optimistic transaction for this request */ + transaction: PropTypes.shape({ + transactionID: PropTypes.string, + comment: PropTypes.shape({ + waypoints: PropTypes.shape({ + lat: PropTypes.number, + lng: PropTypes.number, + address: PropTypes.string, + }) + }), + }), }; const defaultProps = { transactionID: '', + transaction: {}, }; -function DistanceRequest(props) { +function DistanceRequest({transaction, transactionID}) { useEffect(() => { - if (props.transactionID) { + const waypoints = lodashGet(transaction, 'comment.waypoints'); + if (!transaction.transactionID || !_.isEmpty(waypoints)) { return; } - IOU.createEmptyTransaction(); - }, [props.transactionID]); + // Create the initial start and stop waypoints + createInitialWaypoints(transaction.transactionID); + }, [transaction]); return ( Distance Request - transactionID: {props.transactionID} + transactionID: {transactionID} ); } @@ -36,5 +53,5 @@ DistanceRequest.displayName = 'DistanceRequest'; DistanceRequest.propTypes = propTypes; DistanceRequest.defaultProps = defaultProps; export default withOnyx({ - transactionID: {key: ONYXKEYS.IOU, selector: (iou) => iou.transactionID}, + transaction: {key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, selector: (transaction) => ({transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}})}, })(DistanceRequest); diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 468a6f3582db..004405241c0d 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -1403,7 +1403,7 @@ function setMoneyRequestReceipt(receiptPath, receiptSource) { function createEmptyTransaction() { const transactionID = NumberUtils.rand64(); - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {}); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {transactionID}); Onyx.merge(ONYXKEYS.IOU, {transactionID}); } From 6d3820afb933e306dc5f6dd80ca6c6ce3fabaecb Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Wed, 26 Jul 2023 14:20:38 -0700 Subject: [PATCH 04/39] Use distance request page --- src/pages/iou/MoneyRequestSelectorPage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/MoneyRequestSelectorPage.js b/src/pages/iou/MoneyRequestSelectorPage.js index e141501f1afe..be2841342051 100644 --- a/src/pages/iou/MoneyRequestSelectorPage.js +++ b/src/pages/iou/MoneyRequestSelectorPage.js @@ -21,7 +21,7 @@ import MoneyRequestAmountPage from './steps/MoneyRequestAmountPage'; import ReceiptSelector from './ReceiptSelector'; import DragAndDrop from '../../components/DragAndDrop'; import * as IOU from '../../libs/actions/IOU'; -import DistanceRequest from '../../components/DistanceRequest'; +import DistanceRequestPage from './DistanceRequestPage'; import reportPropTypes from '../reportPropTypes'; import NavigateToNextIOUPage from './NavigateToNextIOUPage'; import AttachmentUtils from '../../libs/AttachmentUtils'; @@ -152,7 +152,7 @@ function MoneyRequestSelectorPage({route, report, tabSelected, iou, currentUserP /> )} {selectedTab === CONST.TAB.TAB_DISTANCE && ( - Date: Fri, 28 Jul 2023 18:46:10 -0700 Subject: [PATCH 05/39] Store waypoints under comment as intended --- src/libs/actions/Transaction.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index 7566f950d728..a6f693e6165e 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -3,9 +3,14 @@ import ONYXKEYS from '../../ONYXKEYS'; function createInitialWaypoints(transactionID) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { - 'waypoint0': {}, - 'waypoint1': {}, + comment: { + waypoints: { + 'waypoint0': {}, + 'waypoint1': {}, + } + } }); + } export default createInitialWaypoints; \ No newline at end of file From 4093ecc27a818a3bd0f83169242447c9c367339b Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Fri, 28 Jul 2023 18:47:11 -0700 Subject: [PATCH 06/39] Add secondary icon for waypoint menu items --- src/components/MenuItem.js | 18 ++++++++++++++++++ src/components/menuItemPropTypes.js | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 2860b7cef35c..f9c8db7e09ef 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -45,12 +45,14 @@ const defaultProps = { descriptionTextStyle: styles.breakWord, success: false, icon: undefined, + secondaryIcon: undefined, iconWidth: undefined, iconHeight: undefined, description: undefined, iconRight: Expensicons.ArrowRight, iconStyles: [], iconFill: undefined, + secondaryIconFill: undefined, focused: false, disabled: false, isSelected: false, @@ -194,6 +196,22 @@ function MenuItem(props) { )} )} + {Boolean(props.secondaryIcon) && ( + + + + )} {Boolean(props.description) && props.shouldShowDescriptionOnTop && ( Date: Fri, 28 Jul 2023 18:47:35 -0700 Subject: [PATCH 07/39] WIP display initial waypoints --- src/components/DistanceRequest.js | 43 ++++++++++++++++++++++++------- src/languages/en.js | 7 +++++ 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 4d10e6db93bd..c00c57f1687e 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,13 +1,18 @@ import React, {useEffect} from 'react'; -import {View} from 'react-native'; +import {ScrollView } from 'react-native'; import lodashGet from 'lodash/get'; import _ from 'underscore'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import Text from './Text'; -import styles from '../styles/styles'; import ONYXKEYS from '../ONYXKEYS'; import createInitialWaypoints from '../libs/actions/Transaction'; +import MenuItemWithTopDescription from './MenuItemWithTopDescription'; +import withLocalize, {withLocalizePropTypes} from './withLocalize'; +import compose from '../libs/compose'; +import * as Expensicons from './Icon/Expensicons'; +import theme from '../styles/themes/default'; + const propTypes = { /** The transactionID of this request */ @@ -24,6 +29,8 @@ const propTypes = { }) }), }), + + ...withLocalizePropTypes, }; const defaultProps = { @@ -31,27 +38,43 @@ const defaultProps = { transaction: {}, }; -function DistanceRequest({transaction, transactionID}) { +function DistanceRequest({transaction, transactionID, translate}) { + const waypoints = lodashGet(transaction, 'comment.waypoints'); + useEffect(() => { - const waypoints = lodashGet(transaction, 'comment.waypoints'); if (!transaction.transactionID || !_.isEmpty(waypoints)) { return; } // Create the initial start and stop waypoints createInitialWaypoints(transaction.transactionID); - }, [transaction]); + }, [transaction.transactionID, waypoints]); return ( - + + {_.map(waypoints, (waypoint, index) => { + let titleKey = 'distance.waypointTitle.'; + if (index === 0) { + titleKey += 'start'; + } else if (index === waypoints.length - 1) { + titleKey += 'finish'; + } else { + titleKey += 'stop'; + } + + return ; + })} Distance Request transactionID: {transactionID} - + ); } DistanceRequest.displayName = 'DistanceRequest'; DistanceRequest.propTypes = propTypes; DistanceRequest.defaultProps = defaultProps; -export default withOnyx({ - transaction: {key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, selector: (transaction) => ({transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}})}, -})(DistanceRequest); +export default compose( + withLocalize, + withOnyx({ + transaction: {key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, selector: (transaction) => ({transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}})}, + }) +)(DistanceRequest); diff --git a/src/languages/en.js b/src/languages/en.js index 7d287f67a90c..c6340c0904cb 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1545,4 +1545,11 @@ export default { levelTwoResult: 'Message hidden from channel, plus anonymous warning and message is reported for review.', levelThreeResult: 'Message removed from channel plus anonymous warning and message is reported for review.', }, + distance: { + waypointTitle: { + start: 'Start', + finish: 'Finish', + stop: 'Stop', + }, + } }; From 4b8e4e85c4d559694b462630f761fb76602dcc7e Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Fri, 28 Jul 2023 18:59:30 -0700 Subject: [PATCH 08/39] Fix dynamic waypoint title from key --- src/components/DistanceRequest.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index c00c57f1687e..1c8064799e36 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -39,7 +39,8 @@ const defaultProps = { }; function DistanceRequest({transaction, transactionID, translate}) { - const waypoints = lodashGet(transaction, 'comment.waypoints'); + const waypoints = lodashGet(transaction, 'comment.waypoints', {}) ; + const lastWaypointIndex = _.size(waypoints) - 1; useEffect(() => { if (!transaction.transactionID || !_.isEmpty(waypoints)) { @@ -51,11 +52,13 @@ function DistanceRequest({transaction, transactionID, translate}) { return ( - {_.map(waypoints, (waypoint, index) => { + {_.map(waypoints, (waypoint, key) => { + // key is of the form waypoint0, waypoint1, ... + const index = Number(key.replace('waypoint', '')); let titleKey = 'distance.waypointTitle.'; if (index === 0) { titleKey += 'start'; - } else if (index === waypoints.length - 1) { + } else if (index === lastWaypointIndex) { titleKey += 'finish'; } else { titleKey += 'stop'; From 1a1e7d212f89f42aa6e57cfcba5eefa6fbe94fdc Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Fri, 28 Jul 2023 19:06:01 -0700 Subject: [PATCH 09/39] Set waypoint description instead of title --- src/components/DistanceRequest.js | 10 +++++----- src/languages/en.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 1c8064799e36..12664d611e08 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -55,16 +55,16 @@ function DistanceRequest({transaction, transactionID, translate}) { {_.map(waypoints, (waypoint, key) => { // key is of the form waypoint0, waypoint1, ... const index = Number(key.replace('waypoint', '')); - let titleKey = 'distance.waypointTitle.'; + let descriptionKey = 'distance.waypointDescription.'; if (index === 0) { - titleKey += 'start'; + descriptionKey += 'start'; } else if (index === lastWaypointIndex) { - titleKey += 'finish'; + descriptionKey += 'finish'; } else { - titleKey += 'stop'; + descriptionKey += 'stop'; } - return ; + return ; })} Distance Request transactionID: {transactionID} diff --git a/src/languages/en.js b/src/languages/en.js index c6340c0904cb..50f3ab9f2e4e 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1546,7 +1546,7 @@ export default { levelThreeResult: 'Message removed from channel plus anonymous warning and message is reported for review.', }, distance: { - waypointTitle: { + waypointDescription: { start: 'Start', finish: 'Finish', stop: 'Stop', From 23b584ff83829a8b57853a08b4f3e690bdb34cd2 Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Fri, 28 Jul 2023 19:07:27 -0700 Subject: [PATCH 10/39] Style --- src/components/DistanceRequest.js | 24 +++++++++++++++++------- src/components/MenuItem.js | 5 +---- src/languages/en.js | 2 +- src/libs/actions/Transaction.js | 11 +++++------ src/pages/iou/DistanceRequestPage.js | 3 +-- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 12664d611e08..b6df936426c8 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,5 +1,5 @@ import React, {useEffect} from 'react'; -import {ScrollView } from 'react-native'; +import {ScrollView} from 'react-native'; import lodashGet from 'lodash/get'; import _ from 'underscore'; import PropTypes from 'prop-types'; @@ -13,7 +13,6 @@ import compose from '../libs/compose'; import * as Expensicons from './Icon/Expensicons'; import theme from '../styles/themes/default'; - const propTypes = { /** The transactionID of this request */ transactionID: PropTypes.string, @@ -26,7 +25,7 @@ const propTypes = { lat: PropTypes.number, lng: PropTypes.number, address: PropTypes.string, - }) + }), }), }), @@ -39,7 +38,7 @@ const defaultProps = { }; function DistanceRequest({transaction, transactionID, translate}) { - const waypoints = lodashGet(transaction, 'comment.waypoints', {}) ; + const waypoints = lodashGet(transaction, 'comment.waypoints', {}); const lastWaypointIndex = _.size(waypoints) - 1; useEffect(() => { @@ -64,7 +63,15 @@ function DistanceRequest({transaction, transactionID, translate}) { descriptionKey += 'stop'; } - return ; + return ( + + ); })} Distance Request transactionID: {transactionID} @@ -78,6 +85,9 @@ DistanceRequest.defaultProps = defaultProps; export default compose( withLocalize, withOnyx({ - transaction: {key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, selector: (transaction) => ({transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}})}, - }) + transaction: { + key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, + selector: (transaction) => ({transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}}), + }, + }), )(DistanceRequest); diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index f9c8db7e09ef..f3d564b78a64 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -204,10 +204,7 @@ function MenuItem(props) { height={props.iconHeight} fill={ props.secondaryIconFill || - StyleUtils.getIconFillColor( - getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), - true, - ) + StyleUtils.getIconFillColor(getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true) } /> diff --git a/src/languages/en.js b/src/languages/en.js index 50f3ab9f2e4e..fa52ee4b4846 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1551,5 +1551,5 @@ export default { finish: 'Finish', stop: 'Stop', }, - } + }, }; diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index a6f693e6165e..b5d9ec4bc680 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -5,12 +5,11 @@ function createInitialWaypoints(transactionID) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { comment: { waypoints: { - 'waypoint0': {}, - 'waypoint1': {}, - } - } + waypoint0: {}, + waypoint1: {}, + }, + }, }); - } -export default createInitialWaypoints; \ No newline at end of file +export default createInitialWaypoints; diff --git a/src/pages/iou/DistanceRequestPage.js b/src/pages/iou/DistanceRequestPage.js index ee65787050bc..9284975d4a27 100644 --- a/src/pages/iou/DistanceRequestPage.js +++ b/src/pages/iou/DistanceRequestPage.js @@ -66,7 +66,6 @@ function DistanceRequestPage({route, report, iou, transactionID}) { IOU.createEmptyTransaction(); }, [transactionID]); - return ( iou && iou.transactionID || ''}, + transactionID: {key: ONYXKEYS.IOU, selector: (iou) => (iou && iou.transactionID) || ''}, })(DistanceRequestPage); From c24b2484a247d8bd5fc5c27fa5ea2fa452a7938c Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Wed, 2 Aug 2023 09:31:49 -0500 Subject: [PATCH 11/39] WIP add stop button --- src/components/DistanceRequest.js | 15 +++++++++++---- src/languages/en.js | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index b6df936426c8..7a2e7c45e288 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -4,7 +4,6 @@ import lodashGet from 'lodash/get'; import _ from 'underscore'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; -import Text from './Text'; import ONYXKEYS from '../ONYXKEYS'; import createInitialWaypoints from '../libs/actions/Transaction'; import MenuItemWithTopDescription from './MenuItemWithTopDescription'; @@ -12,6 +11,8 @@ import withLocalize, {withLocalizePropTypes} from './withLocalize'; import compose from '../libs/compose'; import * as Expensicons from './Icon/Expensicons'; import theme from '../styles/themes/default'; +import Button from './Button'; +import styles from '../styles/styles'; const propTypes = { /** The transactionID of this request */ @@ -37,7 +38,7 @@ const defaultProps = { transaction: {}, }; -function DistanceRequest({transaction, transactionID, translate}) { +function DistanceRequest({transaction, translate}) { const waypoints = lodashGet(transaction, 'comment.waypoints', {}); const lastWaypointIndex = _.size(waypoints) - 1; @@ -73,8 +74,14 @@ function DistanceRequest({transaction, transactionID, translate}) { /> ); })} - Distance Request - transactionID: {transactionID} +