-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
MainDrawerNavigator.js
159 lines (139 loc) · 5.26 KB
/
MainDrawerNavigator.js
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
158
159
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import lodashGet from 'lodash/get';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import ONYXKEYS from '../../../ONYXKEYS';
import SCREENS from '../../../SCREENS';
import Permissions from '../../Permissions';
import Timing from '../../actions/Timing';
import CONST from '../../../CONST';
// Screens
import ReportScreen from '../../../pages/home/ReportScreen';
import SidebarScreen from '../../../pages/home/sidebar/SidebarScreen';
import BaseDrawerNavigator from './BaseDrawerNavigator';
import * as ReportUtils from '../../ReportUtils';
import reportPropTypes from '../../../pages/reportPropTypes';
import Navigation from '../Navigation';
import {withNavigationPropTypes} from '../../../components/withNavigation';
const propTypes = {
/** Available reports that would be displayed in this navigator */
reports: PropTypes.objectOf(reportPropTypes),
/** Beta features list */
betas: PropTypes.arrayOf(PropTypes.string),
/** The policies which the user has access to */
policies: PropTypes.objectOf(PropTypes.shape({
/** The policy name */
name: PropTypes.string,
/** The type of the policy */
type: PropTypes.string,
})),
route: PropTypes.shape({
params: PropTypes.shape({
openOnAdminRoom: PropTypes.bool,
}),
}).isRequired,
...withNavigationPropTypes,
};
const defaultProps = {
reports: {},
betas: [],
policies: {},
};
/**
* Get the most recently accessed report for the user
*
* @param {Object} reports
* @param {Boolean} [ignoreDefaultRooms]
* @param {Object} policies
* @param {Boolean} openOnAdminRoom
* @returns {Object}
*/
const getInitialReportScreenParams = (reports, ignoreDefaultRooms, policies, openOnAdminRoom) => {
const last = ReportUtils.findLastAccessedReport(reports, ignoreDefaultRooms, policies, openOnAdminRoom);
// Fallback to empty if for some reason reportID cannot be derived - prevents the app from crashing
const reportID = lodashGet(last, 'reportID', '');
return {reportID: String(reportID)};
};
class MainDrawerNavigator extends Component {
constructor(props) {
super(props);
this.trackAppStartTiming = this.trackAppStartTiming.bind(this);
this.initialParams = getInitialReportScreenParams(
props.reports,
!Permissions.canUseDefaultRooms(props.betas),
props.policies,
lodashGet(props, 'route.params.openOnAdminRoom', false),
);
// When we have chat reports the moment this component got created
// we know that the data was served from storage/cache
this.isFromCache = _.size(props.reports) > 0;
}
shouldComponentUpdate(nextProps) {
const initialNextParams = getInitialReportScreenParams(
nextProps.reports,
!Permissions.canUseDefaultRooms(nextProps.betas),
nextProps.policies,
lodashGet(nextProps, 'route.params.openOnAdminRoom', false),
);
if (this.initialParams.reportID === initialNextParams.reportID) {
return false;
}
// Update the report screen initial params after the reports are available
// to show the correct report instead of the "no access" report.
// https://github.com/Expensify/App/issues/12698#issuecomment-1352632883
if (!this.initialParams.reportID) {
const state = this.props.navigation.getState();
const reportScreenKey = lodashGet(state, 'routes[0].state.routes[0].key', '');
Navigation.setParams(initialNextParams, reportScreenKey);
}
this.initialParams = initialNextParams;
return true;
}
trackAppStartTiming() {
// We only want to report timing events when rendering from cached data
if (!this.isFromCache) {
return;
}
Timing.end(CONST.TIMING.SIDEBAR_LOADED);
}
render() {
return (
<BaseDrawerNavigator
drawerContent={({navigation, state}) => {
// This state belongs to the drawer so it should always have the ReportScreen as it's initial (and only) route
const reportIDFromRoute = lodashGet(state, ['routes', 0, 'params', 'reportID']);
return (
<SidebarScreen
navigation={navigation}
onLayout={this.trackAppStartTiming}
reportIDFromRoute={reportIDFromRoute}
/>
);
}}
screens={[
{
name: SCREENS.REPORT,
component: ReportScreen,
initialParams: this.initialParams,
},
]}
isMainScreen
/>
);
}
}
MainDrawerNavigator.propTypes = propTypes;
MainDrawerNavigator.defaultProps = defaultProps;
MainDrawerNavigator.displayName = 'MainDrawerNavigator';
export default withOnyx({
reports: {
key: ONYXKEYS.COLLECTION.REPORT,
},
betas: {
key: ONYXKEYS.BETAS,
},
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
})(MainDrawerNavigator);