浏览代码

Uses analytics from lib-jitsi-meet and adds new events.

Adds more analytics events for shortcuts, recording and shared video. Changes the way we calculate ttfm.
j8
damencho 8 年前
父节点
当前提交
6302e42229

+ 4
- 1
analytics.js 查看文件

11
   }
11
   }
12
 
12
 
13
   Analytics.prototype.sendEvent = function (action, data) {
13
   Analytics.prototype.sendEvent = function (action, data) {
14
-    ga('send', 'event', 'jit.si', action);
14
+    // empty label and add the value, the value should be integer or null
15
+    var value = parseInt(data);
16
+
17
+    ga('send', 'event', 'jit.si', action, "", value ? value : null);
15
   };
18
   };
16
 
19
 
17
   ctx.Analytics = Analytics;
20
   ctx.Analytics = Analytics;

+ 16
- 3
modules/UI/recording/Recording.js 查看文件

20
 import Feedback from '../Feedback.js';
20
 import Feedback from '../Feedback.js';
21
 import Toolbar from '../toolbars/Toolbar';
21
 import Toolbar from '../toolbars/Toolbar';
22
 import BottomToolbar from '../toolbars/BottomToolbar';
22
 import BottomToolbar from '../toolbars/BottomToolbar';
23
+import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
23
 
24
 
