|
@@ -5,8 +5,15 @@ import { Icon, IconClose } from '../../base/icons';
|
5
|
5
|
import { translate } from '../../base/i18n';
|
6
|
6
|
import { getCurrentConference } from '../../base/conference/functions';
|
7
|
7
|
import { browser } from '../../base/lib-jitsi-meet';
|
8
|
|
-import { isMobileBrowser } from '../../base/environment/utils';
|
|
8
|
+import {
|
|
9
|
+ checkChromeExtensionsInstalled,
|
|
10
|
+ isMobileBrowser
|
|
11
|
+} from '../../base/environment/utils';
|
9
|
12
|
import logger from '../logger';
|
|
13
|
+import {
|
|
14
|
+ createChromeExtensionBannerEvent,
|
|
15
|
+ sendAnalytics
|
|
16
|
+} from '../../analytics';
|
10
|
17
|
|
11
|
18
|
declare var interfaceConfig: Object;
|
12
|
19
|
|
|
@@ -23,19 +30,14 @@ const DONT_SHOW_AGAIN_CHECKED = 'hide_chrome_extension_banner';
|
23
|
30
|
type Props = {
|
24
|
31
|
|
25
|
32
|
/**
|
26
|
|
- * Conference data, if any
|
27
|
|
- */
|
28
|
|
- conference: Object,
|
29
|
|
-
|
30
|
|
- /**
|
31
|
|
- * The url of the chrome extension
|
|
33
|
+ * Contains info about installed/to be installed chrome extension(s).
|
32
|
34
|
*/
|
33
|
|
- chromeExtensionUrl: string,
|
|
35
|
+ bannerCfg: Object,
|
34
|
36
|
|
35
|
37
|
/**
|
36
|
|
- * An array containing info for identifying a chrome extension
|
|
38
|
+ * Conference data, if any
|
37
|
39
|
*/
|
38
|
|
- chromeExtensionsInfo: Array<Object>,
|
|
40
|
+ conference: Object,
|
39
|
41
|
|
40
|
42
|
/**
|
41
|
43
|
* Whether I am the current recorder.
|
|
@@ -91,7 +93,6 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
|
91
|
93
|
|
92
|
94
|
this._onClosePressed = this._onClosePressed.bind(this);
|
93
|
95
|
this._onInstallExtensionClick = this._onInstallExtensionClick.bind(this);
|
94
|
|
- this._checkExtensionsInstalled = this._checkExtensionsInstalled.bind(this);
|
95
|
96
|
this._shouldNotRender = this._shouldNotRender.bind(this);
|
96
|
97
|
this._onDontShowAgainChange = this._onDontShowAgainChange.bind(this);
|
97
|
98
|
}
|
|
@@ -107,15 +108,18 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
|
107
|
108
|
return;
|
108
|
109
|
}
|
109
|
110
|
|
110
|
|
- if (this.props.chromeExtensionUrl && !prevProps.chromeExtensionUrl) {
|
|
111
|
+ const { bannerCfg } = this.props;
|
|
112
|
+ const prevBannerCfg = prevProps.bannerCfg;
|
|
113
|
+
|
|
114
|
+ if (bannerCfg.url && !prevBannerCfg.url) {
|
111
|
115
|
logger.info('Chrome extension URL found.');
|
112
|
116
|
}
|
113
|
117
|
|
114
|
|
- if (this.props.chromeExtensionsInfo.length && !prevProps.chromeExtensionsInfo.length) {
|
|
118
|
+ if ((bannerCfg.chromeExtensionsInfo || []).length && !(prevBannerCfg.chromeExtensionsInfo || []).length) {
|
115
|
119
|
logger.info('Chrome extension(s) info found.');
|
116
|
120
|
}
|
117
|
121
|
|
118
|
|
- const hasExtensions = await this._checkExtensionsInstalled();
|
|
122
|
+ const hasExtensions = await checkChromeExtensionsInstalled(this.props.bannerCfg);
|
119
|
123
|
|
120
|
124
|
if (
|
121
|
125
|
hasExtensions
|
|
@@ -147,6 +151,7 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
|
147
|
151
|
* @returns {void}
|
148
|
152
|
*/
|
149
|
153
|
_onClosePressed() {
|
|
154
|
+ sendAnalytics(createChromeExtensionBannerEvent(false));
|
150
|
155
|
this.setState({ closePressed: true });
|
151
|
156
|
}
|
152
|
157
|
|
|
@@ -158,36 +163,11 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
|
158
|
163
|
* @returns {void}
|
159
|
164
|
*/
|
160
|
165
|
_onInstallExtensionClick() {
|
161
|
|
- window.open(this.props.chromeExtensionUrl);
|
|
166
|
+ sendAnalytics(createChromeExtensionBannerEvent(true));
|
|
167
|
+ window.open(this.props.bannerCfg.url);
|
162
|
168
|
this.setState({ closePressed: true });
|
163
|
169
|
}
|
164
|
170
|
|
165
|
|
- _checkExtensionsInstalled: () => Promise<*>;
|
166
|
|
-
|
167
|
|
- /**
|
168
|
|
- * Checks whether the chrome extensions defined in the config file are installed or not.
|
169
|
|
- *
|
170
|
|
- * @returns {Promise[]}
|
171
|
|
- */
|
172
|
|
- _checkExtensionsInstalled() {
|
173
|
|
- const isExtensionInstalled = info => new Promise(resolve => {
|
174
|
|
- const img = new Image();
|
175
|
|
-
|
176
|
|
- img.src = `chrome-extension://${info.id}/${info.path}`;
|
177
|
|
- img.onload = function() {
|
178
|
|
- resolve(true);
|
179
|
|
- };
|
180
|
|
- img.onerror = function() {
|
181
|
|
- resolve(false);
|
182
|
|
- };
|
183
|
|
- });
|
184
|
|
- const extensionInstalledFunction = info => isExtensionInstalled(info);
|
185
|
|
-
|
186
|
|
- return Promise.all(
|
187
|
|
- this.props.chromeExtensionsInfo.map(info => extensionInstalledFunction(info))
|
188
|
|
- );
|
189
|
|
- }
|
190
|
|
-
|
191
|
171
|
_shouldNotRender: () => boolean;
|
192
|
172
|
|
193
|
173
|
/**
|
|
@@ -202,7 +182,7 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
|
202
|
182
|
|
203
|
183
|
const dontShowAgain = localStorage.getItem(DONT_SHOW_AGAIN_CHECKED) === 'true';
|
204
|
184
|
|
205
|
|
- return !this.props.chromeExtensionUrl
|
|
185
|
+ return !this.props.bannerCfg.url
|
206
|
186
|
|| dontShowAgain
|
207
|
187
|
|| this.state.closePressed
|
208
|
188
|
|| !this.state.shouldShow
|
|
@@ -290,11 +270,8 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
|
290
|
270
|
* @returns {Object}
|
291
|
271
|
*/
|
292
|
272
|
const _mapStateToProps = state => {
|
293
|
|
- const bannerCfg = state['features/base/config'].chromeExtensionBanner || {};
|
294
|
|
-
|
295
|
273
|
return {
|
296
|
|
- chromeExtensionUrl: bannerCfg.url,
|
297
|
|
- chromeExtensionsInfo: bannerCfg.chromeExtensionsInfo || [],
|
|
274
|
+ bannerCfg: state['features/base/config'].chromeExtensionBanner || {},
|
298
|
275
|
conference: getCurrentConference(state),
|
299
|
276
|
iAmRecorder: state['features/base/config'].iAmRecorder
|
300
|
277
|
};
|