-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
index.website.js
157 lines (138 loc) · 5.59 KB
/
index.website.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
import _ from 'underscore';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import React, {PureComponent} from 'react';
import deeplinkRoutes from './deeplinkRoutes';
import FullScreenLoadingIndicator from '../FullscreenLoadingIndicator';
import TextLink from '../TextLink';
import * as Illustrations from '../Icon/Illustrations';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';
import Text from '../Text';
import styles from '../../styles/styles';
import CONST from '../../CONST';
import CONFIG from '../../CONFIG';
import Icon from '../Icon';
import * as Expensicons from '../Icon/Expensicons';
import colors from '../../styles/colors';
import * as Browser from '../../libs/Browser';
const propTypes = {
/** Children to render. */
children: PropTypes.node.isRequired,
...withLocalizePropTypes,
};
class DeeplinkWrapper extends PureComponent {
constructor(props) {
super(props);
this.state = {
appInstallationCheckStatus: this.isMacOSWeb() ? 'checking' : 'not-installed',
};
}
componentDidMount() {
if (!this.isMacOSWeb()) {
return;
}
let focused = true;
window.addEventListener('blur', () => {
focused = false;
});
setTimeout(() => {
if (!focused) {
this.setState({appInstallationCheckStatus: 'installed'});
} else {
this.setState({appInstallationCheckStatus: 'not-installed'});
}
}, 500);
// check if pathname matches with deeplink routes
const matchedRoute = _.find(deeplinkRoutes, (route) => {
const routeRegex = new RegExp(route.pattern);
return routeRegex.test(window.location.pathname);
});
if (matchedRoute) {
this.setState({deeplinkMatch: true});
this.openRouteInDesktopApp();
} else {
this.setState({deeplinkMatch: false});
}
}
openRouteInDesktopApp() {
const expensifyUrl = new URL(CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL);
const expensifyDeeplinkUrl = `${CONST.DEEPLINK_BASE_URL}${expensifyUrl.host}${window.location.pathname}`;
// This check is necessary for Safari, otherwise, if the user
// does NOT have the Expensify desktop app installed, it's gonna
// show an error in the page saying that the address is invalid
if (CONST.BROWSER.SAFARI === Browser.getBrowser()) {
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.contentWindow.location.href = expensifyDeeplinkUrl;
// Since we're creating an iframe for Safari to handle
// deeplink we need to give this iframe some time for
// it to do what it needs to do. After that we can just
// remove the iframe.
setTimeout(() => {
if (!iframe.parentNode) {
return;
}
iframe.parentNode.removeChild(iframe);
}, 100);
} else {
window.location.href = expensifyDeeplinkUrl;
}
}
isMacOSWeb() {
return !Browser.isMobile() && (
typeof navigator === 'object'
&& typeof navigator.userAgent === 'string'
&& /Mac/i.test(navigator.userAgent)
&& !/Electron/i.test(navigator.userAgent)
);
}
render() {
if (this.state.appInstallationCheckStatus === 'checking') {
return <FullScreenLoadingIndicator style={styles.flex1} />;
}
if (
this.state.deeplinkMatch
&& this.state.appInstallationCheckStatus === 'installed'
) {
return (
<View style={styles.deeplinkWrapperContainer}>
<View style={styles.deeplinkWrapperMessage}>
<View style={styles.mb2}>
<Icon
width={200}
height={164}
src={Illustrations.RocketBlue}
/>
</View>
<Text style={[styles.textHeadline, styles.textXXLarge]}>
{this.props.translate('deeplinkWrapper.launching')}
</Text>
<View style={styles.mt2}>
<Text style={[styles.fontSizeNormal, styles.textAlignCenter]}>
{this.props.translate('deeplinkWrapper.redirectedToDesktopApp')}
{'\n'}
{this.props.translate('deeplinkWrapper.youCanAlso')}
{' '}
<TextLink onPress={() => this.setState({deeplinkMatch: false})}>
{this.props.translate('deeplinkWrapper.openLinkInBrowser')}
</TextLink>
</Text>
</View>
</View>
<View style={styles.deeplinkWrapperFooter}>
<Icon
width={154}
height={34}
fill={colors.green}
src={Expensicons.ExpensifyWordmark}
/>
</View>
</View>
);
}
return this.props.children;
}
}
DeeplinkWrapper.propTypes = propTypes;
export default withLocalize(DeeplinkWrapper);