diff --git a/patches/@react-navigation+stack+6.3.16.patch b/patches/@react-navigation+stack+6.3.16.patch index 921f09491927..cf76b607d8d7 100644 --- a/patches/@react-navigation+stack+6.3.16.patch +++ b/patches/@react-navigation+stack+6.3.16.patch @@ -74,7 +74,6 @@ index 6bbce10..7f2eed3 100644 + { route }: { route: Route }, + state: StackNavigationState + ) => { -+ console.log(state) this.props.navigation.emit({ type: 'gestureStart', target: route.key, diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index efbae8bde2cd..fd73bf0d6a29 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -1,6 +1,7 @@ import _ from 'lodash'; import lodashGet from 'lodash/get'; import {CommonActions, getPathFromState, StackActions} from '@react-navigation/native'; +import {getActionFromState} from '@react-navigation/core'; import Log from '../Log'; import DomUtils from '../DomUtils'; import linkTo from './linkTo'; @@ -10,6 +11,7 @@ import navigationRef from './navigationRef'; import NAVIGATORS from '../../NAVIGATORS'; import originalGetTopmostReportId from './getTopmostReportId'; import dismissKeyboardGoingBack from './dismissKeyboardGoingBack'; +import getStateFromPath from './getStateFromPath'; let resolveNavigationIsReadyPromise; const navigationIsReadyPromise = new Promise((resolve) => { @@ -122,15 +124,26 @@ function setParams(params, routeKey) { /** * Dismisses the last modal stack if there is any + * + * @param {String | undefined} targetReportID - The reportID to navigate to after dismissing the modal */ -function dismissModal() { +function dismissModal(targetReportID) { if (!canNavigate('dismissModal')) { return; } const rootState = navigationRef.getRootState(); const lastRoute = _.last(rootState.routes); if (lastRoute.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR || lastRoute.name === NAVIGATORS.FULL_SCREEN_NAVIGATOR) { - navigationRef.current.dispatch(StackActions.pop()); + // if we are not in the target report, we need to navigate to it after dismissing the modal + if (targetReportID && targetReportID !== getTopmostReportId(rootState)) { + const state = getStateFromPath(ROUTES.getReportRoute(targetReportID)); + + const action = getActionFromState(state, linkingConfig.config); + action.type = 'REPLACE'; + navigationRef.current.dispatch(action); + } else { + navigationRef.current.dispatch(StackActions.pop()); + } } else { Log.hmmm('[Navigation] dismissModal failed because there is no modal stack to dismiss'); } diff --git a/src/libs/Navigation/getStateFromPath.js b/src/libs/Navigation/getStateFromPath.js new file mode 100644 index 000000000000..f2564c9d2512 --- /dev/null +++ b/src/libs/Navigation/getStateFromPath.js @@ -0,0 +1,19 @@ +import {getStateFromPath as RNGetStateFromPath} from '@react-navigation/native'; +import linkingConfig from './linkingConfig'; + +/** + * @param {String} path - The path to parse + * @returns {Object | undefined} - It's possible that there is no navigation action for the given path + */ +function getStateFromPath(path) { + const normalizedPath = !path.startsWith('/') ? `/${path}` : path; + + const state = linkingConfig.getStateFromPath ? linkingConfig.getStateFromPath(normalizedPath, linkingConfig.config) : RNGetStateFromPath(normalizedPath, linkingConfig.config); + + if (!state) { + throw new Error('Failed to parse the path to a navigation state.'); + } + return state; +} + +export default getStateFromPath; diff --git a/src/libs/Navigation/linkTo.js b/src/libs/Navigation/linkTo.js index ed2b4c9274e2..e1deab0b9008 100644 --- a/src/libs/Navigation/linkTo.js +++ b/src/libs/Navigation/linkTo.js @@ -1,22 +1,16 @@ -import {getStateFromPath, getActionFromState} from '@react-navigation/core'; +import {getActionFromState} from '@react-navigation/core'; import {Platform} from 'react-native'; import _ from 'lodash'; import NAVIGATORS from '../../NAVIGATORS'; import linkingConfig from './linkingConfig'; import getTopmostReportId from './getTopmostReportId'; +import getStateFromPath from './getStateFromPath'; export default function linkTo(navigation, path, type) { - const normalizedPath = !path.startsWith('/') ? `/${path}` : path; if (navigation === undefined) { throw new Error("Couldn't find a navigation object. Is your component inside a screen in a navigator?"); } - const state = linkingConfig.getStateFromPath ? linkingConfig.getStateFromPath(normalizedPath, linkingConfig.config) : getStateFromPath(normalizedPath, linkingConfig.config); - - if (!state) { - throw new Error('Failed to parse the path to a navigation state.'); - } - let root = navigation; let current; @@ -26,6 +20,8 @@ export default function linkTo(navigation, path, type) { root = current; } + const state = getStateFromPath(path); + const action = getActionFromState(state, linkingConfig.config); // If action type is different than NAVIGATE we can't change it to the PUSH safely diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index ccc133cc56bd..f89f24ba3ee1 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -377,7 +377,7 @@ function requestMoney(report, amount, currency, payeeEmail, participant, comment }, {optimisticData, successData, failureData}, ); - Navigation.navigate(ROUTES.getReportRoute(chatReport.reportID)); + Navigation.dismissModal(chatReport.reportID); } /** @@ -691,7 +691,7 @@ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, onyxData, ); - Navigation.navigate(ROUTES.getReportRoute(groupData.chatReportID)); + Navigation.dismissModal(groupData.chatReportID); } /** @@ -800,7 +800,7 @@ function deleteMoneyRequest(chatReportID, iouReportID, moneyRequestAction, shoul ); if (shouldCloseOnDelete) { - Navigation.navigate(ROUTES.getReportRoute(iouReportID)); + Navigation.dismissModal(iouReportID); } } @@ -1144,7 +1144,7 @@ function sendMoneyElsewhere(report, amount, currency, comment, managerEmail, rec API.write('SendMoneyElsewhere', params, {optimisticData, successData, failureData}); - Navigation.navigate(ROUTES.getReportRoute(params.chatReportID)); + Navigation.dismissModal(params.chatReportID); } /** @@ -1160,7 +1160,7 @@ function sendMoneyWithWallet(report, amount, currency, comment, managerEmail, re API.write('SendMoneyWithWallet', params, {optimisticData, successData, failureData}); - Navigation.navigate(ROUTES.getReportRoute(params.chatReportID)); + Navigation.dismissModal(params.chatReportID); } /** @@ -1176,7 +1176,7 @@ function sendMoneyViaPaypal(report, amount, currency, comment, managerEmail, rec API.write('SendMoneyViaPaypal', params, {optimisticData, successData, failureData}); - Navigation.navigate(ROUTES.getReportRoute(params.chatReportID)); + Navigation.dismissModal(params.chatReportID); asyncOpenURL(Promise.resolve(), buildPayPalPaymentUrl(amount, recipient.payPalMeAddress, currency)); } @@ -1195,7 +1195,7 @@ function payMoneyRequest(paymentType, chatReport, iouReport) { const {params, optimisticData, successData, failureData} = getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentType); API.write('PayMoneyRequest', params, {optimisticData, successData, failureData}); - Navigation.navigate(ROUTES.getReportRoute(chatReport.reportID)); + Navigation.dismissModal(chatReport.reportID); if (paymentType === CONST.IOU.PAYMENT_TYPE.PAYPAL_ME) { asyncOpenURL(Promise.resolve(), buildPayPalPaymentUrl(iouReport.total, recipient.payPalMeAddress, iouReport.currency)); } diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 6a4cd9fe3050..547aed7e4f0f 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -434,7 +434,7 @@ function navigateToAndOpenReport(userLogins) { // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server openReport(reportID, newChat.participants, newChat); - Navigation.navigate(ROUTES.getReportRoute(reportID)); + Navigation.dismissModal(reportID); } /** @@ -1208,7 +1208,7 @@ function addPolicyReport(policy, reportName, visibility) { }, {optimisticData, successData}, ); - Navigation.navigate(ROUTES.getReportRoute(policyReport.reportID)); + Navigation.dismissModal(policyReport.reportID); } /** diff --git a/src/pages/tasks/TaskDescriptionPage.js b/src/pages/tasks/TaskDescriptionPage.js index 1b72f16462cd..e0274fdf2f35 100644 --- a/src/pages/tasks/TaskDescriptionPage.js +++ b/src/pages/tasks/TaskDescriptionPage.js @@ -75,7 +75,7 @@ function TaskDescriptionPage(props) { title={props.translate('newTaskPage.task')} shouldShowBackButton onBackButtonPress={() => Navigation.goBack()} - onCloseButtonPress={() => Navigation.dismissModal(true)} + onCloseButtonPress={() => Navigation.dismissModal()} />
Navigation.goBack()} - onCloseButtonPress={() => Navigation.dismissModal(true)} + onCloseButtonPress={() => Navigation.dismissModal()} /> currentYearMonth) { - Navigation.dismissModal(true); + Navigation.dismissModal(); } }