Browse Source

feat(deep_linking): add analytics

In order to be able to add analytics to the deep-linking pages the
lib-jitsi-meet initialization has been moved so it happens earlier.

The introduced `initPromise` will eventually disappear, once conference is
migrated into React and / or support for Temasys is dropped. At that stage, it
can be turned into a sync function which all platforms share.
j8
hristoterezov 7 years ago
parent
commit
f14095ecfc

+ 8
- 43
conference.js View File

21
     createSelectParticipantFailedEvent,
21
     createSelectParticipantFailedEvent,
22
     createStreamSwitchDelayEvent,
22
     createStreamSwitchDelayEvent,
23
     createTrackMutedEvent,
23
     createTrackMutedEvent,
24
-    initAnalytics,
25
     sendAnalytics
24
     sendAnalytics
26
 } from './react/features/analytics';
25
 } from './react/features/analytics';
27
 import {
26
 import {
49
 } from './react/features/base/conference';
48
 } from './react/features/base/conference';
50
 import { updateDeviceList } from './react/features/base/devices';
49
 import { updateDeviceList } from './react/features/base/devices';
51
 import {
50
 import {
52
-    isAnalyticsEnabled,
53
     isFatalJitsiConnectionError,
51
     isFatalJitsiConnectionError,
54
     JitsiConferenceErrors,
52
     JitsiConferenceErrors,
55
     JitsiConferenceEvents,
53
     JitsiConferenceEvents,
685
     /**
683
     /**
686
      * Open new connection and join to the conference.
684
      * Open new connection and join to the conference.
687
      * @param {object} options
685
      * @param {object} options
688
-     * @param {string} roomName name of the conference
686
+     * @param {string} roomName - The name of the conference.
689
      * @returns {Promise}
687
      * @returns {Promise}
690
      */
688
      */
691
     init(options) {
689
     init(options) {
692
         this.roomName = options.roomName;
690
         this.roomName = options.roomName;
693
 
691
 
694
-        // attaches global error handler, if there is already one, respect it
695
-        if (JitsiMeetJS.getGlobalOnErrorHandler) {
696
-            const oldOnErrorHandler = window.onerror;
697
-
698
-            // eslint-disable-next-line max-params
699
-            window.onerror = (message, source, lineno, colno, error) => {
700
-                JitsiMeetJS.getGlobalOnErrorHandler(
701
-                    message, source, lineno, colno, error);
702
-
703
-                if (oldOnErrorHandler) {
704
-                    oldOnErrorHandler(message, source, lineno, colno, error);
705
-                }
706
-            };
707
-
708
-            const oldOnUnhandledRejection = window.onunhandledrejection;
709
-
710
-            window.onunhandledrejection = function(event) {
711
-                JitsiMeetJS.getGlobalOnErrorHandler(
712
-                    null, null, null, null, event.reason);
713
-
714
-                if (oldOnUnhandledRejection) {
715
-                    oldOnUnhandledRejection(event);
716
-                }
717
-            };
718
-        }
719
-
720
         return (
692
         return (
721
-            JitsiMeetJS.init({
722
-                enableAnalyticsLogging: isAnalyticsEnabled(APP.store),
723
-                ...config
724
-            }).then(() => {
725
-                initAnalytics(APP.store);
726
-
727
-                return this.createInitialLocalTracksAndConnect(
728
-                    options.roomName, {
729
-                        startAudioOnly: config.startAudioOnly,
730
-                        startScreenSharing: config.startScreenSharing,
731
-                        startWithAudioMuted: config.startWithAudioMuted,
732
-                        startWithVideoMuted: config.startWithVideoMuted
733
-                    });
734
-            })
693
+            this.createInitialLocalTracksAndConnect(
694
+                options.roomName, {
695
+                    startAudioOnly: config.startAudioOnly,
696
+                    startScreenSharing: config.startScreenSharing,
697
+                    startWithAudioMuted: config.startWithAudioMuted,
698
+                    startWithVideoMuted: config.startWithVideoMuted
699
+                })
735
             .then(([ tracks, con ]) => {
700
             .then(([ tracks, con ]) => {
736
                 tracks.forEach(track => {
701
                 tracks.forEach(track => {
737
                     if ((track.isAudioTrack() && this.isLocalAudioMuted())
702
                     if ((track.isAudioTrack() && this.isLocalAudioMuted())

+ 19
- 0
react/features/analytics/AnalyticsEvents.js View File

97
     };
97
     };
98
 }
98
 }
99
 
99
 
100
+/**
101
+ * Creates an event for an action on the deep linking page.
102
+ *
103
+ * @param {string} action - The action that the event represents.
104
+ * @param {string} actionSubject - The subject that was acted upon.
105
+ * @param {boolean} attributes - Additional attributes to attach to the event.
106
+ * @returns {Object} The event in a format suitable for sending via
107
+ * sendAnalytics.
108
+ */
109
+export function createDeepLinkingPageEvent(
110
+        action, actionSubject, attributes = {}) {
111
+    return {
112
+        action,
113
+        actionSubject,
114
+        source: 'deepLinkingPage',
115
+        attributes
116
+    };
117
+}
118
+
100
 /**
119
 /**
101
  * Creates an event which indicates that a device was changed.
120
  * Creates an event which indicates that a device was changed.
102
  *
121
  *

+ 16
- 14
react/features/base/connection/actions.web.js View File

30
 
30
 
31
         // XXX Lib-jitsi-meet does not accept uppercase letters.
31
         // XXX Lib-jitsi-meet does not accept uppercase letters.
32
         const room = state['features/base/conference'].room.toLowerCase();
32
         const room = state['features/base/conference'].room.toLowerCase();
33
+        const { initPromise } = state['features/base/lib-jitsi-meet'];
33
 
34
 
34
         // XXX For web based version we use conference initialization logic
35
         // XXX For web based version we use conference initialization logic
35
         // from the old app (at the moment of writing).
36
         // from the old app (at the moment of writing).
36
-        return APP.conference.init({ roomName: room })
37
-            .catch(error => {
38
-                APP.API.notifyConferenceLeft(APP.conference.roomName);
39
-                logger.error(error);
37
+        return initPromise.then(() => APP.conference.init({
38
+            roomName: room
39
+        })).catch(error => {
40
+            APP.API.notifyConferenceLeft(APP.conference.roomName);
41
+            logger.error(error);
40
 
42
 
41
-                // TODO The following are in fact Errors raised by
42
-                // JitsiMeetJS.init() which should be taken care of in
43
-                // features/base/lib-jitsi-meet but we are not there yet on the
44
-                // Web at the time of this writing.
45
-                switch (error.name) {
46
-                case WEBRTC_NOT_READY:
47
-                case WEBRTC_NOT_SUPPORTED:
48
-                    dispatch(libInitError(error));
49
-                }
50
-            });
43
+            // TODO The following are in fact Errors raised by
44
+            // JitsiMeetJS.init() which should be taken care of in
45
+            // features/base/lib-jitsi-meet but we are not there yet on the
46
+            // Web at the time of this writing.
47
+            switch (error.name) {
48
+            case WEBRTC_NOT_READY:
49
+            case WEBRTC_NOT_SUPPORTED:
50
+                dispatch(libInitError(error));
51
+            }
52
+        });
51
     };
53
     };
52
 }
54
 }
53
 
55
 

+ 10
- 0
react/features/base/lib-jitsi-meet/actionTypes.js View File

27
  */
27
  */
28
 export const LIB_INIT_ERROR = Symbol('LIB_INIT_ERROR');
28
 export const LIB_INIT_ERROR = Symbol('LIB_INIT_ERROR');
29
 
29
 
30
+/**
31
+ * Action to dispatch the promise returned by JitsiMeetJS.init.
32
+ *
33
+ * {
34
+ *     type: LIB_INIT_PROMISE_CREATED,
35
+ *     initPromise: Promise
36
+ * }
37
+ */
38
+export const LIB_INIT_PROMISE_CREATED = Symbol('LIB_INIT_PROMISE_CREATED');
39
+
30
 /**
40
 /**
31
  * The type of Redux action which signals that {@link JitsiMeetJS} will be
41
  * The type of Redux action which signals that {@link JitsiMeetJS} will be
32
  * disposed.
42
  * disposed.

+ 17
- 11
react/features/base/lib-jitsi-meet/actions.js View File

7
     LIB_DID_DISPOSE,
7
     LIB_DID_DISPOSE,
8
     LIB_DID_INIT,
8
     LIB_DID_INIT,
9
     LIB_INIT_ERROR,
9
     LIB_INIT_ERROR,
10
+    LIB_INIT_PROMISE_CREATED,
10
     LIB_WILL_DISPOSE,
11
     LIB_WILL_DISPOSE,
11
     LIB_WILL_INIT,
12
     LIB_WILL_INIT,
12
     SET_WEBRTC_READY
13
     SET_WEBRTC_READY
44
             throw new Error('Cannot init lib-jitsi-meet without config');
45
             throw new Error('Cannot init lib-jitsi-meet without config');
45
         }
46
         }
46
 
47
 
47
-        // FIXME Until the logic of conference.js is rewritten into the React
48
-        // app we, JitsiMeetJS.init is to not be used for the React app.
49
-        if (typeof APP !== 'undefined') {
50
-            return Promise.resolve();
51
-        }
52
-
53
         dispatch({ type: LIB_WILL_INIT });
48
         dispatch({ type: LIB_WILL_INIT });
54
 
49
 
50
+        const initPromise = JitsiMeetJS.init({
51
+            enableAnalyticsLogging: isAnalyticsEnabled(getState),
52
+            ...config
53
+        });
54
+
55
+        dispatch({
56
+            type: LIB_INIT_PROMISE_CREATED,
57
+            initPromise
58
+        });
59
+
55
         return (
60
         return (
56
-            JitsiMeetJS.init({
57
-                enableAnalyticsLogging: isAnalyticsEnabled(getState),
58
-                ...config
59
-            })
61
+            initPromise
60
                 .then(() => dispatch({ type: LIB_DID_INIT }))
62
                 .then(() => dispatch({ type: LIB_DID_INIT }))
61
                 .catch(error => {
63
                 .catch(error => {
62
-                    dispatch(libInitError(error));
64
+                    // TODO: See the comment in the connect action in
65
+                    // base/connection/actions.web.js.
66
+                    if (typeof APP === 'undefined') {
67
+                        dispatch(libInitError(error));
68
+                    }
63
 
69
 
64
                     // TODO Handle LIB_INIT_ERROR error somewhere instead.
70
                     // TODO Handle LIB_INIT_ERROR error somewhere instead.
65
                     console.error('lib-jitsi-meet failed to init:', error);
71
                     console.error('lib-jitsi-meet failed to init:', error);

+ 51
- 2
react/features/base/lib-jitsi-meet/middleware.js View File

5
 import { PARTICIPANT_LEFT } from '../participants';
5
 import { PARTICIPANT_LEFT } from '../participants';
6
 import { MiddlewareRegistry } from '../redux';
6
 import { MiddlewareRegistry } from '../redux';
7
 
7
 
8
+import JitsiMeetJS from './_';
8
 import { disposeLib, initLib, setWebRTCReady } from './actions';
9
 import { disposeLib, initLib, setWebRTCReady } from './actions';
9
-import { LIB_DID_INIT, LIB_INIT_ERROR } from './actionTypes';
10
+import { LIB_DID_INIT, LIB_INIT_ERROR, LIB_WILL_INIT } from './actionTypes';
10
 import { WEBRTC_NOT_READY, WEBRTC_NOT_SUPPORTED } from './constants';
11
 import { WEBRTC_NOT_READY, WEBRTC_NOT_SUPPORTED } from './constants';
11
 
12
 
13
+declare var APP: Object;
14
+
12
 /**
15
 /**
13
  * Middleware that captures PARTICIPANT_LEFT action for a local participant
16
  * Middleware that captures PARTICIPANT_LEFT action for a local participant
14
  * (which signalizes that we finally left the app) and disposes lib-jitsi-meet.
17
  * (which signalizes that we finally left the app) and disposes lib-jitsi-meet.
21
  */
24
  */
22
 MiddlewareRegistry.register(store => next => action => {
25
 MiddlewareRegistry.register(store => next => action => {
23
     switch (action.type) {
26
     switch (action.type) {
27
+    case LIB_WILL_INIT:
28
+        // Moved from conference.js init method. It appears the error handlers
29
+        // are not used for mobile.
30
+        if (typeof APP !== 'undefined') {
31
+            _setErrorHandlers();
32
+        }
33
+        break;
24
     case LIB_DID_INIT:
34
     case LIB_DID_INIT:
25
-        store.dispatch(setWebRTCReady(true));
35
+        // FIXME: The web version doesn't need this action during initialization
36
+        // because it is still using the old logic from conference.js. We still
37
+        // have to reactify the old logic from conference.js and then maybe
38
+        // we'll need this action for web too.
39
+        if (typeof APP === 'undefined') {
40
+            store.dispatch(setWebRTCReady(true));
41
+        }
26
         break;
42
         break;
27
 
43
 
28
     case LIB_INIT_ERROR:
44
     case LIB_INIT_ERROR:
119
 
135
 
120
     return result;
136
     return result;
121
 }
137
 }
138
+
139
+/**
140
+ * Attaches our custom error handlers to the window object.
141
+ *
142
+ * @returns {void}
143
+ */
144
+function _setErrorHandlers() {
145
+    // attaches global error handler, if there is already one, respect it
146
+    if (JitsiMeetJS.getGlobalOnErrorHandler) {
147
+        const oldOnErrorHandler = window.onerror;
148
+
149
+        // eslint-disable-next-line max-params
150
+        window.onerror = (message, source, lineno, colno, error) => {
151
+            JitsiMeetJS.getGlobalOnErrorHandler(
152
+                message, source, lineno, colno, error);
153
+
154
+            if (oldOnErrorHandler) {
155
+                oldOnErrorHandler(message, source, lineno, colno, error);
156
+            }
157
+        };
158
+
159
+        const oldOnUnhandledRejection = window.onunhandledrejection;
160
+
161
+        window.onunhandledrejection = function(event) {
162
+            JitsiMeetJS.getGlobalOnErrorHandler(
163
+                null, null, null, null, event.reason);
164
+
165
+            if (oldOnUnhandledRejection) {
166
+                oldOnUnhandledRejection(event);
167
+            }
168
+        };
169
+    }
170
+}

+ 9
- 1
react/features/base/lib-jitsi-meet/reducer.js View File

6
     LIB_DID_DISPOSE,
6
     LIB_DID_DISPOSE,
7
     LIB_DID_INIT,
7
     LIB_DID_INIT,
8
     LIB_INIT_ERROR,
8
     LIB_INIT_ERROR,
9
+    LIB_INIT_PROMISE_CREATED,
9
     SET_WEBRTC_READY
10
     SET_WEBRTC_READY
10
 } from './actionTypes';
11
 } from './actionTypes';
11
 
12
 
34
             return {
35
             return {
35
                 ...state,
36
                 ...state,
36
                 initError: action.error,
37
                 initError: action.error,
37
-                initialized: false
38
+                initialized: false,
39
+                initPromise: undefined
40
+            };
41
+
42
+        case LIB_INIT_PROMISE_CREATED:
43
+            return {
44
+                ...state,
45
+                initPromise: action.initPromise
38
             };
46
             };
39
 
47
 
40
         case SET_WEBRTC_READY:
48
         case SET_WEBRTC_READY:

+ 5
- 1
react/features/base/logging/middleware.js View File

114
  * specified {@code action}.
114
  * specified {@code action}.
115
  */
115
  */
116
 function _libWillInit({ getState }, next, action) {
116
 function _libWillInit({ getState }, next, action) {
117
-    _setLogLevels(JitsiMeetJS, getState()['features/base/logging'].config);
117
+    // Adding the if in order to preserve the logic for web after enabling
118
+    // LIB_WILL_INIT action for web in initLib action.
119
+    if (typeof APP === 'undefined') {
120
+        _setLogLevels(JitsiMeetJS, getState()['features/base/logging'].config);
121
+    }
118
 
122
 
119
     return next(action);
123
     return next(action);
120
 }
124
 }

+ 10
- 0
react/features/deep-linking/components/DeepLinkingDesktopPage.js View File

5
 import React, { Component } from 'react';
5
 import React, { Component } from 'react';
6
 import { connect } from 'react-redux';
6
 import { connect } from 'react-redux';
7
 
7
 
8
+import { createDeepLinkingPageEvent, sendAnalytics } from '../../analytics';
8
 import { translate } from '../../base/i18n';
9
 import { translate } from '../../base/i18n';
9
 
10
 
10
 import {
11
 import {
60
      */
61
      */
61
     componentDidMount() {
62
     componentDidMount() {
62
         this._openDesktopApp();
63
         this._openDesktopApp();
64
+        sendAnalytics(
65
+            createDeepLinkingPageEvent(
66
+                'displayed', 'DeepLinkingDesktop', { isMobileBrowser: false }));
63
     }
67
     }
64
 
68
 
65
     /**
69
     /**
147
      * @returns {void}
151
      * @returns {void}
148
      */
152
      */
149
     _onTryAgain() {
153
     _onTryAgain() {
154
+        sendAnalytics(
155
+            createDeepLinkingPageEvent(
156
+                'clicked', 'tryAgainButton', { isMobileBrowser: false }));
150
         this._openDesktopApp();
157
         this._openDesktopApp();
151
     }
158
     }
152
 
159
 
158
      * @returns {void}
165
      * @returns {void}
159
      */
166
      */
160
     _onLaunchWeb() {
167
     _onLaunchWeb() {
168
+        sendAnalytics(
169
+            createDeepLinkingPageEvent(
170
+                'clicked', 'launchWebButton', { isMobileBrowser: false }));
161
         this.props.dispatch(openWebApp());
171
         this.props.dispatch(openWebApp());
162
     }
172
     }
163
 }
173
 }

+ 57
- 2
react/features/deep-linking/components/DeepLinkingMobilePage.js View File

4
 import React, { Component } from 'react';
4
 import React, { Component } from 'react';
5
 import { connect } from 'react-redux';
5
 import { connect } from 'react-redux';
6
 
6
 
7
+import { createDeepLinkingPageEvent, sendAnalytics } from '../../analytics';
7
 import { translate, translateToHTML } from '../../base/i18n';
8
 import { translate, translateToHTML } from '../../base/i18n';
8
 import { HideNotificationBarStyle, Platform } from '../../base/react';
9
 import { HideNotificationBarStyle, Platform } from '../../base/react';
9
 import { DialInSummary } from '../../invite';
10
 import { DialInSummary } from '../../invite';
63
         t: PropTypes.func
64
         t: PropTypes.func
64
     };
65
     };
65
 
66
 
67
+    /**
68
+     * Initializes a new {@code DeepLinkingMobilePage} instance.
69
+     *
70
+     * @param {Object} props - The read-only React {@code Component} props with
71
+     * which the new instance is to be initialized.
72
+     */
73
+    constructor(props) {
74
+        super(props);
75
+
76
+        // Bind event handlers so they are only bound once per instance.
77
+        this._onDownloadApp = this._onDownloadApp.bind(this);
78
+        this._onOpenApp = this._onOpenApp.bind(this);
79
+    }
80
+
66
     /**
81
     /**
67
      * Initializes the text and URL of the `Start a conference` / `Join the
82
      * Initializes the text and URL of the `Start a conference` / `Join the
68
      * conversation` button which takes the user to the mobile app.
83
      * conversation` button which takes the user to the mobile app.
75
         });
90
         });
76
     }
91
     }
77
 
92
 
93
+    /**
94
+     * Implements the Component's componentDidMount method.
95
+     *
96
+     * @inheritdoc
97
+     */
98
+    componentDidMount() {
99
+        sendAnalytics(
100
+            createDeepLinkingPageEvent(
101
+                'displayed', 'DeepLinkingMobile', { isMobileBrowser: true }));
102
+    }
103
+
78
     /**
104
     /**
79
      * Implements React's {@link Component#render()}.
105
      * Implements React's {@link Component#render()}.
80
      *
106
      *
110
                                 { app: NATIVE_APP_NAME })
136
                                 { app: NATIVE_APP_NAME })
111
                         }
137
                         }
112
                     </p>
138
                     </p>
113
-                    <a href = { _URLS[Platform.OS] }>
139
+                    <a
140
+                        href = { _URLS[Platform.OS] }
141
+                        onClick = { this._onDownloadApp } >
114
                         <button className = { downloadButtonClassName }>
142
                         <button className = { downloadButtonClassName }>
115
                             { t(`${_TNS}.downloadApp`) }
143
                             { t(`${_TNS}.downloadApp`) }
116
                         </button>
144
                         </button>
117
                     </a>
145
                     </a>
118
                     <a
146
                     <a
119
                         className = { `${_SNS}__href` }
147
                         className = { `${_SNS}__href` }
120
-                        href = { this.state.joinURL }>
148
+                        href = { this.state.joinURL }
149
+                        onClick = { this._onOpenApp }>
121
                         {/* <button className = { `${_SNS}__button` }> */}
150
                         {/* <button className = { `${_SNS}__button` }> */}
122
                         { t(`${_TNS}.openApp`) }
151
                         { t(`${_TNS}.openApp`) }
123
                         {/* </button> */}
152
                         {/* </button> */}
131
             </div>
160
             </div>
132
         );
161
         );
133
     }
162
     }
163
+
164
+    _onDownloadApp: () => {};
165
+
166
+    /**
167
+     * Handles download app button clicks.
168
+     *
169
+     * @returns {void}
170
+     */
171
+    _onDownloadApp() {
172
+        sendAnalytics(
173
+            createDeepLinkingPageEvent(
174
+                'clicked', 'downloadAppButton', { isMobileBrowser: true }));
175
+    }
176
+
177
+    _onOpenApp: () => {};
178
+
179
+    /**
180
+     * Handles open app button clicks.
181
+     *
182
+     * @returns {void}
183
+     */
184
+    _onOpenApp() {
185
+        sendAnalytics(
186
+            createDeepLinkingPageEvent(
187
+                'clicked', 'openAppButton', { isMobileBrowser: true }));
188
+    }
134
 }
189
 }
135
 
190
 
136
 /**
191
 /**

+ 12
- 0
react/features/deep-linking/components/NoMobileApp.js View File

2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 
4
 
5
+import { createDeepLinkingPageEvent, sendAnalytics } from '../../analytics';
5
 import { HideNotificationBarStyle } from '../../base/react';
6
 import { HideNotificationBarStyle } from '../../base/react';
6
 
7
 
7
 declare var interfaceConfig: Object;
8
 declare var interfaceConfig: Object;
12
  * @class NoMobileApp
13
  * @class NoMobileApp
13
  */
14
  */
14
 export default class NoMobileApp extends Component<*> {
15
 export default class NoMobileApp extends Component<*> {
16
+    /**
17
+     * Implements the Component's componentDidMount method.
18
+     *
19
+     * @inheritdoc
20
+     */
21
+    componentDidMount() {
22
+        sendAnalytics(
23
+            createDeepLinkingPageEvent(
24
+                'displayed', 'noMobileApp', { isMobileBrowser: true }));
25
+    }
26
+
15
     /**
27
     /**
16
      * Renders the component.
28
      * Renders the component.
17
      *
29
      *

+ 1
- 14
react/features/welcome/components/WelcomePage.web.js View File

1
-/* global APP, config, interfaceConfig, JitsiMeetJS */
1
+/* global interfaceConfig */
2
 
2
 
3
 import Button from '@atlaskit/button';
3
 import Button from '@atlaskit/button';
4
 import { FieldTextStateless } from '@atlaskit/field-text';
4
 import { FieldTextStateless } from '@atlaskit/field-text';
6
 import React from 'react';
6
 import React from 'react';
7
 import { connect } from 'react-redux';
7
 import { connect } from 'react-redux';
8
 
8
 
9
-import { initAnalytics } from '../../analytics';
10
 import { translate } from '../../base/i18n';
9
 import { translate } from '../../base/i18n';
11
-import { isAnalyticsEnabled } from '../../base/lib-jitsi-meet';
12
 import { HideNotificationBarStyle, Watermarks } from '../../base/react';
10
 import { HideNotificationBarStyle, Watermarks } from '../../base/react';
13
 
11
 
14
 import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
12
 import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
71
     componentDidMount() {
69
     componentDidMount() {
72
         document.body.classList.add('welcome-page');
70
         document.body.classList.add('welcome-page');
73
 
71
 
74
-        // FIXME: This is not the best place for this logic. Ideally we should
75
-        // use features/base/lib-jitsi-meet#initLib() action for this use case.
76
-        // But currently lib-jitsi-meet#initLib()'s logic works for mobile only
77
-        // (on web it ends up with infinite loop over initLib).
78
-        JitsiMeetJS.init({
79
-            enableAnalyticsLogging: isAnalyticsEnabled(APP.store),
80
-            ...config
81
-        }).then(() => {
82
-            initAnalytics(APP.store);
83
-        });
84
-
85
         if (this.state.generateRoomnames) {
72
         if (this.state.generateRoomnames) {
86
             this._updateRoomname();
73
             this._updateRoomname();
87
         }
74
         }

Loading…
Cancel
Save