From 9eafd1fce280df3a53617063348a525f3f2ca6b5 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 7 Dec 2023 09:39:04 -0300 Subject: [PATCH 01/32] Add 'didScreenTransitionEnd' prop to MoneyRequestParticipantsSelector --- .../MoneyRequestParticipantsSelector.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index c08c8c0a21b8..8d6ed55724bf 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -66,6 +66,9 @@ const propTypes = { /** Whether we are searching for reports in the server */ isSearchingForReports: PropTypes.bool, + /** Whether the screen transition has ended */ + didScreenTransitionEnd: PropTypes.bool, + ...withLocalizePropTypes, }; @@ -78,6 +81,7 @@ const defaultProps = { betas: [], isDistanceRequest: false, isSearchingForReports: false, + didScreenTransitionEnd: false, }; function MoneyRequestParticipantsSelector({ @@ -94,6 +98,7 @@ function MoneyRequestParticipantsSelector({ iouType, isDistanceRequest, isSearchingForReports, + didScreenTransitionEnd, }) { const styles = useThemeStyles(); const [searchTerm, setSearchTerm] = useState(''); From a5ed7d8ddc0cdcb9d1caa0da9e391bcb3b751c04 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 7 Dec 2023 09:41:25 -0300 Subject: [PATCH 02/32] Integrate 'didScreenTransitionEnd' prop in MoneyRequestParticipantsPage --- .../MoneyRequestParticipantsPage.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js index d0982e6296db..edf452c78848 100644 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js @@ -132,7 +132,7 @@ function MoneyRequestParticipantsPage({iou, selectedTab, route, transaction}) { onEntryTransitionEnd={() => optionsSelectorRef.current && optionsSelectorRef.current.focus()} testID={MoneyRequestParticipantsPage.displayName} > - {({safeAreaPaddingBottomStyle}) => ( + {({safeAreaPaddingBottomStyle, didScreenTransitionEnd}) => ( )} From 19d6d6856cd2b713a8da56b47a8b4c35d444a7e8 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 7 Dec 2023 09:44:33 -0300 Subject: [PATCH 03/32] Conditionally update chatOptions on screen transition end --- .../MoneyRequestParticipantsSelector.js | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index 8d6ed55724bf..292ace6c9c50 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -230,37 +230,39 @@ function MoneyRequestParticipantsSelector({ const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); useEffect(() => { - const chatOptions = OptionsListUtils.getFilteredOptions( - reports, - personalDetails, - betas, - searchTerm, - participants, - CONST.EXPENSIFY_EMAILS, - - // If we are using this component in the "Request money" flow then we pass the includeOwnedWorkspaceChats argument so that the current user - // sees the option to request money from their admin on their own Workspace Chat. - iouType === CONST.IOU.TYPE.REQUEST, - - // We don't want to include any P2P options like personal details or reports that are not workspace chats for certain features. - !isDistanceRequest, - false, - {}, - [], - false, - {}, - [], - // We don't want the user to be able to invite individuals when they are in the "Distance request" flow for now. - // This functionality is being built here: https://github.com/Expensify/App/issues/23291 - !isDistanceRequest, - true, - ); - setNewChatOptions({ - recentReports: chatOptions.recentReports, - personalDetails: chatOptions.personalDetails, - userToInvite: chatOptions.userToInvite, - }); - }, [betas, reports, participants, personalDetails, translate, searchTerm, setNewChatOptions, iouType, isDistanceRequest]); + if (didScreenTransitionEnd) { + const chatOptions = OptionsListUtils.getFilteredOptions( + reports, + personalDetails, + betas, + searchTerm, + participants, + CONST.EXPENSIFY_EMAILS, + + // If we are using this component in the "Request money" flow then we pass the includeOwnedWorkspaceChats argument so that the current user + // sees the option to request money from their admin on their own Workspace Chat. + iouType === CONST.IOU.TYPE.REQUEST, + + // We don't want to include any P2P options like personal details or reports that are not workspace chats for certain features. + !isDistanceRequest, + false, + {}, + [], + false, + {}, + [], + // We don't want the user to be able to invite individuals when they are in the "Distance request" flow for now. + // This functionality is being built here: https://github.com/Expensify/App/issues/23291 + !isDistanceRequest, + true, + ); + setNewChatOptions({ + recentReports: chatOptions.recentReports, + personalDetails: chatOptions.personalDetails, + userToInvite: chatOptions.userToInvite, + }); + } + }, [betas, reports, participants, personalDetails, translate, searchTerm, setNewChatOptions, iouType, isDistanceRequest, didScreenTransitionEnd]); // When search term updates we will fetch any reports const setSearchTermAndSearchInServer = useCallback((text = '') => { From ef06c1f4d00c4685b5cd8c11c7e95c91676a1461 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 14 Dec 2023 15:36:28 -0300 Subject: [PATCH 04/32] Revert "Conditionally update chatOptions on screen transition end" This reverts commit 19d6d6856cd2b713a8da56b47a8b4c35d444a7e8. --- .../MoneyRequestParticipantsSelector.js | 64 +++++++++---------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index 14e94db38202..8c0fc71b0112 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -230,39 +230,37 @@ function MoneyRequestParticipantsSelector({ const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); useEffect(() => { - if (didScreenTransitionEnd) { - const chatOptions = OptionsListUtils.getFilteredOptions( - reports, - personalDetails, - betas, - searchTerm, - participants, - CONST.EXPENSIFY_EMAILS, - - // If we are using this component in the "Request money" flow then we pass the includeOwnedWorkspaceChats argument so that the current user - // sees the option to request money from their admin on their own Workspace Chat. - iouType === CONST.IOU.TYPE.REQUEST, - - // We don't want to include any P2P options like personal details or reports that are not workspace chats for certain features. - !isDistanceRequest, - false, - {}, - [], - false, - {}, - [], - // We don't want the user to be able to invite individuals when they are in the "Distance request" flow for now. - // This functionality is being built here: https://github.com/Expensify/App/issues/23291 - !isDistanceRequest, - true, - ); - setNewChatOptions({ - recentReports: chatOptions.recentReports, - personalDetails: chatOptions.personalDetails, - userToInvite: chatOptions.userToInvite, - }); - } - }, [betas, reports, participants, personalDetails, translate, searchTerm, setNewChatOptions, iouType, isDistanceRequest, didScreenTransitionEnd]); + const chatOptions = OptionsListUtils.getFilteredOptions( + reports, + personalDetails, + betas, + searchTerm, + participants, + CONST.EXPENSIFY_EMAILS, + + // If we are using this component in the "Request money" flow then we pass the includeOwnedWorkspaceChats argument so that the current user + // sees the option to request money from their admin on their own Workspace Chat. + iouType === CONST.IOU.TYPE.REQUEST, + + // We don't want to include any P2P options like personal details or reports that are not workspace chats for certain features. + !isDistanceRequest, + false, + {}, + [], + false, + {}, + [], + // We don't want the user to be able to invite individuals when they are in the "Distance request" flow for now. + // This functionality is being built here: https://github.com/Expensify/App/issues/23291 + !isDistanceRequest, + true, + ); + setNewChatOptions({ + recentReports: chatOptions.recentReports, + personalDetails: chatOptions.personalDetails, + userToInvite: chatOptions.userToInvite, + }); + }, [betas, reports, participants, personalDetails, translate, searchTerm, setNewChatOptions, iouType, isDistanceRequest]); // When search term updates we will fetch any reports const setSearchTermAndSearchInServer = useCallback((text = '') => { From 1108784a7451d387dc9ab2d54482c1b792903925 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 14 Dec 2023 15:37:56 -0300 Subject: [PATCH 05/32] Revert "Integrate 'didScreenTransitionEnd' prop in MoneyRequestParticipantsPage" This reverts commit a5ed7d8ddc0cdcb9d1caa0da9e391bcb3b751c04. --- .../MoneyRequestParticipantsPage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js index a2073f9f5d44..7826643d4283 100644 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js @@ -133,7 +133,7 @@ function MoneyRequestParticipantsPage({iou, selectedTab, route, transaction}) { onEntryTransitionEnd={() => optionsSelectorRef.current && optionsSelectorRef.current.focus()} testID={MoneyRequestParticipantsPage.displayName} > - {({safeAreaPaddingBottomStyle, didScreenTransitionEnd}) => ( + {({safeAreaPaddingBottomStyle}) => ( )} From c69ecfd1f3a1296c2a9be1a575abb5c5c39a829c Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 14 Dec 2023 15:38:24 -0300 Subject: [PATCH 06/32] Revert "Add 'didScreenTransitionEnd' prop to MoneyRequestParticipantsSelector" This reverts commit 9eafd1fce280df3a53617063348a525f3f2ca6b5. --- .../MoneyRequestParticipantsSelector.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index 8c0fc71b0112..d8d644479270 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -66,9 +66,6 @@ const propTypes = { /** Whether we are searching for reports in the server */ isSearchingForReports: PropTypes.bool, - /** Whether the screen transition has ended */ - didScreenTransitionEnd: PropTypes.bool, - ...withLocalizePropTypes, }; @@ -81,7 +78,6 @@ const defaultProps = { betas: [], isDistanceRequest: false, isSearchingForReports: false, - didScreenTransitionEnd: false, }; function MoneyRequestParticipantsSelector({ @@ -98,7 +94,6 @@ function MoneyRequestParticipantsSelector({ iouType, isDistanceRequest, isSearchingForReports, - didScreenTransitionEnd, }) { const styles = useThemeStyles(); const [searchTerm, setSearchTerm] = useState(''); From dc1f87fdc77b65716dc625b65c61be8fccb718e5 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 14 Dec 2023 16:01:52 -0300 Subject: [PATCH 07/32] Integrate 'didScreenTransitionEnd' prop in IOURequestStepParticipants --- .../step/IOURequestStepParticipants.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.js b/src/pages/iou/request/step/IOURequestStepParticipants.js index 85d67ea34bae..fe5633c2f05c 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.js +++ b/src/pages/iou/request/step/IOURequestStepParticipants.js @@ -87,14 +87,17 @@ function IOURequestStepParticipants({ onEntryTransitionEnd={() => optionsSelectorRef.current && optionsSelectorRef.current.focus()} includeSafeAreaPaddingBottom > - (optionsSelectorRef.current = el)} - participants={participants} - onParticipantsAdded={addParticipant} - onFinish={goToNextStep} - iouType={iouType} - iouRequestType={iouRequestType} - /> + {({didScreenTransitionEnd}) => ( + (optionsSelectorRef.current = el)} + participants={participants} + onParticipantsAdded={addParticipant} + onFinish={goToNextStep} + iouType={iouType} + iouRequestType={iouRequestType} + didScreenTransitionEnd={didScreenTransitionEnd} + /> + )} ); } From 9cd0ab537b3c3f36438baf221352b2aabc5e7881 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 14 Dec 2023 16:03:38 -0300 Subject: [PATCH 08/32] Add 'didScreenTransitionEnd' prop to MoneyRequestParticipantsSelector --- .../MoneyTemporaryForRefactorRequestParticipantsSelector.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 8d7d5cfceb77..6194398e2bb9 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -63,6 +63,9 @@ const propTypes = { /** Whether we are searching for reports in the server */ isSearchingForReports: PropTypes.bool, + /** Whether the screen transition has ended */ + didScreenTransitionEnd: PropTypes.bool, + ...withLocalizePropTypes, }; @@ -74,6 +77,7 @@ const defaultProps = { reports: {}, betas: [], isSearchingForReports: false, + didScreenTransitionEnd: false, }; function MoneyTemporaryForRefactorRequestParticipantsSelector({ @@ -89,6 +93,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ iouType, iouRequestType, isSearchingForReports, + didScreenTransitionEnd, }) { const styles = useThemeStyles(); const [searchTerm, setSearchTerm] = useState(''); From a6a36f82518fdf220d41b754ee5723db64a61277 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 14 Dec 2023 16:05:15 -0300 Subject: [PATCH 09/32] Conditionally update 'chatOptions' on screen transition end --- ...yForRefactorRequestParticipantsSelector.js | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 6194398e2bb9..48fac9c1cef5 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -228,38 +228,40 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); useEffect(() => { - const chatOptions = OptionsListUtils.getFilteredOptions( - reports, - personalDetails, - betas, - searchTerm, - participants, - CONST.EXPENSIFY_EMAILS, - - // If we are using this component in the "Request money" flow then we pass the includeOwnedWorkspaceChats argument so that the current user - // sees the option to request money from their admin on their own Workspace Chat. - iouType === CONST.IOU.TYPE.REQUEST, - - // We don't want to include any P2P options like personal details or reports that are not workspace chats for certain features. - iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE, - false, - {}, - [], - false, - {}, - [], - - // We don't want the user to be able to invite individuals when they are in the "Distance request" flow for now. - // This functionality is being built here: https://github.com/Expensify/App/issues/23291 - iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE, - true, - ); - setNewChatOptions({ - recentReports: chatOptions.recentReports, - personalDetails: chatOptions.personalDetails, - userToInvite: chatOptions.userToInvite, - }); - }, [betas, reports, participants, personalDetails, translate, searchTerm, setNewChatOptions, iouType, iouRequestType]); + if (didScreenTransitionEnd) { + const chatOptions = OptionsListUtils.getFilteredOptions( + reports, + personalDetails, + betas, + searchTerm, + participants, + CONST.EXPENSIFY_EMAILS, + + // If we are using this component in the "Request money" flow then we pass the includeOwnedWorkspaceChats argument so that the current user + // sees the option to request money from their admin on their own Workspace Chat. + iouType === CONST.IOU.TYPE.REQUEST, + + // We don't want to include any P2P options like personal details or reports that are not workspace chats for certain features. + iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE, + false, + {}, + [], + false, + {}, + [], + + // We don't want the user to be able to invite individuals when they are in the "Distance request" flow for now. + // This functionality is being built here: https://github.com/Expensify/App/issues/23291 + iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE, + true, + ); + setNewChatOptions({ + recentReports: chatOptions.recentReports, + personalDetails: chatOptions.personalDetails, + userToInvite: chatOptions.userToInvite, + }); + } + }, [betas, reports, participants, personalDetails, translate, searchTerm, setNewChatOptions, iouType, iouRequestType, didScreenTransitionEnd]); // When search term updates we will fetch any reports const setSearchTermAndSearchInServer = useCallback((text = '') => { @@ -324,7 +326,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')} textInputAlert={isOffline ? `${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}` : ''} safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle} - shouldShowOptions={isOptionsDataReady} + shouldShowOptions={didScreenTransitionEnd && isOptionsDataReady} shouldShowReferralCTA referralContentType={iouType === 'send' ? CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SEND_MONEY : CONST.REFERRAL_PROGRAM.CONTENT_TYPES.MONEY_REQUEST} shouldPreventDefaultFocusOnSelectRow={!Browser.isMobile()} From cb616829c5d7ecc94b915e0adc46f19cdfb673e5 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 14 Dec 2023 23:57:01 -0300 Subject: [PATCH 10/32] Use early return --- ...yForRefactorRequestParticipantsSelector.js | 65 ++++++++++--------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 48fac9c1cef5..6341326b6eec 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -228,39 +228,40 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); useEffect(() => { - if (didScreenTransitionEnd) { - const chatOptions = OptionsListUtils.getFilteredOptions( - reports, - personalDetails, - betas, - searchTerm, - participants, - CONST.EXPENSIFY_EMAILS, - - // If we are using this component in the "Request money" flow then we pass the includeOwnedWorkspaceChats argument so that the current user - // sees the option to request money from their admin on their own Workspace Chat. - iouType === CONST.IOU.TYPE.REQUEST, - - // We don't want to include any P2P options like personal details or reports that are not workspace chats for certain features. - iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE, - false, - {}, - [], - false, - {}, - [], - - // We don't want the user to be able to invite individuals when they are in the "Distance request" flow for now. - // This functionality is being built here: https://github.com/Expensify/App/issues/23291 - iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE, - true, - ); - setNewChatOptions({ - recentReports: chatOptions.recentReports, - personalDetails: chatOptions.personalDetails, - userToInvite: chatOptions.userToInvite, - }); + if (!didScreenTransitionEnd) { + return; } + const chatOptions = OptionsListUtils.getFilteredOptions( + reports, + personalDetails, + betas, + searchTerm, + participants, + CONST.EXPENSIFY_EMAILS, + + // If we are using this component in the "Request money" flow then we pass the includeOwnedWorkspaceChats argument so that the current user + // sees the option to request money from their admin on their own Workspace Chat. + iouType === CONST.IOU.TYPE.REQUEST, + + // We don't want to include any P2P options like personal details or reports that are not workspace chats for certain features. + iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE, + false, + {}, + [], + false, + {}, + [], + + // We don't want the user to be able to invite individuals when they are in the "Distance request" flow for now. + // This functionality is being built here: https://github.com/Expensify/App/issues/23291 + iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE, + true, + ); + setNewChatOptions({ + recentReports: chatOptions.recentReports, + personalDetails: chatOptions.personalDetails, + userToInvite: chatOptions.userToInvite, + }); }, [betas, reports, participants, personalDetails, translate, searchTerm, setNewChatOptions, iouType, iouRequestType, didScreenTransitionEnd]); // When search term updates we will fetch any reports From 4f25fa70385ad275a55d86f726a1cfca433a4b40 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Fri, 22 Dec 2023 00:57:12 -0300 Subject: [PATCH 11/32] Enhance 'OptionsListSkeletonView' for quicker display using Dimensions. --- src/components/OptionsListSkeletonView.js | 130 ++++++++++------------ 1 file changed, 58 insertions(+), 72 deletions(-) diff --git a/src/components/OptionsListSkeletonView.js b/src/components/OptionsListSkeletonView.js index 2c46ac5d4d7a..f2e77f80f96e 100644 --- a/src/components/OptionsListSkeletonView.js +++ b/src/components/OptionsListSkeletonView.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import {View} from 'react-native'; +import {View, Dimensions} from 'react-native'; import {Circle, Rect} from 'react-native-svg'; import compose from '@libs/compose'; import CONST from '@src/CONST'; @@ -9,64 +9,55 @@ import withTheme, {withThemePropTypes} from './withTheme'; import withThemeStyles, {withThemeStylesPropTypes} from './withThemeStyles'; const propTypes = { - /** Whether to animate the skeleton view */ - shouldAnimate: PropTypes.bool, - ...withThemeStylesPropTypes, - ...withThemePropTypes, + /** Whether to animate the skeleton view */ + shouldAnimate: PropTypes.bool, + ...withThemeStylesPropTypes, + ...withThemePropTypes, }; const defaultTypes = { - shouldAnimate: true, + shouldAnimate: true, }; class OptionsListSkeletonView extends React.Component { - constructor(props) { - super(props); - this.state = { - skeletonViewItems: [], - }; - } - - /** - * Generate the skeleton view items. - * - * @param {Number} numItems - */ - generateSkeletonViewItems(numItems) { - if (this.state.skeletonViewItems.length === numItems) { - return; - } + constructor(props) { + super(props); + const screenHeight = Dimensions.get('window').height; + const numItems = Math.ceil(screenHeight / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT); + this.state = { + skeletonViewItems: this.generateSkeletonViewItems(numItems), + }; + } - if (this.state.skeletonViewItems.length > numItems) { - this.setState((prevState) => ({ - skeletonViewItems: prevState.skeletonViewItems.slice(0, numItems), - })); - return; - } - - const skeletonViewItems = []; - for (let i = this.state.skeletonViewItems.length; i < numItems; i++) { - const step = i % 3; - let lineWidth; - switch (step) { - case 0: - lineWidth = '100%'; - break; - case 1: - lineWidth = '50%'; - break; - default: - lineWidth = '25%'; - } - skeletonViewItems.push( - + /** + * Generate the skeleton view items. + * + * @param {Number} numItems + */ + generateSkeletonViewItems(numItems) { + const skeletonViewItems = []; + for (let i = 0; i < numItems; i++) { + const step = i % 3; + let lineWidth; + switch (step) { + case 0: + lineWidth = '100%'; + break; + case 1: + lineWidth = '50%'; + break; + default: + lineWidth = '25%'; + } + skeletonViewItems.push( + - , - ); - } - - this.setState((prevState) => ({ - skeletonViewItems: [...prevState.skeletonViewItems, ...skeletonViewItems], - })); + , + ); } - render() { - return ( - { - const numItems = Math.ceil(event.nativeEvent.layout.height / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT); - this.generateSkeletonViewItems(numItems); - }} - > - {this.state.skeletonViewItems} - - ); - } + return skeletonViewItems; + } + + render() { + return ( + + {this.state.skeletonViewItems} + + ); + } } OptionsListSkeletonView.propTypes = propTypes; OptionsListSkeletonView.defaultProps = defaultTypes; export default compose(withThemeStyles, withTheme)(OptionsListSkeletonView); + From fefd084e6af6f8d9d6b40cf85a3f7557f3ac447c Mon Sep 17 00:00:00 2001 From: brunovjk Date: Sat, 23 Dec 2023 10:37:12 -0300 Subject: [PATCH 12/32] Revert "Enhance 'OptionsListSkeletonView' for quicker display using Dimensions." This reverts commit 4f25fa70385ad275a55d86f726a1cfca433a4b40. --- src/components/OptionsListSkeletonView.js | 130 ++++++++++++---------- 1 file changed, 72 insertions(+), 58 deletions(-) diff --git a/src/components/OptionsListSkeletonView.js b/src/components/OptionsListSkeletonView.js index f2e77f80f96e..2c46ac5d4d7a 100644 --- a/src/components/OptionsListSkeletonView.js +++ b/src/components/OptionsListSkeletonView.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import {View, Dimensions} from 'react-native'; +import {View} from 'react-native'; import {Circle, Rect} from 'react-native-svg'; import compose from '@libs/compose'; import CONST from '@src/CONST'; @@ -9,55 +9,64 @@ import withTheme, {withThemePropTypes} from './withTheme'; import withThemeStyles, {withThemeStylesPropTypes} from './withThemeStyles'; const propTypes = { - /** Whether to animate the skeleton view */ - shouldAnimate: PropTypes.bool, - ...withThemeStylesPropTypes, - ...withThemePropTypes, + /** Whether to animate the skeleton view */ + shouldAnimate: PropTypes.bool, + ...withThemeStylesPropTypes, + ...withThemePropTypes, }; const defaultTypes = { - shouldAnimate: true, + shouldAnimate: true, }; class OptionsListSkeletonView extends React.Component { - constructor(props) { - super(props); - const screenHeight = Dimensions.get('window').height; - const numItems = Math.ceil(screenHeight / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT); - this.state = { - skeletonViewItems: this.generateSkeletonViewItems(numItems), - }; - } + constructor(props) { + super(props); + this.state = { + skeletonViewItems: [], + }; + } + + /** + * Generate the skeleton view items. + * + * @param {Number} numItems + */ + generateSkeletonViewItems(numItems) { + if (this.state.skeletonViewItems.length === numItems) { + return; + } - /** - * Generate the skeleton view items. - * - * @param {Number} numItems - */ - generateSkeletonViewItems(numItems) { - const skeletonViewItems = []; - for (let i = 0; i < numItems; i++) { - const step = i % 3; - let lineWidth; - switch (step) { - case 0: - lineWidth = '100%'; - break; - case 1: - lineWidth = '50%'; - break; - default: - lineWidth = '25%'; - } - skeletonViewItems.push( - + if (this.state.skeletonViewItems.length > numItems) { + this.setState((prevState) => ({ + skeletonViewItems: prevState.skeletonViewItems.slice(0, numItems), + })); + return; + } + + const skeletonViewItems = []; + for (let i = this.state.skeletonViewItems.length; i < numItems; i++) { + const step = i % 3; + let lineWidth; + switch (step) { + case 0: + lineWidth = '100%'; + break; + case 1: + lineWidth = '50%'; + break; + default: + lineWidth = '25%'; + } + skeletonViewItems.push( + - , - ); - } + , + ); + } - return skeletonViewItems; - } + this.setState((prevState) => ({ + skeletonViewItems: [...prevState.skeletonViewItems, ...skeletonViewItems], + })); + } - render() { - return ( - - {this.state.skeletonViewItems} - - ); - } + render() { + return ( + { + const numItems = Math.ceil(event.nativeEvent.layout.height / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT); + this.generateSkeletonViewItems(numItems); + }} + > + {this.state.skeletonViewItems} + + ); + } } OptionsListSkeletonView.propTypes = propTypes; OptionsListSkeletonView.defaultProps = defaultTypes; export default compose(withThemeStyles, withTheme)(OptionsListSkeletonView); - From 271ace6bab57ab3390c093c44e1a1a096d66e9c3 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Sat, 23 Dec 2023 11:23:26 -0300 Subject: [PATCH 13/32] Optimize OptionsListSkeletonView component --- src/CONST.ts | 1 + src/components/OptionsListSkeletonView.js | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index bc0a0c3216f0..544b4ce7e044 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -980,6 +980,7 @@ const CONST = { }, }, LHN_SKELETON_VIEW_ITEM_HEIGHT: 64, + SKELETON_VIEW_HEIGHT_THRESHOLD: 0.3, EXPENSIFY_PARTNER_NAME: 'expensify.com', EMAIL: { ACCOUNTING: 'accounting@expensify.com', diff --git a/src/components/OptionsListSkeletonView.js b/src/components/OptionsListSkeletonView.js index 2c46ac5d4d7a..ab617df28943 100644 --- a/src/components/OptionsListSkeletonView.js +++ b/src/components/OptionsListSkeletonView.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import {View} from 'react-native'; +import {View, Dimensions} from 'react-native'; import {Circle, Rect} from 'react-native-svg'; import compose from '@libs/compose'; import CONST from '@src/CONST'; @@ -22,8 +22,11 @@ const defaultTypes = { class OptionsListSkeletonView extends React.Component { constructor(props) { super(props); + const numItems = Math.ceil( + Dimensions.get('window').height * CONST.SKELETON_VIEW_HEIGHT_THRESHOLD / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT + ); this.state = { - skeletonViewItems: [], + skeletonViewItems: this.generateSkeletonViewItems(numItems), }; } From 99dd07a464741a96f06dd9f88373d5d361b0f715 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 27 Dec 2023 15:55:48 -0300 Subject: [PATCH 14/32] Revert "Optimize OptionsListSkeletonView component" This reverts commit 271ace6bab57ab3390c093c44e1a1a096d66e9c3. --- src/CONST.ts | 1 - src/components/OptionsListSkeletonView.js | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 1c0c1ef6112e..0fc684347243 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -986,7 +986,6 @@ const CONST = { }, }, LHN_SKELETON_VIEW_ITEM_HEIGHT: 64, - SKELETON_VIEW_HEIGHT_THRESHOLD: 0.3, EXPENSIFY_PARTNER_NAME: 'expensify.com', EMAIL: { ACCOUNTING: 'accounting@expensify.com', diff --git a/src/components/OptionsListSkeletonView.js b/src/components/OptionsListSkeletonView.js index ab617df28943..2c46ac5d4d7a 100644 --- a/src/components/OptionsListSkeletonView.js +++ b/src/components/OptionsListSkeletonView.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import {View, Dimensions} from 'react-native'; +import {View} from 'react-native'; import {Circle, Rect} from 'react-native-svg'; import compose from '@libs/compose'; import CONST from '@src/CONST'; @@ -22,11 +22,8 @@ const defaultTypes = { class OptionsListSkeletonView extends React.Component { constructor(props) { super(props); - const numItems = Math.ceil( - Dimensions.get('window').height * CONST.SKELETON_VIEW_HEIGHT_THRESHOLD / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT - ); this.state = { - skeletonViewItems: this.generateSkeletonViewItems(numItems), + skeletonViewItems: [], }; } From ed2ffb4a04097f4de857ffca6ffe9c4e863d2104 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 10 Jan 2024 15:40:14 -0300 Subject: [PATCH 15/32] Move 'isOptionsDataReady' to an 'useState' --- .../MoneyTemporaryForRefactorRequestParticipantsSelector.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 250f68b2b504..025250a4b70a 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -96,6 +96,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ didScreenTransitionEnd, }) { const styles = useThemeStyles(); + const [isOptionsDataReady, setIsOptionsDataReady] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const [newChatOptions, setNewChatOptions] = useState({ recentReports: [], @@ -225,7 +226,6 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ maxParticipantsReached, _.some(participants, (participant) => lodashGet(participant, 'searchText', '').toLowerCase().includes(searchTerm.trim().toLowerCase())), ); - const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); useEffect(() => { if (!didScreenTransitionEnd) { @@ -262,6 +262,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ personalDetails: chatOptions.personalDetails, userToInvite: chatOptions.userToInvite, }); + setIsOptionsDataReady(ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails)) }, [betas, reports, participants, personalDetails, translate, searchTerm, setNewChatOptions, iouType, iouRequestType, didScreenTransitionEnd]); // When search term updates we will fetch any reports @@ -326,7 +327,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')} textInputAlert={isOffline ? `${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}` : ''} safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle} - shouldShowOptions={didScreenTransitionEnd && isOptionsDataReady} + shouldShowOptions={isOptionsDataReady} shouldShowReferralCTA referralContentType={iouType === 'send' ? CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SEND_MONEY : CONST.REFERRAL_PROGRAM.CONTENT_TYPES.MONEY_REQUEST} shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()} From 37dc816e62294fadd10223f04b0124a61c0b87eb Mon Sep 17 00:00:00 2001 From: brunovjk Date: Sun, 14 Jan 2024 19:25:14 -0300 Subject: [PATCH 16/32] Pass 'didScreenTransitionEnd' from 'StepParticipants.StepScreenWrapper' to 'ParticipantsSelector' --- ...aryForRefactorRequestParticipantsSelector.js | 5 +++++ .../request/step/IOURequestStepParticipants.js | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index d9ae8b9fab1c..9246fb202534 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -56,6 +56,9 @@ const propTypes = { /** Whether we are searching for reports in the server */ isSearchingForReports: PropTypes.bool, + + /** Whether the parent screen transition has ended */ + didScreenTransitionEnd: PropTypes.bool, }; const defaultProps = { @@ -64,6 +67,7 @@ const defaultProps = { reports: {}, betas: [], isSearchingForReports: false, + didScreenTransitionEnd: false, }; function MoneyTemporaryForRefactorRequestParticipantsSelector({ @@ -76,6 +80,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ iouType, iouRequestType, isSearchingForReports, + didScreenTransitionEnd, }) { const {translate} = useLocalize(); const styles = useThemeStyles(); diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.js b/src/pages/iou/request/step/IOURequestStepParticipants.js index 9f06360ef3b1..aad85307b3e4 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.js +++ b/src/pages/iou/request/step/IOURequestStepParticipants.js @@ -87,13 +87,16 @@ function IOURequestStepParticipants({ testID={IOURequestStepParticipants.displayName} includeSafeAreaPaddingBottom > - + {({didScreenTransitionEnd}) => ( + + )} ); } From 8af2b8d78b27d08305879c39e097a776060f2d6e Mon Sep 17 00:00:00 2001 From: brunovjk Date: Sun, 14 Jan 2024 19:48:24 -0300 Subject: [PATCH 17/32] Handle OptionsListUtils logic after screen transition --- ...emporaryForRefactorRequestParticipantsSelector.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 9246fb202534..f6731f775b9b 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -99,6 +99,16 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ */ const [sections, newChatOptions] = useMemo(() => { const newSections = []; + if (!didScreenTransitionEnd) { + return [ + newSections, + { + recentReports: {}, + personalDetails: {}, + userToInvite: {}, + } + ]; + } let indexOffset = 0; const chatOptions = OptionsListUtils.getFilteredOptions( @@ -173,7 +183,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ } return [newSections, chatOptions]; - }, [reports, personalDetails, betas, searchTerm, participants, iouType, iouRequestType, maxParticipantsReached, translate]); + }, [didScreenTransitionEnd, reports, personalDetails, betas, searchTerm, participants, iouType, iouRequestType, maxParticipantsReached, translate]); /** * Adds a single participant to the request From a2611cc2e153b10d571bb4362821fc0b92467456 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Sun, 14 Jan 2024 21:01:27 -0300 Subject: [PATCH 18/32] Implement 'isLoadingNewOptions' to 'BaseSelectionList' --- src/components/SelectionList/BaseSelectionList.js | 2 ++ src/components/SelectionList/selectionListPropTypes.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/components/SelectionList/BaseSelectionList.js b/src/components/SelectionList/BaseSelectionList.js index 960618808fd9..221436e1020e 100644 --- a/src/components/SelectionList/BaseSelectionList.js +++ b/src/components/SelectionList/BaseSelectionList.js @@ -45,6 +45,7 @@ function BaseSelectionList({ inputMode = CONST.INPUT_MODE.TEXT, onChangeText, initiallyFocusedOptionKey = '', + isLoadingNewOptions = false, onScroll, onScrollBeginDrag, headerMessage = '', @@ -428,6 +429,7 @@ function BaseSelectionList({ spellCheck={false} onSubmitEditing={selectFocusedOption} blurOnSubmit={Boolean(flattenedSections.allOptions.length)} + isLoading={isLoadingNewOptions} /> )} diff --git a/src/components/SelectionList/selectionListPropTypes.js b/src/components/SelectionList/selectionListPropTypes.js index f5178112a4c3..b0c5dd37867e 100644 --- a/src/components/SelectionList/selectionListPropTypes.js +++ b/src/components/SelectionList/selectionListPropTypes.js @@ -151,6 +151,9 @@ const propTypes = { /** Item `keyForList` to focus initially */ initiallyFocusedOptionKey: PropTypes.string, + /** Whether we are loading new options */ + isLoadingNewOptions: PropTypes.bool, + /** Callback to fire when the list is scrolled */ onScroll: PropTypes.func, From 301df39b60fc9f49b608b6932727f1eebd743c28 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Sun, 14 Jan 2024 21:07:20 -0300 Subject: [PATCH 19/32] Adjust 'SelectionList' props --- ...oneyTemporaryForRefactorRequestParticipantsSelector.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index f6731f775b9b..9fb91e34fb33 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -16,6 +16,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as Report from '@libs/actions/Report'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import MoneyRequestReferralProgramCTA from '@pages/iou/MoneyRequestReferralProgramCTA'; import reportPropTypes from '@pages/reportPropTypes'; import CONST from '@src/CONST'; @@ -337,11 +338,13 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ [addParticipantToSelection, isAllowedToSplit, styles, translate], ); + const isOptionsDataReady = useMemo(() => ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails), [personalDetails]); + return ( 0 ? safeAreaPaddingBottomStyle : {}]}> ); From 6d15a87cc10a4f59e1b474272e563aa5968ba8c8 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Sun, 14 Jan 2024 21:09:36 -0300 Subject: [PATCH 20/32] Fill MoneyRequestReferralProgramCTA icon --- src/pages/iou/MoneyRequestReferralProgramCTA.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/iou/MoneyRequestReferralProgramCTA.tsx b/src/pages/iou/MoneyRequestReferralProgramCTA.tsx index 31394e1bd0e1..30db04dffdac 100644 --- a/src/pages/iou/MoneyRequestReferralProgramCTA.tsx +++ b/src/pages/iou/MoneyRequestReferralProgramCTA.tsx @@ -41,6 +41,7 @@ function MoneyRequestReferralProgramCTA({referralContentType}: MoneyRequestRefer src={Info} height={20} width={20} + fill={theme.icon} /> ); From 078b4ce44115245ac26aa2157219dd520714a877 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Mon, 15 Jan 2024 14:41:47 -0300 Subject: [PATCH 21/32] Revert "Fill MoneyRequestReferralProgramCTA icon" This reverts commit 6d15a87cc10a4f59e1b474272e563aa5968ba8c8. --- src/pages/iou/MoneyRequestReferralProgramCTA.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/iou/MoneyRequestReferralProgramCTA.tsx b/src/pages/iou/MoneyRequestReferralProgramCTA.tsx index 30db04dffdac..31394e1bd0e1 100644 --- a/src/pages/iou/MoneyRequestReferralProgramCTA.tsx +++ b/src/pages/iou/MoneyRequestReferralProgramCTA.tsx @@ -41,7 +41,6 @@ function MoneyRequestReferralProgramCTA({referralContentType}: MoneyRequestRefer src={Info} height={20} width={20} - fill={theme.icon} /> ); From 87f5cf5db7ac4ccc8ce6cd70a35563512bb2fb28 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Mon, 15 Jan 2024 15:03:35 -0300 Subject: [PATCH 22/32] Use debounce text input value --- ...ryForRefactorRequestParticipantsSelector.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 9fb91e34fb33..02e0eb730c43 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useMemo, useState} from 'react'; +import React, {useCallback, useEffect,useMemo} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -10,6 +10,7 @@ import {usePersonalDetails} from '@components/OnyxProvider'; import {PressableWithFeedback} from '@components/Pressable'; import SelectCircle from '@components/SelectCircle'; import SelectionList from '@components/SelectionList'; +import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -85,7 +86,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ }) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [searchTerm, setSearchTerm] = useState(''); + const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); const {isOffline} = useNetwork(); const personalDetails = usePersonalDetails(); @@ -254,13 +255,12 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ [maxParticipantsReached, newChatOptions.personalDetails.length, newChatOptions.recentReports.length, newChatOptions.userToInvite, participants, searchTerm], ); - // When search term updates we will fetch any reports - const setSearchTermAndSearchInServer = useCallback((text = '') => { - if (text.length) { - Report.searchInServer(text); + useEffect(() => { + if (!debouncedSearchTerm.length) { + return; } - setSearchTerm(text); - }, []); + Report.searchInServer(debouncedSearchTerm); + }, [debouncedSearchTerm]); // Right now you can't split a request with a workspace and other additional participants // This is getting properly fixed in https://github.com/Expensify/App/issues/27508, but as a stop-gap to prevent @@ -348,7 +348,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ textInputValue={searchTerm} textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')} textInputHint={offlineMessage} - onChangeText={setSearchTermAndSearchInServer} + onChangeText={setSearchTerm} shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()} onSelectRow={addSingleParticipant} footerContent={footerContent} From 97f1c9aac058e9f74c10777bf61da77c1d7c3eb2 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Mon, 15 Jan 2024 16:03:55 -0300 Subject: [PATCH 23/32] applying all the same changes in 'pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js' --- .../MoneyRequestParticipantsPage.js | 3 +- .../MoneyRequestParticipantsSelector.js | 43 +++++++++++++------ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js index 216154be9cd4..76b7b80c6306 100644 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js @@ -130,7 +130,7 @@ function MoneyRequestParticipantsPage({iou, selectedTab, route, transaction}) { shouldEnableMaxHeight={DeviceCapabilities.canUseTouchScreen()} testID={MoneyRequestParticipantsPage.displayName} > - {({safeAreaPaddingBottomStyle}) => ( + {({didScreenTransitionEnd, safeAreaPaddingBottomStyle}) => ( )} diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index 9edede770233..708398d7ea00 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useMemo, useState} from 'react'; +import React, {useCallback, useEffect,useMemo} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -10,16 +10,19 @@ import {usePersonalDetails} from '@components/OnyxProvider'; import {PressableWithFeedback} from '@components/Pressable'; import SelectCircle from '@components/SelectCircle'; import SelectionList from '@components/SelectionList'; +import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Report from '@libs/actions/Report'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import MoneyRequestReferralProgramCTA from '@pages/iou/MoneyRequestReferralProgramCTA'; import reportPropTypes from '@pages/reportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; const propTypes = { /** Beta features list */ @@ -59,6 +62,9 @@ const propTypes = { /** Whether we are searching for reports in the server */ isSearchingForReports: PropTypes.bool, + + /** Whether the parent screen transition has ended */ + didScreenTransitionEnd: PropTypes.bool, }; const defaultProps = { @@ -68,6 +74,7 @@ const defaultProps = { betas: [], isDistanceRequest: false, isSearchingForReports: false, + didScreenTransitionEnd: false, }; function MoneyRequestParticipantsSelector({ @@ -81,16 +88,24 @@ function MoneyRequestParticipantsSelector({ iouType, isDistanceRequest, isSearchingForReports, + didScreenTransitionEnd, }) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [searchTerm, setSearchTerm] = useState(''); + const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); const {isOffline} = useNetwork(); const personalDetails = usePersonalDetails(); const offlineMessage = isOffline ? `${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}` : ''; const newChatOptions = useMemo(() => { + if (!didScreenTransitionEnd) { + return { + recentReports: {}, + personalDetails: {}, + userToInvite: {}, + }; + } const chatOptions = OptionsListUtils.getFilteredOptions( reports, personalDetails, @@ -121,7 +136,7 @@ function MoneyRequestParticipantsSelector({ personalDetails: chatOptions.personalDetails, userToInvite: chatOptions.userToInvite, }; - }, [betas, reports, participants, personalDetails, searchTerm, iouType, isDistanceRequest]); + }, [betas, didScreenTransitionEnd, reports, participants, personalDetails, searchTerm, iouType, isDistanceRequest]); const maxParticipantsReached = participants.length === CONST.REPORT.MAXIMUM_PARTICIPANTS; @@ -166,7 +181,7 @@ function MoneyRequestParticipantsSelector({ }); indexOffset += newChatOptions.personalDetails.length; - if (newChatOptions.userToInvite && !OptionsListUtils.isCurrentUser(newChatOptions.userToInvite)) { + if (isNotEmptyObject(newChatOptions.userToInvite) && !OptionsListUtils.isCurrentUser(newChatOptions.userToInvite)) { newSections.push({ title: undefined, data: _.map([newChatOptions.userToInvite], (participant) => { @@ -258,11 +273,12 @@ function MoneyRequestParticipantsSelector({ [maxParticipantsReached, newChatOptions.personalDetails.length, newChatOptions.recentReports.length, newChatOptions.userToInvite, participants, searchTerm], ); - // When search term updates we will fetch any reports - const setSearchTermAndSearchInServer = useCallback((text = '') => { - Report.searchInServer(text); - setSearchTerm(text); - }, []); + useEffect(() => { + if (!debouncedSearchTerm.length) { + return; + } + Report.searchInServer(debouncedSearchTerm); + }, [debouncedSearchTerm]); // Right now you can't split a request with a workspace and other additional participants // This is getting properly fixed in https://github.com/Expensify/App/issues/27508, but as a stop-gap to prevent @@ -341,21 +357,24 @@ function MoneyRequestParticipantsSelector({ [addParticipantToSelection, isAllowedToSplit, styles, translate], ); + const isOptionsDataReady = useMemo(() => ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails), [personalDetails]); + return ( 0 ? safeAreaPaddingBottomStyle : {}]}> ); From 8d08f71beb23eb08f6d65770fe0a83c6a28d2aa6 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Mon, 15 Jan 2024 18:20:32 -0300 Subject: [PATCH 24/32] Resolve conflict over 'ReferralProgramCTA' --- ...yForRefactorRequestParticipantsSelector.js | 43 +++++++++++++----- .../MoneyRequestParticipantsSelector.js | 45 +++++++++++++------ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index ea9788ccddb5..72f9831c2c12 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useMemo, useState} from 'react'; +import React, {useCallback, useEffect,useMemo} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -11,12 +11,14 @@ import {PressableWithFeedback} from '@components/Pressable'; import ReferralProgramCTA from '@components/ReferralProgramCTA'; import SelectCircle from '@components/SelectCircle'; import SelectionList from '@components/SelectionList'; +import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Report from '@libs/actions/Report'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -56,6 +58,9 @@ const propTypes = { /** Whether we are searching for reports in the server */ isSearchingForReports: PropTypes.bool, + + /** Whether the parent screen transition has ended */ + didScreenTransitionEnd: PropTypes.bool, }; const defaultProps = { @@ -64,6 +69,7 @@ const defaultProps = { reports: {}, betas: [], isSearchingForReports: false, + didScreenTransitionEnd: false, }; function MoneyTemporaryForRefactorRequestParticipantsSelector({ @@ -76,10 +82,11 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ iouType, iouRequestType, isSearchingForReports, + didScreenTransitionEnd, }) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [searchTerm, setSearchTerm] = useState(''); + const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); const {isOffline} = useNetwork(); const personalDetails = usePersonalDetails(); @@ -94,6 +101,16 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ */ const [sections, newChatOptions] = useMemo(() => { const newSections = []; + if (!didScreenTransitionEnd) { + return [ + newSections, + { + recentReports: {}, + personalDetails: {}, + userToInvite: {}, + } + ]; + } let indexOffset = 0; const chatOptions = OptionsListUtils.getFilteredOptions( @@ -168,7 +185,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ } return [newSections, chatOptions]; - }, [reports, personalDetails, betas, searchTerm, participants, iouType, iouRequestType, maxParticipantsReached, translate]); + }, [didScreenTransitionEnd, reports, personalDetails, betas, searchTerm, participants, iouType, iouRequestType, maxParticipantsReached, translate]); /** * Adds a single participant to the request @@ -238,13 +255,12 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ [maxParticipantsReached, newChatOptions.personalDetails.length, newChatOptions.recentReports.length, newChatOptions.userToInvite, participants, searchTerm], ); - // When search term updates we will fetch any reports - const setSearchTermAndSearchInServer = useCallback((text = '') => { - if (text.length) { - Report.searchInServer(text); + useEffect(() => { + if (!debouncedSearchTerm.length) { + return; } - setSearchTerm(text); - }, []); + Report.searchInServer(debouncedSearchTerm); + }, [debouncedSearchTerm]); // Right now you can't split a request with a workspace and other additional participants // This is getting properly fixed in https://github.com/Expensify/App/issues/27508, but as a stop-gap to prevent @@ -322,21 +338,24 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ [addParticipantToSelection, isAllowedToSplit, styles, translate], ); + const isOptionsDataReady = useMemo(() => ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails), [personalDetails]); + return ( 0 ? safeAreaPaddingBottomStyle : {}]}> ); diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index 2162e81d7bb8..76e97b140506 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useMemo, useState} from 'react'; +import React, {useCallback, useEffect,useMemo} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -11,15 +11,18 @@ import {PressableWithFeedback} from '@components/Pressable'; import ReferralProgramCTA from '@components/ReferralProgramCTA'; import SelectCircle from '@components/SelectCircle'; import SelectionList from '@components/SelectionList'; +import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Report from '@libs/actions/Report'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; const propTypes = { /** Beta features list */ @@ -59,6 +62,9 @@ const propTypes = { /** Whether we are searching for reports in the server */ isSearchingForReports: PropTypes.bool, + + /** Whether the parent screen transition has ended */ + didScreenTransitionEnd: PropTypes.bool, }; const defaultProps = { @@ -68,6 +74,7 @@ const defaultProps = { betas: [], isDistanceRequest: false, isSearchingForReports: false, + didScreenTransitionEnd: false, }; function MoneyRequestParticipantsSelector({ @@ -81,16 +88,24 @@ function MoneyRequestParticipantsSelector({ iouType, isDistanceRequest, isSearchingForReports, + didScreenTransitionEnd, }) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [searchTerm, setSearchTerm] = useState(''); + const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); const {isOffline} = useNetwork(); const personalDetails = usePersonalDetails(); const offlineMessage = isOffline ? `${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}` : ''; const newChatOptions = useMemo(() => { + if (!didScreenTransitionEnd) { + return { + recentReports: {}, + personalDetails: {}, + userToInvite: {}, + }; + } const chatOptions = OptionsListUtils.getFilteredOptions( reports, personalDetails, @@ -121,7 +136,7 @@ function MoneyRequestParticipantsSelector({ personalDetails: chatOptions.personalDetails, userToInvite: chatOptions.userToInvite, }; - }, [betas, reports, participants, personalDetails, searchTerm, iouType, isDistanceRequest]); + }, [betas, didScreenTransitionEnd, reports, participants, personalDetails, searchTerm, iouType, isDistanceRequest]); const maxParticipantsReached = participants.length === CONST.REPORT.MAXIMUM_PARTICIPANTS; @@ -166,7 +181,7 @@ function MoneyRequestParticipantsSelector({ }); indexOffset += newChatOptions.personalDetails.length; - if (newChatOptions.userToInvite && !OptionsListUtils.isCurrentUser(newChatOptions.userToInvite)) { + if (isNotEmptyObject(newChatOptions.userToInvite) && !OptionsListUtils.isCurrentUser(newChatOptions.userToInvite)) { newSections.push({ title: undefined, data: _.map([newChatOptions.userToInvite], (participant) => { @@ -258,11 +273,12 @@ function MoneyRequestParticipantsSelector({ [maxParticipantsReached, newChatOptions.personalDetails.length, newChatOptions.recentReports.length, newChatOptions.userToInvite, participants, searchTerm], ); - // When search term updates we will fetch any reports - const setSearchTermAndSearchInServer = useCallback((text = '') => { - Report.searchInServer(text); - setSearchTerm(text); - }, []); + useEffect(() => { + if (!debouncedSearchTerm.length) { + return; + } + Report.searchInServer(debouncedSearchTerm); + }, [debouncedSearchTerm]); // Right now you can't split a request with a workspace and other additional participants // This is getting properly fixed in https://github.com/Expensify/App/issues/27508, but as a stop-gap to prevent @@ -341,21 +357,24 @@ function MoneyRequestParticipantsSelector({ [addParticipantToSelection, isAllowedToSplit, styles, translate], ); + const isOptionsDataReady = useMemo(() => ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails), [personalDetails]); + return ( 0 ? safeAreaPaddingBottomStyle : {}]}> ); @@ -376,4 +395,4 @@ export default withOnyx({ key: ONYXKEYS.IS_SEARCHING_FOR_REPORTS, initWithStoredValues: false, }, -})(MoneyRequestParticipantsSelector); \ No newline at end of file +})(MoneyRequestParticipantsSelector); From 8859d213427b1dae8f28d09ad15dd89cd29db80d Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 17 Jan 2024 10:10:18 -0300 Subject: [PATCH 25/32] Changes requested by reviewer --- src/components/SelectionList/BaseSelectionList.js | 2 +- ...neyTemporaryForRefactorRequestParticipantsSelector.js | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/components/SelectionList/BaseSelectionList.js b/src/components/SelectionList/BaseSelectionList.js index 221436e1020e..2d209ef573c3 100644 --- a/src/components/SelectionList/BaseSelectionList.js +++ b/src/components/SelectionList/BaseSelectionList.js @@ -433,7 +433,7 @@ function BaseSelectionList({ /> )} - {Boolean(headerMessage) && ( + {!isLoadingNewOptions && Boolean(headerMessage) && ( {headerMessage} diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 01ef3d9bb697..2554b5933c6a 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -102,14 +102,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ const [sections, newChatOptions] = useMemo(() => { const newSections = []; if (!didScreenTransitionEnd) { - return [ - newSections, - { - recentReports: {}, - personalDetails: {}, - userToInvite: {}, - } - ]; + return [newSections, {}]; } let indexOffset = 0; From 1a94efad3cdfecf94266dea234835cabc6e4b7ae Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 18 Jan 2024 12:07:53 -0300 Subject: [PATCH 26/32] Resolve conflict over Migrate 'SelectionList' --- src/components/SelectionList/BaseSelectionList.js | 4 +++- src/components/SelectionList/selectionListPropTypes.js | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/SelectionList/BaseSelectionList.js b/src/components/SelectionList/BaseSelectionList.js index ea9ee3a0012c..0ad7d3621660 100644 --- a/src/components/SelectionList/BaseSelectionList.js +++ b/src/components/SelectionList/BaseSelectionList.js @@ -45,6 +45,7 @@ function BaseSelectionList({ inputMode = CONST.INPUT_MODE.TEXT, onChangeText, initiallyFocusedOptionKey = '', + isLoadingNewOptions = false, onScroll, onScrollBeginDrag, headerMessage = '', @@ -428,10 +429,11 @@ function BaseSelectionList({ spellCheck={false} onSubmitEditing={selectFocusedOption} blurOnSubmit={Boolean(flattenedSections.allOptions.length)} + isLoading={isLoadingNewOptions} /> )} - {Boolean(headerMessage) && ( + {!isLoadingNewOptions && !!headerMessage && ( {headerMessage} diff --git a/src/components/SelectionList/selectionListPropTypes.js b/src/components/SelectionList/selectionListPropTypes.js index 7914ecc8572c..254f3e22b684 100644 --- a/src/components/SelectionList/selectionListPropTypes.js +++ b/src/components/SelectionList/selectionListPropTypes.js @@ -151,6 +151,9 @@ const propTypes = { /** Item `keyForList` to focus initially */ initiallyFocusedOptionKey: PropTypes.string, + /** Whether we are loading new options */ + isLoadingNewOptions: PropTypes.bool, + /** Callback to fire when the list is scrolled */ onScroll: PropTypes.func, From 0d6b7a5aca021eea4be0e8aa1385db6f67d1ec74 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 18 Jan 2024 12:12:48 -0300 Subject: [PATCH 27/32] Resolve conflict over Migrate 'SelectionList' --- src/components/SelectionList/BaseSelectionList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SelectionList/BaseSelectionList.js b/src/components/SelectionList/BaseSelectionList.js index 0ad7d3621660..36d56813e917 100644 --- a/src/components/SelectionList/BaseSelectionList.js +++ b/src/components/SelectionList/BaseSelectionList.js @@ -433,7 +433,7 @@ function BaseSelectionList({ /> )} - {!isLoadingNewOptions && !!headerMessage && ( + {!isLoadingNewOptions && Boolean(headerMessage) && ( {headerMessage} From 8c0eee24ebe61eaffc271b680d944b2d35b401ac Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 18 Jan 2024 13:28:39 -0300 Subject: [PATCH 28/32] Run prettier --- src/components/SelectionList/BaseListItem.js | 2 +- .../SelectionList/BaseSelectionList.js | 2 +- src/components/SelectionList/RadioListItem.js | 2 +- src/components/SelectionList/UserListItem.js | 2 +- src/components/SelectionList/index.android.js | 2 +- src/components/SelectionList/index.ios.js | 2 +- src/components/SelectionList/index.js | 2 +- .../SelectionList/selectionListPropTypes.js | 2 +- ...yForRefactorRequestParticipantsSelector.js | 4 +- .../step/IOURequestStepParticipants.js | 2 +- .../MoneyRequestParticipantsPage.js | 3 +- .../MoneyRequestParticipantsSelector.js | 43 ++++++------------- 12 files changed, 24 insertions(+), 44 deletions(-) diff --git a/src/components/SelectionList/BaseListItem.js b/src/components/SelectionList/BaseListItem.js index ad19e7dcad76..6a067ea0fe3d 100644 --- a/src/components/SelectionList/BaseListItem.js +++ b/src/components/SelectionList/BaseListItem.js @@ -142,4 +142,4 @@ function BaseListItem({ BaseListItem.displayName = 'BaseListItem'; BaseListItem.propTypes = baseListItemPropTypes; -export default BaseListItem; \ No newline at end of file +export default BaseListItem; diff --git a/src/components/SelectionList/BaseSelectionList.js b/src/components/SelectionList/BaseSelectionList.js index 36d56813e917..2d209ef573c3 100644 --- a/src/components/SelectionList/BaseSelectionList.js +++ b/src/components/SelectionList/BaseSelectionList.js @@ -513,4 +513,4 @@ function BaseSelectionList({ BaseSelectionList.displayName = 'BaseSelectionList'; BaseSelectionList.propTypes = propTypes; -export default withKeyboardState(BaseSelectionList); \ No newline at end of file +export default withKeyboardState(BaseSelectionList); diff --git a/src/components/SelectionList/RadioListItem.js b/src/components/SelectionList/RadioListItem.js index 5b465f9efe58..2de0c96932ea 100644 --- a/src/components/SelectionList/RadioListItem.js +++ b/src/components/SelectionList/RadioListItem.js @@ -41,4 +41,4 @@ function RadioListItem({item, showTooltip, textStyles, alternateTextStyles}) { RadioListItem.displayName = 'RadioListItem'; RadioListItem.propTypes = radioListItemPropTypes; -export default RadioListItem; \ No newline at end of file +export default RadioListItem; diff --git a/src/components/SelectionList/UserListItem.js b/src/components/SelectionList/UserListItem.js index 1513f2601b9f..a842f19858f2 100644 --- a/src/components/SelectionList/UserListItem.js +++ b/src/components/SelectionList/UserListItem.js @@ -54,4 +54,4 @@ function UserListItem({item, textStyles, alternateTextStyles, showTooltip, style UserListItem.displayName = 'UserListItem'; UserListItem.propTypes = userListItemPropTypes; -export default UserListItem; \ No newline at end of file +export default UserListItem; diff --git a/src/components/SelectionList/index.android.js b/src/components/SelectionList/index.android.js index 5c98df733c02..53d5b6bbce06 100644 --- a/src/components/SelectionList/index.android.js +++ b/src/components/SelectionList/index.android.js @@ -14,4 +14,4 @@ const SelectionList = forwardRef((props, ref) => ( SelectionList.displayName = 'SelectionList'; -export default SelectionList; \ No newline at end of file +export default SelectionList; diff --git a/src/components/SelectionList/index.ios.js b/src/components/SelectionList/index.ios.js index b03aae215f9d..7f2a282aeb89 100644 --- a/src/components/SelectionList/index.ios.js +++ b/src/components/SelectionList/index.ios.js @@ -13,4 +13,4 @@ const SelectionList = forwardRef((props, ref) => ( SelectionList.displayName = 'SelectionList'; -export default SelectionList; \ No newline at end of file +export default SelectionList; diff --git a/src/components/SelectionList/index.js b/src/components/SelectionList/index.js index f0fe27acbe2d..24ea60d29be5 100644 --- a/src/components/SelectionList/index.js +++ b/src/components/SelectionList/index.js @@ -43,4 +43,4 @@ const SelectionList = forwardRef((props, ref) => { SelectionList.displayName = 'SelectionList'; -export default SelectionList; \ No newline at end of file +export default SelectionList; diff --git a/src/components/SelectionList/selectionListPropTypes.js b/src/components/SelectionList/selectionListPropTypes.js index 254f3e22b684..b0c5dd37867e 100644 --- a/src/components/SelectionList/selectionListPropTypes.js +++ b/src/components/SelectionList/selectionListPropTypes.js @@ -203,4 +203,4 @@ const propTypes = { rightHandSideComponent: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), }; -export {propTypes, baseListItemPropTypes, radioListItemPropTypes, userListItemPropTypes}; \ No newline at end of file +export {propTypes, baseListItemPropTypes, radioListItemPropTypes, userListItemPropTypes}; diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 2554b5933c6a..6da8524934d3 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useEffect,useMemo} from 'react'; +import React, {useCallback, useEffect, useMemo} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -369,4 +369,4 @@ export default withOnyx({ key: ONYXKEYS.IS_SEARCHING_FOR_REPORTS, initWithStoredValues: false, }, -})(MoneyTemporaryForRefactorRequestParticipantsSelector); \ No newline at end of file +})(MoneyTemporaryForRefactorRequestParticipantsSelector); diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.js b/src/pages/iou/request/step/IOURequestStepParticipants.js index aad85307b3e4..4846c3c4c8a4 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.js +++ b/src/pages/iou/request/step/IOURequestStepParticipants.js @@ -105,4 +105,4 @@ IOURequestStepParticipants.displayName = 'IOURequestStepParticipants'; IOURequestStepParticipants.propTypes = propTypes; IOURequestStepParticipants.defaultProps = defaultProps; -export default compose(withWritableReportOrNotFound, withFullTransactionOrNotFound)(IOURequestStepParticipants); \ No newline at end of file +export default compose(withWritableReportOrNotFound, withFullTransactionOrNotFound)(IOURequestStepParticipants); diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js index 76b7b80c6306..216154be9cd4 100644 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js @@ -130,7 +130,7 @@ function MoneyRequestParticipantsPage({iou, selectedTab, route, transaction}) { shouldEnableMaxHeight={DeviceCapabilities.canUseTouchScreen()} testID={MoneyRequestParticipantsPage.displayName} > - {({didScreenTransitionEnd, safeAreaPaddingBottomStyle}) => ( + {({safeAreaPaddingBottomStyle}) => ( )} diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index 76e97b140506..9567b17ecdf5 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useEffect,useMemo} from 'react'; +import React, {useCallback, useMemo, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -11,18 +11,15 @@ import {PressableWithFeedback} from '@components/Pressable'; import ReferralProgramCTA from '@components/ReferralProgramCTA'; import SelectCircle from '@components/SelectCircle'; import SelectionList from '@components/SelectionList'; -import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Report from '@libs/actions/Report'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; const propTypes = { /** Beta features list */ @@ -62,9 +59,6 @@ const propTypes = { /** Whether we are searching for reports in the server */ isSearchingForReports: PropTypes.bool, - - /** Whether the parent screen transition has ended */ - didScreenTransitionEnd: PropTypes.bool, }; const defaultProps = { @@ -74,7 +68,6 @@ const defaultProps = { betas: [], isDistanceRequest: false, isSearchingForReports: false, - didScreenTransitionEnd: false, }; function MoneyRequestParticipantsSelector({ @@ -88,24 +81,16 @@ function MoneyRequestParticipantsSelector({ iouType, isDistanceRequest, isSearchingForReports, - didScreenTransitionEnd, }) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); + const [searchTerm, setSearchTerm] = useState(''); const {isOffline} = useNetwork(); const personalDetails = usePersonalDetails(); const offlineMessage = isOffline ? `${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}` : ''; const newChatOptions = useMemo(() => { - if (!didScreenTransitionEnd) { - return { - recentReports: {}, - personalDetails: {}, - userToInvite: {}, - }; - } const chatOptions = OptionsListUtils.getFilteredOptions( reports, personalDetails, @@ -136,7 +121,7 @@ function MoneyRequestParticipantsSelector({ personalDetails: chatOptions.personalDetails, userToInvite: chatOptions.userToInvite, }; - }, [betas, didScreenTransitionEnd, reports, participants, personalDetails, searchTerm, iouType, isDistanceRequest]); + }, [betas, reports, participants, personalDetails, searchTerm, iouType, isDistanceRequest]); const maxParticipantsReached = participants.length === CONST.REPORT.MAXIMUM_PARTICIPANTS; @@ -181,7 +166,7 @@ function MoneyRequestParticipantsSelector({ }); indexOffset += newChatOptions.personalDetails.length; - if (isNotEmptyObject(newChatOptions.userToInvite) && !OptionsListUtils.isCurrentUser(newChatOptions.userToInvite)) { + if (newChatOptions.userToInvite && !OptionsListUtils.isCurrentUser(newChatOptions.userToInvite)) { newSections.push({ title: undefined, data: _.map([newChatOptions.userToInvite], (participant) => { @@ -273,12 +258,11 @@ function MoneyRequestParticipantsSelector({ [maxParticipantsReached, newChatOptions.personalDetails.length, newChatOptions.recentReports.length, newChatOptions.userToInvite, participants, searchTerm], ); - useEffect(() => { - if (!debouncedSearchTerm.length) { - return; - } - Report.searchInServer(debouncedSearchTerm); - }, [debouncedSearchTerm]); + // When search term updates we will fetch any reports + const setSearchTermAndSearchInServer = useCallback((text = '') => { + Report.searchInServer(text); + setSearchTerm(text); + }, []); // Right now you can't split a request with a workspace and other additional participants // This is getting properly fixed in https://github.com/Expensify/App/issues/27508, but as a stop-gap to prevent @@ -357,24 +341,21 @@ function MoneyRequestParticipantsSelector({ [addParticipantToSelection, isAllowedToSplit, styles, translate], ); - const isOptionsDataReady = useMemo(() => ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails), [personalDetails]); - return ( 0 ? safeAreaPaddingBottomStyle : {}]}> ); From 55408387417e016eb45bb908df9ade8b373c3a68 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Fri, 19 Jan 2024 09:51:36 -0300 Subject: [PATCH 29/32] Isolate reuse 'didScreenTransitionEnd' to address the screen transition skeleton issue --- .../SelectionList/BaseSelectionList.js | 4 +--- .../SelectionList/selectionListPropTypes.js | 3 --- ...ryForRefactorRequestParticipantsSelector.js | 18 +++++++++--------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/components/SelectionList/BaseSelectionList.js b/src/components/SelectionList/BaseSelectionList.js index 2d209ef573c3..960618808fd9 100644 --- a/src/components/SelectionList/BaseSelectionList.js +++ b/src/components/SelectionList/BaseSelectionList.js @@ -45,7 +45,6 @@ function BaseSelectionList({ inputMode = CONST.INPUT_MODE.TEXT, onChangeText, initiallyFocusedOptionKey = '', - isLoadingNewOptions = false, onScroll, onScrollBeginDrag, headerMessage = '', @@ -429,11 +428,10 @@ function BaseSelectionList({ spellCheck={false} onSubmitEditing={selectFocusedOption} blurOnSubmit={Boolean(flattenedSections.allOptions.length)} - isLoading={isLoadingNewOptions} /> )} - {!isLoadingNewOptions && Boolean(headerMessage) && ( + {Boolean(headerMessage) && ( {headerMessage} diff --git a/src/components/SelectionList/selectionListPropTypes.js b/src/components/SelectionList/selectionListPropTypes.js index b0c5dd37867e..f5178112a4c3 100644 --- a/src/components/SelectionList/selectionListPropTypes.js +++ b/src/components/SelectionList/selectionListPropTypes.js @@ -151,9 +151,6 @@ const propTypes = { /** Item `keyForList` to focus initially */ initiallyFocusedOptionKey: PropTypes.string, - /** Whether we are loading new options */ - isLoadingNewOptions: PropTypes.bool, - /** Callback to fire when the list is scrolled */ onScroll: PropTypes.func, diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 6da8524934d3..65b51da1d72d 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useEffect, useMemo} from 'react'; +import React, {useCallback, useMemo, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -11,7 +11,6 @@ import {PressableWithFeedback} from '@components/Pressable'; import ReferralProgramCTA from '@components/ReferralProgramCTA'; import SelectCircle from '@components/SelectCircle'; import SelectionList from '@components/SelectionList'; -import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -86,7 +85,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ }) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); + const [searchTerm, setSearchTerm] = useState(''); const {isOffline} = useNetwork(); const personalDetails = usePersonalDetails(); @@ -248,12 +247,13 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ [maxParticipantsReached, newChatOptions, participants, searchTerm], ); - useEffect(() => { - if (!debouncedSearchTerm.length) { - return; + // When search term updates we will fetch any reports + const setSearchTermAndSearchInServer = useCallback((text = '') => { + if (text.length) { + Report.searchInServer(text); } - Report.searchInServer(debouncedSearchTerm); - }, [debouncedSearchTerm]); + setSearchTerm(text); + }, []); // Right now you can't split a request with a workspace and other additional participants // This is getting properly fixed in https://github.com/Expensify/App/issues/27508, but as a stop-gap to prevent @@ -341,7 +341,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ textInputValue={searchTerm} textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')} textInputHint={offlineMessage} - onChangeText={setSearchTerm} + onChangeText={setSearchTermAndSearchInServer} shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()} onSelectRow={addSingleParticipant} footerContent={footerContent} From c235a069b0630394813b8bb18cf4b1fc94d61e53 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Fri, 19 Jan 2024 13:53:25 -0300 Subject: [PATCH 30/32] remove redundance --- .../MoneyTemporaryForRefactorRequestParticipantsSelector.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 65b51da1d72d..699284645162 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -348,7 +348,6 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ headerMessage={headerMessage} showLoadingPlaceholder={!(didScreenTransitionEnd && isOptionsDataReady)} rightHandSideComponent={itemRightSideComponent} - isLoadingNewOptions={isSearchingForReports} /> ); From a5caca2d9e411566e7a9510d416c8dbd8930248b Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 25 Jan 2024 10:15:52 -0300 Subject: [PATCH 31/32] fix lint --- .../MoneyTemporaryForRefactorRequestParticipantsSelector.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 40f535ebbaf7..34c06fad8618 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -80,7 +80,6 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ safeAreaPaddingBottomStyle, iouType, iouRequestType, - isSearchingForReports, didScreenTransitionEnd, }) { const {translate} = useLocalize(); From c53276d7bb3e30edc066d9c01ef58d701459e521 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Thu, 25 Jan 2024 10:55:35 -0300 Subject: [PATCH 32/32] fix lint: Removed unused variables and props --- ...oneyTemporaryForRefactorRequestParticipantsSelector.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 34c06fad8618..15f98205839e 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -55,9 +55,6 @@ const propTypes = { /** The request type, ie. manual, scan, distance */ iouRequestType: PropTypes.oneOf(_.values(CONST.IOU.REQUEST_TYPE)).isRequired, - /** Whether we are searching for reports in the server */ - isSearchingForReports: PropTypes.bool, - /** Whether the parent screen transition has ended */ didScreenTransitionEnd: PropTypes.bool, }; @@ -67,7 +64,6 @@ const defaultProps = { safeAreaPaddingBottomStyle: {}, reports: {}, betas: [], - isSearchingForReports: false, didScreenTransitionEnd: false, }; @@ -369,8 +365,4 @@ export default withOnyx({ betas: { key: ONYXKEYS.BETAS, }, - isSearchingForReports: { - key: ONYXKEYS.IS_SEARCHING_FOR_REPORTS, - initWithStoredValues: false, - }, })(MoneyTemporaryForRefactorRequestParticipantsSelector);