24
 /**
25
 /**
25
  * The dialog for user input.
26
  * The dialog for user input.
306
         selector.click(function () {
307
         selector.click(function () {
307
             if (dialog)
308
             if (dialog)
308
                 return;
309
                 return;
309
-
310
+            AnalyticsAdapter.sendEvent('recording.clicked');
310
             switch (self.currentState) {
311
             switch (self.currentState) {
311
                 case Status.ON:
312
                 case Status.ON:
312
                 case Status.RETRYING:
313
                 case Status.RETRYING:
313
                 case Status.PENDING: {
314
                 case Status.PENDING: {
314
-                    _showStopRecordingPrompt(recordingType).then(() =>
315
-                        self.eventEmitter.emit(UIEvents.RECORDING_TOGGLED),
315
+                    _showStopRecordingPrompt(recordingType).then(
316
+                        () => {
317
+                            self.eventEmitter.emit(UIEvents.RECORDING_TOGGLED);
318
+                            AnalyticsAdapter.sendEvent('recording.stopped');
319
+                        },
316
                         () => {});
320
                         () => {});
317
                     break;
321
                     break;
318
                 }
322
                 }
322
                         _requestLiveStreamId().then((streamId) => {
326
                         _requestLiveStreamId().then((streamId) => {
323
                             self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
327
                             self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
324
                                 {streamId: streamId});
328
                                 {streamId: streamId});
329
+                            AnalyticsAdapter.sendEvent('recording.started');
325
                         }).catch(
330
                         }).catch(
326
                             reason => {
331
                             reason => {
327
                                 if (reason !== APP.UI.messageHandler.CANCEL)
332
                                 if (reason !== APP.UI.messageHandler.CANCEL)
328
                                     console.error(reason);
333
                                     console.error(reason);
334
+                                else
335
+                                    AnalyticsAdapter.sendEvent(
336
+                                        'recording.canceled');
329
                             }
337
                             }
330
                         );
338
                         );
331
                     else {
339
                     else {
332
                         if (self.predefinedToken) {
340
                         if (self.predefinedToken) {
333
                             self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
341
                             self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
334
                                 {token: self.predefinedToken});
342
                                 {token: self.predefinedToken});
343
+                            AnalyticsAdapter.sendEvent('recording.started');
335
                             return;
344
                             return;
336
                         }
345
                         }
337
 
346
 
338
                         _requestRecordingToken().then((token) => {
347
                         _requestRecordingToken().then((token) => {
339
                             self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
348
                             self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
340
                                 {token: token});
349
                                 {token: token});
350
+                            AnalyticsAdapter.sendEvent('recording.started');
341
                         }).catch(
351
                         }).catch(
342
                             reason => {
352
                             reason => {
343
                                 if (reason !== APP.UI.messageHandler.CANCEL)
353
                                 if (reason !== APP.UI.messageHandler.CANCEL)
344
                                     console.error(reason);
354
                                     console.error(reason);
355
+                                else
356
+                                    AnalyticsAdapter.sendEvent(
357
+                                        'recording.canceled');
345
                             }
358
                             }
346
                         );
359
                         );
347
                     }
360
                     }

+ 18
- 6
modules/UI/shared_video/SharedVideo.js 查看文件

8
 import SmallVideo from '../videolayout/SmallVideo';
8
 import SmallVideo from '../videolayout/SmallVideo';
9
 import FilmStrip from '../videolayout/FilmStrip';
9
 import FilmStrip from '../videolayout/FilmStrip';
10
 import ToolbarToggler from "../toolbars/ToolbarToggler";
10
 import ToolbarToggler from "../toolbars/ToolbarToggler";
11
+import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
11
 
12
 
12
 export const SHARED_VIDEO_CONTAINER_TYPE = "sharedvideo";
13
 export const SHARED_VIDEO_CONTAINER_TYPE = "sharedvideo";
13
 
14
 
68
 
69
 
69
         if(!this.isSharedVideoShown) {
70
         if(!this.isSharedVideoShown) {
70
             requestVideoLink().then(
71
             requestVideoLink().then(
71
-                    url => this.emitter.emit(
72
-                                UIEvents.UPDATE_SHARED_VIDEO, url, 'start'),
73
-                    err => console.log('SHARED VIDEO CANCELED', err)
72
+                    url => {
73
+                        this.emitter.emit(
74
+                            UIEvents.UPDATE_SHARED_VIDEO, url, 'start');
75
+                        AnalyticsAdapter.sendEvent('sharedvideo.started');
76
+                    },
77
+                    err => {
78
+                        console.log('SHARED VIDEO CANCELED', err);
79
+                        AnalyticsAdapter.sendEvent('sharedvideo.canceled');
80
+                    }
74
             );
81
             );
75
             return;
82
             return;
76
         }
83
         }
77
 
84
 
78
         if(APP.conference.isLocalId(this.from)) {
85
         if(APP.conference.isLocalId(this.from)) {
79
-            showStopVideoPropmpt().then(() =>
80
-                this.emitter.emit(
81
-                    UIEvents.UPDATE_SHARED_VIDEO, this.url, 'stop'),
86
+            showStopVideoPropmpt().then(() => {
87
+                    this.emitter.emit(
88
+                        UIEvents.UPDATE_SHARED_VIDEO, this.url, 'stop');
89
+                    AnalyticsAdapter.sendEvent('sharedvideo.stoped');
90
+                },
82
                 () => {});
91
                 () => {});
83
         } else {
92
         } else {
84
             dialog = APP.UI.messageHandler.openMessageDialog(
93
             dialog = APP.UI.messageHandler.openMessageDialog(
89
                     dialog = null;
98
                     dialog = null;
90
                 }
99
                 }
91
             );
100
             );
101
+            AnalyticsAdapter.sendEvent('sharedvideo.alreadyshared');
92
         }
102
         }
93
     }
103
     }
94
 
104
 
192
                 self.smartAudioMute();
202
                 self.smartAudioMute();
193
             } else if (event.data == YT.PlayerState.PAUSED) {
203
             } else if (event.data == YT.PlayerState.PAUSED) {
194
                 self.smartAudioUnmute();
204
                 self.smartAudioUnmute();
205
+                AnalyticsAdapter.sendEvent('sharedvideo.paused');
195
             }
206
             }
196
             self.fireSharedVideoEvent(event.data == YT.PlayerState.PAUSED);
207
             self.fireSharedVideoEvent(event.data == YT.PlayerState.PAUSED);
197
         };
208
         };
221
             else if (event.data.volume <=0 || event.data.muted) {
232
             else if (event.data.volume <=0 || event.data.muted) {
222
                 self.smartAudioUnmute();
233
                 self.smartAudioUnmute();
223
             }
234
             }
235
+            AnalyticsAdapter.sendEvent('sharedvideo.volumechanged');
224
         };
236
         };
225
 
237
 
226
         window.onPlayerReady = function(event) {
238
         window.onPlayerReady = function(event) {

+ 1
- 0
modules/UI/toolbars/Toolbar.js 查看文件

82
         }
82
         }
83
     },
83
     },
84
     "toolbar_button_security": function () {
84
     "toolbar_button_security": function () {
85
+        AnalyticsAdapter.sendEvent('toolbar.lock.clicked');
85
         emitter.emit(UIEvents.ROOM_LOCK_CLICKED);
86
         emitter.emit(UIEvents.ROOM_LOCK_CLICKED);
86
     },
87
     },
87
     "toolbar_button_link": function () {
88
     "toolbar_button_link": function () {

+ 1
- 1
modules/UI/videolayout/SmallVideo.js 查看文件

173
         // the rest participants. It subtracts the period of waiting for the
173
         // the rest participants. It subtracts the period of waiting for the
174
         // second participant to join (time between join and first
174
         // second participant to join (time between join and first
175
         // session initiate).
175
         // session initiate).
176
-        var ttfm = now - APP.connectionTimes["document.ready"]
176
+        var ttfm = now
177
             - (APP.conference.getConnectionTimes()["session.initiate"]
177
             - (APP.conference.getConnectionTimes()["session.initiate"]
178
                 - APP.conference.getConnectionTimes()["muc.joined"]);
178
                 - APP.conference.getConnectionTimes()["muc.joined"]);
179
         console.log("(TIME) TTFM " + type + ":\t", ttfm);
179
         console.log("(TIME) TTFM " + type + ":\t", ttfm);

+ 9
- 0
modules/keyboardshortcut/keyboardshortcut.js 查看文件

1
 /* global APP, $ */
