forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExpensify.js
183 lines (158 loc) · 5.88 KB
/
Expensify.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {PureComponent} from 'react';
import {View, StatusBar, AppState} from 'react-native';
import Onyx, {withOnyx} from 'react-native-onyx';
import BootSplash from './libs/BootSplash';
import listenToStorageEvents from './libs/listenToStorageEvents';
import * as ActiveClientManager from './libs/ActiveClientManager';
import ONYXKEYS from './ONYXKEYS';
import CONST from './CONST';
import NavigationRoot from './libs/Navigation/NavigationRoot';
import Log from './libs/Log';
import migrateOnyx from './libs/migrateOnyx';
import styles from './styles/styles';
import PushNotification from './libs/Notification/PushNotification';
import UpdateAppModal from './components/UpdateAppModal';
import Visibility from './libs/Visibility';
import GrowlNotification from './components/GrowlNotification';
import {growlRef} from './libs/Growl';
// Initialize the store when the app loads for the first time
Onyx.init({
keys: ONYXKEYS,
safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
initialKeyStates: {
// Clear any loading and error messages so they do not appear on app startup
[ONYXKEYS.SESSION]: {loading: false, shouldShowComposeInput: true},
[ONYXKEYS.ACCOUNT]: CONST.DEFAULT_ACCOUNT_DATA,
[ONYXKEYS.NETWORK]: {isOffline: false},
[ONYXKEYS.IOU]: {loading: false, error: false, creatingIOUTransaction: false},
},
registerStorageEventListener: (onStorageEvent) => {
listenToStorageEvents(onStorageEvent);
},
});
Onyx.registerLogger(({level, message}) => {
if (level === 'alert') {
Log.alert(message, 0, {}, false);
} else {
Log.client(message);
}
});
const propTypes = {
/* Onyx Props */
/** Session info for the currently logged in user. */
session: PropTypes.shape({
/** Currently logged in user authToken */
authToken: PropTypes.string,
/** Currently logged in user accountID */
accountID: PropTypes.number,
}),
/** Whether a new update is available and ready to install. */
updateAvailable: PropTypes.bool,
/** Whether the initial data needed to render the app is ready */
initialReportDataLoaded: PropTypes.bool,
};
const defaultProps = {
session: {
authToken: null,
accountID: null,
},
updateAvailable: false,
initialReportDataLoaded: false,
};
class Expensify extends PureComponent {
constructor(props) {
super(props);
// Initialize this client as being an active client
ActiveClientManager.init();
this.hideSplash = this.hideSplash.bind(this);
this.initializeClient = this.initializeClient.bind(true);
this.state = {
isOnyxMigrated: false,
};
}
componentDidMount() {
// Run any Onyx schema migrations and then continue loading the main app
migrateOnyx()
.then(() => {
// When we don't have an authToken we'll want to show the sign in screen immediately so we'll hide our
// boot screen right away
if (!this.getAuthToken()) {
this.hideSplash();
}
this.setState({isOnyxMigrated: true});
});
AppState.addEventListener('change', this.initializeClient);
}
componentDidUpdate(prevProps) {
const previousAccountID = lodashGet(prevProps, 'session.accountID', null);
const currentAccountID = lodashGet(this.props, 'session.accountID', null);
if (currentAccountID && (currentAccountID !== previousAccountID)) {
PushNotification.register(currentAccountID);
}
// If we previously had no authToken and now have an authToken we'll want to reshow the boot splash screen so
// that we can remove it again once the content is ready
const previousAuthToken = lodashGet(prevProps, 'session.authToken', null);
if (this.getAuthToken() && !previousAuthToken) {
BootSplash.show({fade: true});
}
if (this.getAuthToken() && this.props.initialReportDataLoaded) {
BootSplash.getVisibilityStatus()
.then((value) => {
if (value !== 'visible') {
return;
}
this.hideSplash();
});
}
}
componentWillUnmount() {
AppState.removeEventListener('change', this.initializeClient);
}
getAuthToken() {
return lodashGet(this.props, 'session.authToken', null);
}
initializeClient() {
if (Visibility.isVisible()) {
ActiveClientManager.init();
}
}
hideSplash() {
BootSplash.hide({fade: true}).then(() => {
// To prevent the splash from shifting positions we set status bar translucent after splash is hidden.
// on IOS it has no effect.
StatusBar.setTranslucent(true);
});
}
render() {
// Display a blank page until the onyx migration completes
if (!this.state.isOnyxMigrated) {
return (
<View style={styles.genericView} />
);
}
return (
<>
<GrowlNotification ref={growlRef} />
{/* We include the modal for showing a new update at the top level so the option is always present. */}
{this.props.updateAvailable ? <UpdateAppModal /> : null}
<NavigationRoot authenticated={Boolean(this.getAuthToken())} />
</>
);
}
}
Expensify.propTypes = propTypes;
Expensify.defaultProps = defaultProps;
export default withOnyx({
session: {
key: ONYXKEYS.SESSION,
},
updateAvailable: {
key: ONYXKEYS.UPDATE_AVAILABLE,
initWithStoredValues: false,
},
initialReportDataLoaded: {
key: ONYXKEYS.INITIAL_REPORT_DATA_LOADED,
},
})(Expensify);