forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dismissModalWithReport.ts
157 lines (143 loc) · 7.11 KB
/
dismissModalWithReport.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import {getActionFromState} from '@react-navigation/core';
import type {NavigationContainerRef} from '@react-navigation/native';
import {StackActions} from '@react-navigation/native';
import {findLastIndex} from 'lodash';
import type {OnyxEntry} from 'react-native-onyx';
import Log from '@libs/Log';
import {isCentralPaneName} from '@libs/NavigationUtils';
import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils';
import {doesReportBelongToWorkspace} from '@libs/ReportUtils';
import NAVIGATORS from '@src/NAVIGATORS';
import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';
import type {Report} from '@src/types/onyx';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import getPolicyIDFromState from './getPolicyIDFromState';
import getStateFromPath from './getStateFromPath';
import getTopmostReportId from './getTopmostReportId';
import linkingConfig from './linkingConfig';
import switchPolicyID from './switchPolicyID';
import type {RootStackParamList, StackNavigationAction, State} from './types';
// This function is in a separate file than Navigation.ts to avoid cyclic dependency.
/**
* Dismisses the last modal stack if there is any
*
* @param targetReportID - The reportID to navigate to after dismissing the modal
*/
// function dismissModalWithReport(targetReport: OnyxEntry<Report>, navigationRef: NavigationContainerRef<RootStackParamList>) {
// if (!navigationRef.isReady()) {
// return;
// }
// const state = navigationRef.getState();
// const lastRoute = state.routes.at(-1);
// switch (lastRoute?.name) {
// case NAVIGATORS.FULL_SCREEN_NAVIGATOR:
// case NAVIGATORS.LEFT_MODAL_NAVIGATOR:
// case NAVIGATORS.RIGHT_MODAL_NAVIGATOR:
// case SCREENS.NOT_FOUND:
// case SCREENS.ATTACHMENTS:
// case SCREENS.TRANSACTION_RECEIPT:
// case SCREENS.PROFILE_AVATAR:
// case SCREENS.WORKSPACE_AVATAR:
// case SCREENS.REPORT_AVATAR:
// case SCREENS.CONCIERGE:
// // If we are not in the target report, we need to navigate to it after dismissing the modal
// if (targetReport?.reportID !== getTopmostReportId(state)) {
// const reportState = getStateFromPath(ROUTES.REPORT_WITH_ID.getRoute(targetReport?.reportID ?? '-1'));
// const policyID = getPolicyIDFromState(state as State<RootStackParamList>);
// const policyMemberAccountIDs = getPolicyEmployeeAccountIDs(policyID);
// const shouldOpenAllWorkspace = isEmptyObject(targetReport) ? true : !doesReportBelongToWorkspace(targetReport, policyMemberAccountIDs, policyID);
// if (shouldOpenAllWorkspace) {
// switchPolicyID(navigationRef, {route: ROUTES.HOME});
// } else {
// switchPolicyID(navigationRef, {policyID, route: ROUTES.HOME});
// }
// const action: StackNavigationAction = getActionFromState(reportState, linkingConfig.config);
// if (action) {
// action.type = 'REPLACE';
// navigationRef.dispatch(action);
// }
// // If not-found page is in the route stack, we need to close it
// } else if (state.routes.some((route) => route.name === SCREENS.NOT_FOUND)) {
// const lastRouteIndex = state.routes.length - 1;
// const centralRouteIndex = findLastIndex(state.routes, (route) => isCentralPaneName(route.name));
// navigationRef.dispatch({...StackActions.pop(lastRouteIndex - centralRouteIndex), target: state.key});
// } else {
// navigationRef.dispatch({...StackActions.pop(), target: state.key});
// }
// break;
// default: {
// Log.hmmm('[Navigation] dismissModalWithReport failed because there is no modal stack to dismiss');
// }
// }
// }
function performDismissModalLogic(targetReport, navigationRef) {
if (!navigationRef.isReady()) {
return false;
}
const state = navigationRef.getState();
const lastRoute = state.routes.at(-1);
switch (lastRoute?.name) {
case NAVIGATORS.FULL_SCREEN_NAVIGATOR:
case NAVIGATORS.LEFT_MODAL_NAVIGATOR:
case NAVIGATORS.RIGHT_MODAL_NAVIGATOR:
case SCREENS.NOT_FOUND:
case SCREENS.ATTACHMENTS:
case SCREENS.TRANSACTION_RECEIPT:
case SCREENS.PROFILE_AVATAR:
case SCREENS.WORKSPACE_AVATAR:
case SCREENS.REPORT_AVATAR:
case SCREENS.CONCIERGE:
if (targetReport?.reportID !== getTopmostReportId(state)) {
const reportState = getStateFromPath(ROUTES.REPORT_WITH_ID.getRoute(targetReport?.reportID ?? '-1'));
const policyID = getPolicyIDFromState(state);
const policyMemberAccountIDs = getPolicyEmployeeAccountIDs(policyID);
const shouldOpenAllWorkspace = isEmptyObject(targetReport) ? true : !doesReportBelongToWorkspace(targetReport, policyMemberAccountIDs, policyID);
if (shouldOpenAllWorkspace) {
switchPolicyID(navigationRef, { route: ROUTES.HOME });
} else {
switchPolicyID(navigationRef, { policyID, route: ROUTES.HOME });
}
const action = getActionFromState(reportState, linkingConfig.config);
if (action) {
action.type = 'REPLACE';
navigationRef.dispatch(action);
return true;
}
} else if (state.routes.some((route) => route.name === SCREENS.NOT_FOUND)) {
const lastRouteIndex = state.routes.length - 1;
const centralRouteIndex = findLastIndex(state.routes, (route) => isCentralPaneName(route.name));
navigationRef.dispatch({ ...StackActions.pop(lastRouteIndex - centralRouteIndex), target: state.key });
} else {
navigationRef.dispatch({ ...StackActions.pop(), target: state.key });
}
return true;
default:
Log.hmmm('[Navigation] dismissModalWithReport failed because there is no modal stack to dismiss');
return false;
}
}
function dismissModalWithReport(targetReport, navigationRef) {
performDismissModalLogic(targetReport, navigationRef);
}
function dismissModalWithPromise(targetReport, navigationRef) {
return new Promise((resolve, reject) => {
const onNavigationStateChange = () => {
resolve();
navigationRef.current?.removeListener('state', onNavigationStateChange);
};
try {
const actionDispatched = performDismissModalLogic(targetReport, navigationRef);
if (actionDispatched) {
navigationRef.current?.addListener('state', onNavigationStateChange);
} else {
resolve();
}
} catch (error) {
navigationRef.current?.removeListener('state', onNavigationStateChange);
reject(error);
}
});
}
export default dismissModalWithReport;
export {dismissModalWithPromise};