1
 /* global APP, $ */
2
+import AnalyticsAdapter from '../statistics/AnalyticsAdapter';
2
 //maps keycode to character, id of popover for given function and function
3
 //maps keycode to character, id of popover for given function and function
3
 var shortcuts = {};
4
 var shortcuts = {};
4
 function initShortcutHandlers() {
5
 function initShortcutHandlers() {
13
             character: "C",
14
             character: "C",
14
             id: "toggleChatPopover",
15
             id: "toggleChatPopover",
15
             function: function() {
16
             function: function() {
17
+                AnalyticsAdapter.sendEvent('shortcut.chat.toggled');
16
                 APP.UI.toggleChat();
18
                 APP.UI.toggleChat();
17
             }
19
             }
18
         },
20
         },
20
             character: "D",
22
             character: "D",
21
             id: "toggleDesktopSharingPopover",
23
             id: "toggleDesktopSharingPopover",
22
             function: function () {
24
             function: function () {
25
+                AnalyticsAdapter.sendEvent('shortcut.screen.toggled');
23
                 APP.conference.toggleScreenSharing();
26
                 APP.conference.toggleScreenSharing();
24
             }
27
             }
25
         },
28
         },
27
             character: "F",
30
             character: "F",
28
             id: "filmstripPopover",
31
             id: "filmstripPopover",
29
             function: function() {
32
             function: function() {
33
+                AnalyticsAdapter.sendEvent('shortcut.film.toggled');
30
                 APP.UI.toggleFilmStrip();
34
                 APP.UI.toggleFilmStrip();
31
             }
35
             }
32
         },
36
         },
34
             character: "M",
38
             character: "M",
35
             id: "mutePopover",
39
             id: "mutePopover",
36
             function: function() {
40
             function: function() {
41
+                AnalyticsAdapter.sendEvent('shortcut.audiomute.toggled');
37
                 APP.conference.toggleAudioMuted();
42
                 APP.conference.toggleAudioMuted();
38
             }
43
             }
39
         },
44
         },
40
         "R": {
45
         "R": {
41
             character: "R",
46
             character: "R",
42
             function: function() {
47
             function: function() {
48
+                AnalyticsAdapter.sendEvent('shortcut.raisedhand.toggled');
43
                 APP.conference.maybeToggleRaisedHand();
49
                 APP.conference.maybeToggleRaisedHand();
44
             }
50
             }
45
 
51
 
47
         "T": {
53
         "T": {
48
             character: "T",
54
             character: "T",
49
             function: function() {
55
             function: function() {
56
+                AnalyticsAdapter.sendEvent('shortcut.talk.clicked');
50
                 APP.conference.muteAudio(true);
57
                 APP.conference.muteAudio(true);
51
             }
58
             }
52
         },
59
         },
54
             character: "V",
61
             character: "V",
55
             id: "toggleVideoPopover",
62
             id: "toggleVideoPopover",
56
             function: function() {
63
             function: function() {
64
+                AnalyticsAdapter.sendEvent('shortcut.videomute.toggled');
57
                 APP.conference.toggleVideoMuted();
65
                 APP.conference.toggleVideoMuted();
58
             }
66
             }
59
         },
67
         },
60
         "?": {
68
         "?": {
61
             character: "?",
69
             character: "?",
62
             function: function(e) {
70
             function: function(e) {
71
+                AnalyticsAdapter.sendEvent('shortcut.shortcut.help');
63
                 APP.UI.toggleKeyboardShortcutsPanel();
72
                 APP.UI.toggleKeyboardShortcutsPanel();
64
             }
73
             }
65
         }
74
         }

+ 1
- 29
modules/statistics/AnalyticsAdapter.js 查看文件

15
             /* prepend */ false);
15
             /* prepend */ false);
16
 }
16
 }
17
 
17
 
18
-class NoopAnalytics {
19
-    sendEvent () {}
20
-}
21
-
22
-// XXX Since we asynchronously load the integration of the analytics API and the
23
-// analytics API may asynchronously load its implementation (e.g. Google
24
-// Analytics), we cannot make the decision with respect to which analytics
25
-// implementation we will use here and we have to postpone it i.e. we will make
26
-// a lazy decision.
27
-
28
-class AnalyticsAdapter {
29
-    constructor () {
30
-    }
31
-
32
-    sendEvent (...args) {
33
-        var a = this.analytics;
34
-
35
-        if (a === null || typeof a === 'undefined') {
36
-            var AnalyticsImpl = window.Analytics || NoopAnalytics;
37
-
38
-            this.analytics = a = new AnalyticsImpl();
39
-        }
40
-        try {
41
-            a.sendEvent(...args);
42
-        } catch (ignored) {}
43
-    }
44
-}
45
-
46
-export default new AnalyticsAdapter();
18
+export default JitsiMeetJS.analytics;

正在加载...
取消
保存