From 99363dab7c8b529c952aa565455f21d234dfdfff Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 16:04:58 -0600 Subject: [PATCH 01/15] convert to functional component --- .../MoneyRequestConfirmationList.js | 230 +++++++++--------- 1 file changed, 110 insertions(+), 120 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 048744c9eca7..c331917b20ff 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -1,4 +1,4 @@ -import React, {Component} from 'react'; +import React, {Component, useState, useCallback} from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -88,135 +88,127 @@ const defaultProps = { ...withCurrentUserPersonalDetailsDefaultProps, }; -class MoneyRequestConfirmationList extends Component { - constructor(props) { - super(props); +function MoneyRequestConfirmationList(props) { + const formattedParticipants = useCallback(_.map(this.getParticipantsWithAmount(props.participants), (participant) => ({ + ...participant, + selected: true, + })), [props.participants]); - const formattedParticipants = _.map(this.getParticipantsWithAmount(props.participants), (participant) => ({ - ...participant, - selected: true, - })); - - this.state = { - participants: formattedParticipants, - didConfirm: false, - }; - - this.toggleOption = this.toggleOption.bind(this); - this.confirm = this.confirm.bind(this); - } + const [participants, setParticipants] = useState(formattedParticipants); + const [didConfirm, setDidConfirm] = useState(false); /** * Get the confirmation button options * @returns {Array} */ - getSplitOrRequestOptions() { - const text = this.props.translate(this.props.hasMultipleParticipants ? 'iou.splitAmount' : 'iou.requestAmount', { - amount: CurrencyUtils.convertToDisplayString(this.props.iouAmount, this.props.iou.selectedCurrencyCode), + const getSplitOrRequestOptions = useCallback(() => { + const text = props.translate(props.hasMultipleParticipants ? 'iou.splitAmount' : 'iou.requestAmount', { + amount: CurrencyUtils.convertToDisplayString(props.iouAmount, props.iou.selectedCurrencyCode), }); return [ { text: text[0].toUpperCase() + text.slice(1), - value: this.props.hasMultipleParticipants ? CONST.IOU.MONEY_REQUEST_TYPE.SPLIT : CONST.IOU.MONEY_REQUEST_TYPE.REQUEST, + value: props.hasMultipleParticipants ? CONST.IOU.MONEY_REQUEST_TYPE.SPLIT : CONST.IOU.MONEY_REQUEST_TYPE.REQUEST, }, ]; - } + }, [props.hasMultipleParticipants, props.iouAmount, props.iou.selectedCurrencyCode]); /** * Get selected participants * @returns {Array} */ - getSelectedParticipants() { - return _.filter(this.state.participants, (participant) => participant.selected); - } + const getSelectedParticipants = useCallback(() => { + return _.filter(participants, (participant) => participant.selected); + }, [participants]); /** * Get unselected participants * @returns {Array} */ - getUnselectedParticipants() { - return _.filter(this.state.participants, (participant) => !participant.selected); - } + const getUnselectedParticipants = useCallback(() => { + return _.filter(participants, (participant) => !participant.selected); + }, [participants]); /** + * @TODO: should I use useCallback here??????????????????????????? * Returns the participants with amount * @param {Array} participants * @returns {Array} */ - getParticipantsWithAmount(participants) { - const iouAmount = IOUUtils.calculateAmount(participants.length, this.props.iouAmount); - return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participants, CurrencyUtils.convertToDisplayString(iouAmount, this.props.iou.selectedCurrencyCode)); + const getParticipantsWithAmount = (participants) => { + const iouAmount = IOUUtils.calculateAmount(participants.length, props.iouAmount); + return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participants, CurrencyUtils.convertToDisplayString(iouAmount, props.iou.selectedCurrencyCode)); } /** + * @TODO: should I use useCallback here??????????????????????????? * Returns the participants without amount * * @param {Array} participants * @returns {Array} */ - getParticipantsWithoutAmount(participants) { + const getParticipantsWithoutAmount = (participants) => { return _.map(participants, (option) => _.omit(option, 'descriptiveText')); } /** * Returns the sections needed for the OptionsSelector - * * @returns {Array} */ - getSections() { + const getSections = useCallback(() => { const sections = []; - if (this.props.hasMultipleParticipants) { - const selectedParticipants = this.getSelectedParticipants(); - const unselectedParticipants = this.getUnselectedParticipants(); + if (props.hasMultipleParticipants) { + const selectedParticipants = getSelectedParticipants(); + const unselectedParticipants = getUnselectedParticipants(); - const formattedSelectedParticipants = this.getParticipantsWithAmount(selectedParticipants); - const formattedUnselectedParticipants = this.getParticipantsWithoutAmount(unselectedParticipants); + const formattedSelectedParticipants = getParticipantsWithAmount(selectedParticipants); + const formattedUnselectedParticipants = getParticipantsWithoutAmount(unselectedParticipants); const formattedParticipants = _.union(formattedSelectedParticipants, formattedUnselectedParticipants); - const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants.length, this.props.iouAmount, true); + const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants.length, props.iouAmount, true); const formattedMyPersonalDetails = OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail( - this.props.currentUserPersonalDetails, - CurrencyUtils.convertToDisplayString(myIOUAmount, this.props.iou.selectedCurrencyCode), + props.currentUserPersonalDetails, + CurrencyUtils.convertToDisplayString(myIOUAmount, props.iou.selectedCurrencyCode), ); sections.push( { - title: this.props.translate('moneyRequestConfirmationList.whoPaid'), + title: props.translate('moneyRequestConfirmationList.whoPaid'), data: [formattedMyPersonalDetails], shouldShow: true, indexOffset: 0, isDisabled: true, }, { - title: this.props.translate('moneyRequestConfirmationList.whoWasThere'), + title: props.translate('moneyRequestConfirmationList.whoWasThere'), data: formattedParticipants, shouldShow: true, indexOffset: 1, }, ); } else { - const formattedParticipants = this.getParticipantsWithoutAmount(this.props.participants); + const formattedParticipants = this.getParticipantsWithoutAmount(props.participants); sections.push({ - title: this.props.translate('common.to'), + title: props.translate('common.to'), data: formattedParticipants, shouldShow: true, indexOffset: 0, }); } return sections; - } + }, [props.hasMultipleParticipants, props.iouAmount, props.currentUserPersonalDetails, props.iou.selectedCurrencyCode, props.participants]); /** * Returns selected options -- there is checkmark for every row in List for split flow * @returns {Array} */ - getSelectedOptions() { - if (!this.props.hasMultipleParticipants) { + const getSelectedOptions = useCallback(() => { + if (!props.hasMultipleParticipants) { return []; } - const selectedParticipants = this.getSelectedParticipants(); - return [...selectedParticipants, OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail(this.props.currentUserPersonalDetails)]; - } + const selectedParticipants = getSelectedParticipants(); + return [...selectedParticipants, OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail(props.currentUserPersonalDetails)]; + }, [props.hasMultipleParticipants, props.currentUserPersonalDetails]); /** * Toggle selected option's selected prop. @@ -224,7 +216,7 @@ class MoneyRequestConfirmationList extends Component { */ toggleOption(option) { // Return early if selected option is currently logged in user. - if (option.login === this.props.session.email) { + if (option.login === props.session.email) { return; } @@ -250,82 +242,80 @@ class MoneyRequestConfirmationList extends Component { return; } - if (this.props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND) { + if (props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND) { if (!paymentMethod) { return; } Log.info(`[IOU] Sending money via: ${paymentMethod}`); - this.props.onSendMoney(paymentMethod); + props.onSendMoney(paymentMethod); } else { - this.props.onConfirm(selectedParticipants); + props.onConfirm(selectedParticipants); } } - render() { - const selectedParticipants = this.getSelectedParticipants(); - const shouldShowSettlementButton = this.props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND; - const shouldDisableButton = selectedParticipants.length === 0; - const recipient = this.state.participants[0]; - const canModifyParticipants = this.props.canModifyParticipants && this.props.hasMultipleParticipants; - const formattedAmount = CurrencyUtils.convertToDisplayString(this.props.iouAmount, this.props.iou.selectedCurrencyCode); - - return ( - - ) : ( - this.confirm(value)} - options={this.getSplitOrRequestOptions()} - /> - ) - } - > - this.props.navigateToStep(0)} - style={[styles.moneyRequestMenuItem, styles.mt2]} - titleStyle={styles.moneyRequestConfirmationAmount} - disabled={this.state.didConfirm} - /> - Navigation.navigate(ROUTES.MONEY_REQUEST_DESCRIPTION)} - style={[styles.moneyRequestMenuItem, styles.mb2]} - disabled={this.state.didConfirm} - /> - - ); - } + const selectedParticipants = this.getSelectedParticipants(); + const shouldShowSettlementButton = props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND; + const shouldDisableButton = selectedParticipants.length === 0; + const recipient = participants[0]; + const canModifyParticipants = props.canModifyParticipants && props.hasMultipleParticipants; + const formattedAmount = CurrencyUtils.convertToDisplayString(props.iouAmount, props.iou.selectedCurrencyCode); + + return ( + + ) : ( + this.confirm(value)} + options={this.getSplitOrRequestOptions()} + /> + ) + } + > + props.navigateToStep(0)} + style={[styles.moneyRequestMenuItem, styles.mt2]} + titleStyle={styles.moneyRequestConfirmationAmount} + disabled={didConfirm} + /> + Navigation.navigate(ROUTES.MONEY_REQUEST_DESCRIPTION)} + style={[styles.moneyRequestMenuItem, styles.mb2]} + disabled={didConfirm} + /> + + ); } MoneyRequestConfirmationList.propTypes = propTypes; From 34ee559f2901b71b0ceddfe474fddfbb41f1546e Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 16:18:08 -0600 Subject: [PATCH 02/15] convert more functions --- .../MoneyRequestConfirmationList.js | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index c331917b20ff..241da8701cd6 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -89,7 +89,7 @@ const defaultProps = { }; function MoneyRequestConfirmationList(props) { - const formattedParticipants = useCallback(_.map(this.getParticipantsWithAmount(props.participants), (participant) => ({ + const formattedParticipants = useCallback(_.map(getParticipantsWithAmount(props.participants), (participant) => ({ ...participant, selected: true, })), [props.participants]); @@ -214,30 +214,30 @@ function MoneyRequestConfirmationList(props) { * Toggle selected option's selected prop. * @param {Object} option */ - toggleOption(option) { + const toggleOption = useCallback((option) => { // Return early if selected option is currently logged in user. if (option.login === props.session.email) { return; } - this.setState((prevState) => { - const newParticipants = _.map(prevState.participants, (participant) => { + setParticipants((prevParticipants) => { + const newParticipants = _.map(prevParticipants, (participant) => { if (participant.login === option.login) { - return {...participant, selected: !participant.selected}; + return { ...participant, selected: !participant.selected }; } return participant; }); - return {participants: newParticipants}; + return newParticipants; }); - } + }, [props.session.email]); /** * @param {String} paymentMethod */ - confirm(paymentMethod) { - this.setState({didConfirm: true}); + const confirm = useCallback((paymentMethod) => { + setDidConfirm(true); - const selectedParticipants = this.getSelectedParticipants(); + const selectedParticipants = getSelectedParticipants(); if (_.isEmpty(selectedParticipants)) { return; } @@ -252,9 +252,9 @@ function MoneyRequestConfirmationList(props) { } else { props.onConfirm(selectedParticipants); } - } + }, [getSelectedParticipants, props.iouType, props.onSendMoney, props.onConfirm]); - const selectedParticipants = this.getSelectedParticipants(); + const selectedParticipants = getSelectedParticipants(); const shouldShowSettlementButton = props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND; const shouldDisableButton = selectedParticipants.length === 0; const recipient = participants[0]; @@ -263,11 +263,11 @@ function MoneyRequestConfirmationList(props) { return ( this.confirm(value)} - options={this.getSplitOrRequestOptions()} + onPress={(_event, value) => confirm(value)} + options={getSplitOrRequestOptions()} /> ) } From 1703839f29a784a0706abe02c9fe7a246cfaf2c3 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 16:23:05 -0600 Subject: [PATCH 03/15] fix style --- .../MoneyRequestConfirmationList.js | 96 ++++++++++--------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 241da8701cd6..5af8ec84ca71 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -89,10 +89,23 @@ const defaultProps = { }; function MoneyRequestConfirmationList(props) { - const formattedParticipants = useCallback(_.map(getParticipantsWithAmount(props.participants), (participant) => ({ + /** + * Returns the participants with amount + * @param {Array} participants + * @returns {Array} + */ + const getParticipantsWithAmount = useCallback( + (participants) => { + const iouAmount = IOUUtils.calculateAmount(participants.length, props.iouAmount); + return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participants, CurrencyUtils.convertToDisplayString(iouAmount, props.iou.selectedCurrencyCode)); + }, + [props.iouAmount, props.iou.selectedCurrencyCode], + ); + + const formattedParticipants = _.map(getParticipantsWithAmount(props.participants), (participant) => ({ ...participant, selected: true, - })), [props.participants]); + })); const [participants, setParticipants] = useState(formattedParticipants); const [didConfirm, setDidConfirm] = useState(false); @@ -129,17 +142,6 @@ function MoneyRequestConfirmationList(props) { return _.filter(participants, (participant) => !participant.selected); }, [participants]); - /** - * @TODO: should I use useCallback here??????????????????????????? - * Returns the participants with amount - * @param {Array} participants - * @returns {Array} - */ - const getParticipantsWithAmount = (participants) => { - const iouAmount = IOUUtils.calculateAmount(participants.length, props.iouAmount); - return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participants, CurrencyUtils.convertToDisplayString(iouAmount, props.iou.selectedCurrencyCode)); - } - /** * @TODO: should I use useCallback here??????????????????????????? * Returns the participants without amount @@ -149,7 +151,7 @@ function MoneyRequestConfirmationList(props) { */ const getParticipantsWithoutAmount = (participants) => { return _.map(participants, (option) => _.omit(option, 'descriptiveText')); - } + }; /** * Returns the sections needed for the OptionsSelector @@ -187,7 +189,7 @@ function MoneyRequestConfirmationList(props) { }, ); } else { - const formattedParticipants = this.getParticipantsWithoutAmount(props.participants); + const formattedParticipants = getParticipantsWithoutAmount(props.participants); sections.push({ title: props.translate('common.to'), data: formattedParticipants, @@ -214,45 +216,51 @@ function MoneyRequestConfirmationList(props) { * Toggle selected option's selected prop. * @param {Object} option */ - const toggleOption = useCallback((option) => { - // Return early if selected option is currently logged in user. - if (option.login === props.session.email) { - return; - } + const toggleOption = useCallback( + (option) => { + // Return early if selected option is currently logged in user. + if (option.login === props.session.email) { + return; + } - setParticipants((prevParticipants) => { - const newParticipants = _.map(prevParticipants, (participant) => { - if (participant.login === option.login) { - return { ...participant, selected: !participant.selected }; - } - return participant; + setParticipants((prevParticipants) => { + const newParticipants = _.map(prevParticipants, (participant) => { + if (participant.login === option.login) { + return {...participant, selected: !participant.selected}; + } + return participant; + }); + return newParticipants; }); - return newParticipants; - }); - }, [props.session.email]); + }, + [props.session.email], + ); /** * @param {String} paymentMethod */ - const confirm = useCallback((paymentMethod) => { - setDidConfirm(true); - - const selectedParticipants = getSelectedParticipants(); - if (_.isEmpty(selectedParticipants)) { - return; - } + const confirm = useCallback( + (paymentMethod) => { + setDidConfirm(true); - if (props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND) { - if (!paymentMethod) { + const selectedParticipants = getSelectedParticipants(); + if (_.isEmpty(selectedParticipants)) { return; } - Log.info(`[IOU] Sending money via: ${paymentMethod}`); - props.onSendMoney(paymentMethod); - } else { - props.onConfirm(selectedParticipants); - } - }, [getSelectedParticipants, props.iouType, props.onSendMoney, props.onConfirm]); + if (props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND) { + if (!paymentMethod) { + return; + } + + Log.info(`[IOU] Sending money via: ${paymentMethod}`); + props.onSendMoney(paymentMethod); + } else { + props.onConfirm(selectedParticipants); + } + }, + [getSelectedParticipants, props.iouType, props.onSendMoney, props.onConfirm], + ); const selectedParticipants = getSelectedParticipants(); const shouldShowSettlementButton = props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND; From 6ec7da5e9a440d1f8e2d923cee362d4250549b8f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 16:26:17 -0600 Subject: [PATCH 04/15] fix some errors --- .../MoneyRequestConfirmationList.js | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 5af8ec84ca71..d2ea8a88f53e 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -130,28 +130,21 @@ function MoneyRequestConfirmationList(props) { * Get selected participants * @returns {Array} */ - const getSelectedParticipants = useCallback(() => { - return _.filter(participants, (participant) => participant.selected); - }, [participants]); + const getSelectedParticipants = useCallback(() => _.filter(participants, (participant) => participant.selected), [participants]); /** * Get unselected participants * @returns {Array} */ - const getUnselectedParticipants = useCallback(() => { - return _.filter(participants, (participant) => !participant.selected); - }, [participants]); + const getUnselectedParticipants = useCallback(() => _.filter(participants, (participant) => !participant.selected), [participants]); /** - * @TODO: should I use useCallback here??????????????????????????? * Returns the participants without amount * * @param {Array} participants * @returns {Array} */ - const getParticipantsWithoutAmount = (participants) => { - return _.map(participants, (option) => _.omit(option, 'descriptiveText')); - }; + const getParticipantsWithoutAmount = useCallback((participantsList) => _.map(participantsList, (option) => _.omit(option, 'descriptiveText')), []); /** * Returns the sections needed for the OptionsSelector @@ -165,7 +158,7 @@ function MoneyRequestConfirmationList(props) { const formattedSelectedParticipants = getParticipantsWithAmount(selectedParticipants); const formattedUnselectedParticipants = getParticipantsWithoutAmount(unselectedParticipants); - const formattedParticipants = _.union(formattedSelectedParticipants, formattedUnselectedParticipants); + const formattedParticipantsList = _.union(formattedSelectedParticipants, formattedUnselectedParticipants); const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants.length, props.iouAmount, true); const formattedMyPersonalDetails = OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail( @@ -183,16 +176,16 @@ function MoneyRequestConfirmationList(props) { }, { title: props.translate('moneyRequestConfirmationList.whoWasThere'), - data: formattedParticipants, + data: formattedParticipantsList, shouldShow: true, indexOffset: 1, }, ); } else { - const formattedParticipants = getParticipantsWithoutAmount(props.participants); + const formattedParticipantsList = getParticipantsWithoutAmount(props.participants); sections.push({ title: props.translate('common.to'), - data: formattedParticipants, + data: formattedParticipantsList, shouldShow: true, indexOffset: 0, }); From d1c7374a6c3e218a8407a4a762c452d58807bff8 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 16:43:12 -0600 Subject: [PATCH 05/15] add more dependencies --- src/components/MoneyRequestConfirmationList.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index d2ea8a88f53e..414b219713d9 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -1,4 +1,4 @@ -import React, {Component, useState, useCallback} from 'react'; +import React, {useState, useCallback} from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -191,7 +191,7 @@ function MoneyRequestConfirmationList(props) { }); } return sections; - }, [props.hasMultipleParticipants, props.iouAmount, props.currentUserPersonalDetails, props.iou.selectedCurrencyCode, props.participants]); + }, [getSelectedParticipants, getUnselectedParticipants, getParticipantsWithAmount, getParticipantsWithoutAmount, props.hasMultipleParticipants, props.iouAmount, props.currentUserPersonalDetails, props.iou.selectedCurrencyCode, props.participants]); /** * Returns selected options -- there is checkmark for every row in List for split flow @@ -203,7 +203,7 @@ function MoneyRequestConfirmationList(props) { } const selectedParticipants = getSelectedParticipants(); return [...selectedParticipants, OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail(props.currentUserPersonalDetails)]; - }, [props.hasMultipleParticipants, props.currentUserPersonalDetails]); + }, [getSelectedParticipants, props.hasMultipleParticipants, props.currentUserPersonalDetails]); /** * Toggle selected option's selected prop. From 4033c8dd522c9f34c9e4c286cab36e5dc5eb57c7 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 16:43:29 -0600 Subject: [PATCH 06/15] fix styles --- src/components/MoneyRequestConfirmationList.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 414b219713d9..52073270a0b8 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -191,7 +191,17 @@ function MoneyRequestConfirmationList(props) { }); } return sections; - }, [getSelectedParticipants, getUnselectedParticipants, getParticipantsWithAmount, getParticipantsWithoutAmount, props.hasMultipleParticipants, props.iouAmount, props.currentUserPersonalDetails, props.iou.selectedCurrencyCode, props.participants]); + }, [ + getSelectedParticipants, + getUnselectedParticipants, + getParticipantsWithAmount, + getParticipantsWithoutAmount, + props.hasMultipleParticipants, + props.iouAmount, + props.currentUserPersonalDetails, + props.iou.selectedCurrencyCode, + props.participants, + ]); /** * Returns selected options -- there is checkmark for every row in List for split flow From 9c15261a45e2170c6002a3ccea97c58888f9b3ee Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 17:05:39 -0600 Subject: [PATCH 07/15] include translate --- src/components/MoneyRequestConfirmationList.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 52073270a0b8..702a9a3ca907 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -124,7 +124,7 @@ function MoneyRequestConfirmationList(props) { value: props.hasMultipleParticipants ? CONST.IOU.MONEY_REQUEST_TYPE.SPLIT : CONST.IOU.MONEY_REQUEST_TYPE.REQUEST, }, ]; - }, [props.hasMultipleParticipants, props.iouAmount, props.iou.selectedCurrencyCode]); + }, [props.hasMultipleParticipants, props.iouAmount, props.iou.selectedCurrencyCode, props.translate]); /** * Get selected participants @@ -201,6 +201,7 @@ function MoneyRequestConfirmationList(props) { props.currentUserPersonalDetails, props.iou.selectedCurrencyCode, props.participants, + props.translate, ]); /** From b03b92d21c2cf70275cd69b8d6d014fdb5287a51 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 17:20:44 -0600 Subject: [PATCH 08/15] use useMemo --- src/components/MoneyRequestConfirmationList.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 702a9a3ca907..4334942e0f4d 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -1,4 +1,4 @@ -import React, {useState, useCallback} from 'react'; +import React, {useState, useCallback, useMemo} from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -94,7 +94,7 @@ function MoneyRequestConfirmationList(props) { * @param {Array} participants * @returns {Array} */ - const getParticipantsWithAmount = useCallback( + const getParticipantsWithAmount = useMemo( (participants) => { const iouAmount = IOUUtils.calculateAmount(participants.length, props.iouAmount); return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participants, CurrencyUtils.convertToDisplayString(iouAmount, props.iou.selectedCurrencyCode)); @@ -114,7 +114,7 @@ function MoneyRequestConfirmationList(props) { * Get the confirmation button options * @returns {Array} */ - const getSplitOrRequestOptions = useCallback(() => { + const getSplitOrRequestOptions = useMemo(() => { const text = props.translate(props.hasMultipleParticipants ? 'iou.splitAmount' : 'iou.requestAmount', { amount: CurrencyUtils.convertToDisplayString(props.iouAmount, props.iou.selectedCurrencyCode), }); @@ -130,13 +130,13 @@ function MoneyRequestConfirmationList(props) { * Get selected participants * @returns {Array} */ - const getSelectedParticipants = useCallback(() => _.filter(participants, (participant) => participant.selected), [participants]); + const getSelectedParticipants = useMemo(() => _.filter(participants, (participant) => participant.selected), [participants]); /** * Get unselected participants * @returns {Array} */ - const getUnselectedParticipants = useCallback(() => _.filter(participants, (participant) => !participant.selected), [participants]); + const getUnselectedParticipants = useMemo(() => _.filter(participants, (participant) => !participant.selected), [participants]); /** * Returns the participants without amount @@ -144,13 +144,13 @@ function MoneyRequestConfirmationList(props) { * @param {Array} participants * @returns {Array} */ - const getParticipantsWithoutAmount = useCallback((participantsList) => _.map(participantsList, (option) => _.omit(option, 'descriptiveText')), []); + const getParticipantsWithoutAmount = useMemo((participantsList) => _.map(participantsList, (option) => _.omit(option, 'descriptiveText')), []); /** * Returns the sections needed for the OptionsSelector * @returns {Array} */ - const getSections = useCallback(() => { + const getSections = useMemo(() => { const sections = []; if (props.hasMultipleParticipants) { const selectedParticipants = getSelectedParticipants(); @@ -208,7 +208,7 @@ function MoneyRequestConfirmationList(props) { * Returns selected options -- there is checkmark for every row in List for split flow * @returns {Array} */ - const getSelectedOptions = useCallback(() => { + const getSelectedOptions = useMemo(() => { if (!props.hasMultipleParticipants) { return []; } From 7e21fc7dd0faf1284d0320513870ba75b3fa727d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 17:39:44 -0600 Subject: [PATCH 09/15] refactor functions to consts --- .../MoneyRequestConfirmationList.js | 55 +++++-------------- 1 file changed, 14 insertions(+), 41 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 4334942e0f4d..ba052a7d064e 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -94,7 +94,7 @@ function MoneyRequestConfirmationList(props) { * @param {Array} participants * @returns {Array} */ - const getParticipantsWithAmount = useMemo( + const getParticipantsWithAmount = useCallback( (participants) => { const iouAmount = IOUUtils.calculateAmount(participants.length, props.iouAmount); return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participants, CurrencyUtils.convertToDisplayString(iouAmount, props.iou.selectedCurrencyCode)); @@ -110,11 +110,7 @@ function MoneyRequestConfirmationList(props) { const [participants, setParticipants] = useState(formattedParticipants); const [didConfirm, setDidConfirm] = useState(false); - /** - * Get the confirmation button options - * @returns {Array} - */ - const getSplitOrRequestOptions = useMemo(() => { + const splitOrRequestOptions = useMemo(() => { const text = props.translate(props.hasMultipleParticipants ? 'iou.splitAmount' : 'iou.requestAmount', { amount: CurrencyUtils.convertToDisplayString(props.iouAmount, props.iou.selectedCurrencyCode), }); @@ -126,17 +122,8 @@ function MoneyRequestConfirmationList(props) { ]; }, [props.hasMultipleParticipants, props.iouAmount, props.iou.selectedCurrencyCode, props.translate]); - /** - * Get selected participants - * @returns {Array} - */ - const getSelectedParticipants = useMemo(() => _.filter(participants, (participant) => participant.selected), [participants]); - - /** - * Get unselected participants - * @returns {Array} - */ - const getUnselectedParticipants = useMemo(() => _.filter(participants, (participant) => !participant.selected), [participants]); + const selectedParticipants = useMemo(() => _.filter(participants, (participant) => participant.selected), [participants]); + const unselectedParticipants = useMemo(() => _.filter(participants, (participant) => !participant.selected), [participants]); /** * Returns the participants without amount @@ -144,18 +131,11 @@ function MoneyRequestConfirmationList(props) { * @param {Array} participants * @returns {Array} */ - const getParticipantsWithoutAmount = useMemo((participantsList) => _.map(participantsList, (option) => _.omit(option, 'descriptiveText')), []); + const getParticipantsWithoutAmount = useCallback((participantsList) => _.map(participantsList, (option) => _.omit(option, 'descriptiveText')), []); - /** - * Returns the sections needed for the OptionsSelector - * @returns {Array} - */ - const getSections = useMemo(() => { + const optionSelectorSections = useMemo(() => { const sections = []; if (props.hasMultipleParticipants) { - const selectedParticipants = getSelectedParticipants(); - const unselectedParticipants = getUnselectedParticipants(); - const formattedSelectedParticipants = getParticipantsWithAmount(selectedParticipants); const formattedUnselectedParticipants = getParticipantsWithoutAmount(unselectedParticipants); const formattedParticipantsList = _.union(formattedSelectedParticipants, formattedUnselectedParticipants); @@ -192,8 +172,8 @@ function MoneyRequestConfirmationList(props) { } return sections; }, [ - getSelectedParticipants, - getUnselectedParticipants, + selectedParticipants, + unselectedParticipants, getParticipantsWithAmount, getParticipantsWithoutAmount, props.hasMultipleParticipants, @@ -204,17 +184,12 @@ function MoneyRequestConfirmationList(props) { props.translate, ]); - /** - * Returns selected options -- there is checkmark for every row in List for split flow - * @returns {Array} - */ - const getSelectedOptions = useMemo(() => { + const selectedOptions = useMemo(() => { if (!props.hasMultipleParticipants) { return []; } - const selectedParticipants = getSelectedParticipants(); return [...selectedParticipants, OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail(props.currentUserPersonalDetails)]; - }, [getSelectedParticipants, props.hasMultipleParticipants, props.currentUserPersonalDetails]); + }, [selectedParticipants, props.hasMultipleParticipants, props.currentUserPersonalDetails]); /** * Toggle selected option's selected prop. @@ -247,7 +222,6 @@ function MoneyRequestConfirmationList(props) { (paymentMethod) => { setDidConfirm(true); - const selectedParticipants = getSelectedParticipants(); if (_.isEmpty(selectedParticipants)) { return; } @@ -263,10 +237,9 @@ function MoneyRequestConfirmationList(props) { props.onConfirm(selectedParticipants); } }, - [getSelectedParticipants, props.iouType, props.onSendMoney, props.onConfirm], + [selectedParticipants, props.iouType, props.onSendMoney, props.onConfirm], ); - const selectedParticipants = getSelectedParticipants(); const shouldShowSettlementButton = props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND; const shouldDisableButton = selectedParticipants.length === 0; const recipient = participants[0]; @@ -275,11 +248,11 @@ function MoneyRequestConfirmationList(props) { return ( confirm(value)} - options={getSplitOrRequestOptions()} + options={splitOrRequestOptions} /> ) } From 8a544086776fd3bd3d8dab9904d8eadc04325ea1 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 May 2023 17:53:32 -0600 Subject: [PATCH 10/15] rename param --- src/components/MoneyRequestConfirmationList.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index ba052a7d064e..76148578a161 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -95,9 +95,9 @@ function MoneyRequestConfirmationList(props) { * @returns {Array} */ const getParticipantsWithAmount = useCallback( - (participants) => { - const iouAmount = IOUUtils.calculateAmount(participants.length, props.iouAmount); - return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participants, CurrencyUtils.convertToDisplayString(iouAmount, props.iou.selectedCurrencyCode)); + (participantsList) => { + const iouAmount = IOUUtils.calculateAmount(participantsList.length, props.iouAmount); + return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participantsList, CurrencyUtils.convertToDisplayString(iouAmount, props.iou.selectedCurrencyCode)); }, [props.iouAmount, props.iou.selectedCurrencyCode], ); From 803690555f8b1504e15a2fec54e64fc6ba3e05fa Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 25 May 2023 10:08:07 -0600 Subject: [PATCH 11/15] destructure functions in props --- .../MoneyRequestConfirmationList.js | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 76148578a161..a6ab804928e7 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -89,6 +89,10 @@ const defaultProps = { }; function MoneyRequestConfirmationList(props) { + // Destructure functions from props to pass it as a dependecy to useCallback/useMemo hooks. + // Prop functions pass props itself as a "this" value to the function which means they change every time props change. + const {translate, onSendMoney, onConfirm} = props; + /** * Returns the participants with amount * @param {Array} participants @@ -111,7 +115,7 @@ function MoneyRequestConfirmationList(props) { const [didConfirm, setDidConfirm] = useState(false); const splitOrRequestOptions = useMemo(() => { - const text = props.translate(props.hasMultipleParticipants ? 'iou.splitAmount' : 'iou.requestAmount', { + const text = translate(props.hasMultipleParticipants ? 'iou.splitAmount' : 'iou.requestAmount', { amount: CurrencyUtils.convertToDisplayString(props.iouAmount, props.iou.selectedCurrencyCode), }); return [ @@ -120,7 +124,7 @@ function MoneyRequestConfirmationList(props) { value: props.hasMultipleParticipants ? CONST.IOU.MONEY_REQUEST_TYPE.SPLIT : CONST.IOU.MONEY_REQUEST_TYPE.REQUEST, }, ]; - }, [props.hasMultipleParticipants, props.iouAmount, props.iou.selectedCurrencyCode, props.translate]); + }, [props.hasMultipleParticipants, props.iouAmount, props.iou.selectedCurrencyCode, translate]); const selectedParticipants = useMemo(() => _.filter(participants, (participant) => participant.selected), [participants]); const unselectedParticipants = useMemo(() => _.filter(participants, (participant) => !participant.selected), [participants]); @@ -148,14 +152,14 @@ function MoneyRequestConfirmationList(props) { sections.push( { - title: props.translate('moneyRequestConfirmationList.whoPaid'), + title: translate('moneyRequestConfirmationList.whoPaid'), data: [formattedMyPersonalDetails], shouldShow: true, indexOffset: 0, isDisabled: true, }, { - title: props.translate('moneyRequestConfirmationList.whoWasThere'), + title: translate('moneyRequestConfirmationList.whoWasThere'), data: formattedParticipantsList, shouldShow: true, indexOffset: 1, @@ -164,7 +168,7 @@ function MoneyRequestConfirmationList(props) { } else { const formattedParticipantsList = getParticipantsWithoutAmount(props.participants); sections.push({ - title: props.translate('common.to'), + title: translate('common.to'), data: formattedParticipantsList, shouldShow: true, indexOffset: 0, @@ -181,7 +185,7 @@ function MoneyRequestConfirmationList(props) { props.currentUserPersonalDetails, props.iou.selectedCurrencyCode, props.participants, - props.translate, + translate, ]); const selectedOptions = useMemo(() => { @@ -232,12 +236,12 @@ function MoneyRequestConfirmationList(props) { } Log.info(`[IOU] Sending money via: ${paymentMethod}`); - props.onSendMoney(paymentMethod); + onSendMoney(paymentMethod); } else { - props.onConfirm(selectedParticipants); + onConfirm(selectedParticipants); } }, - [selectedParticipants, props.iouType, props.onSendMoney, props.onConfirm], + [selectedParticipants, onSendMoney, onConfirm, props.iouType], ); const shouldShowSettlementButton = props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND; @@ -285,7 +289,7 @@ function MoneyRequestConfirmationList(props) { props.navigateToStep(0)} style={[styles.moneyRequestMenuItem, styles.mt2]} titleStyle={styles.moneyRequestConfirmationAmount} @@ -294,7 +298,7 @@ function MoneyRequestConfirmationList(props) { Navigation.navigate(ROUTES.MONEY_REQUEST_DESCRIPTION)} style={[styles.moneyRequestMenuItem, styles.mb2]} disabled={didConfirm} From 65f67be3c1d671502b823bbd6612a61cffa5b971 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 25 May 2023 10:09:14 -0600 Subject: [PATCH 12/15] convert formattedParticipants to function --- src/components/MoneyRequestConfirmationList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index a6ab804928e7..55d2de9fe48b 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -106,12 +106,12 @@ function MoneyRequestConfirmationList(props) { [props.iouAmount, props.iou.selectedCurrencyCode], ); - const formattedParticipants = _.map(getParticipantsWithAmount(props.participants), (participant) => ({ + const getFormattedParticipants = () => _.map(getParticipantsWithAmount(props.participants), (participant) => ({ ...participant, selected: true, })); - const [participants, setParticipants] = useState(formattedParticipants); + const [participants, setParticipants] = useState(getFormattedParticipants); const [didConfirm, setDidConfirm] = useState(false); const splitOrRequestOptions = useMemo(() => { From 777b1c3c8c2baa2d87cc2be5d27655f913a2e886 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 25 May 2023 10:15:08 -0600 Subject: [PATCH 13/15] move unselectedParticipants --- src/components/MoneyRequestConfirmationList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 55d2de9fe48b..dee31d7f8443 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -127,7 +127,6 @@ function MoneyRequestConfirmationList(props) { }, [props.hasMultipleParticipants, props.iouAmount, props.iou.selectedCurrencyCode, translate]); const selectedParticipants = useMemo(() => _.filter(participants, (participant) => participant.selected), [participants]); - const unselectedParticipants = useMemo(() => _.filter(participants, (participant) => !participant.selected), [participants]); /** * Returns the participants without amount @@ -139,6 +138,7 @@ function MoneyRequestConfirmationList(props) { const optionSelectorSections = useMemo(() => { const sections = []; + const unselectedParticipants = _.filter(participants, (participant) => !participant.selected); if (props.hasMultipleParticipants) { const formattedSelectedParticipants = getParticipantsWithAmount(selectedParticipants); const formattedUnselectedParticipants = getParticipantsWithoutAmount(unselectedParticipants); @@ -177,7 +177,6 @@ function MoneyRequestConfirmationList(props) { return sections; }, [ selectedParticipants, - unselectedParticipants, getParticipantsWithAmount, getParticipantsWithoutAmount, props.hasMultipleParticipants, @@ -185,6 +184,7 @@ function MoneyRequestConfirmationList(props) { props.currentUserPersonalDetails, props.iou.selectedCurrencyCode, props.participants, + participants, translate, ]); From fdb899eb9ba7aba9eef1b9232afce10f3882b419 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 25 May 2023 10:19:46 -0600 Subject: [PATCH 14/15] fix style --- src/components/MoneyRequestConfirmationList.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index dee31d7f8443..5ffb71dbd37b 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -106,10 +106,11 @@ function MoneyRequestConfirmationList(props) { [props.iouAmount, props.iou.selectedCurrencyCode], ); - const getFormattedParticipants = () => _.map(getParticipantsWithAmount(props.participants), (participant) => ({ - ...participant, - selected: true, - })); + const getFormattedParticipants = () => + _.map(getParticipantsWithAmount(props.participants), (participant) => ({ + ...participant, + selected: true, + })); const [participants, setParticipants] = useState(getFormattedParticipants); const [didConfirm, setDidConfirm] = useState(false); From b09946d524f619aa9f75df0e48f501b20a459e4a Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 7 Jun 2023 09:13:56 -0600 Subject: [PATCH 15/15] rm comment --- src/components/MoneyRequestConfirmationList.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 3aef3331e2ff..3fca7f714be7 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -143,15 +143,7 @@ function MoneyRequestConfirmationList(props) { }, [props.hasMultipleParticipants, props.iouAmount, props.iouCurrencyCode, translate]); const selectedParticipants = useMemo(() => _.filter(participants, (participant) => participant.selected), [participants]); - - /** - * Returns the participants without amount - * - * @param {Array} participants - * @returns {Array} - */ const getParticipantsWithoutAmount = useCallback((participantsList) => _.map(participantsList, (option) => _.omit(option, 'descriptiveText')), []); - const payeePersonalDetails = useMemo(() => props.payeePersonalDetails || props.currentUserPersonalDetails, [props.payeePersonalDetails, props.currentUserPersonalDetails]); const optionSelectorSections = useMemo(() => {