Merge pull request #774 from jitsi/analytics-move

Analytics move
This commit is contained in:
George Politis 2016-08-05 13:49:05 -05:00 committed by GitHub
commit 541f83cf71
7 changed files with 49 additions and 58 deletions

View File

@ -11,7 +11,10 @@
} }
Analytics.prototype.sendEvent = function (action, data) { Analytics.prototype.sendEvent = function (action, data) {
ga('send', 'event', 'jit.si', action); // empty label and add the value, the value should be integer or null
var value = parseInt(data);
ga('send', 'event', 'jit.si', action, "", value ? value : null);
}; };
ctx.Analytics = Analytics; ctx.Analytics = Analytics;

View File

@ -20,6 +20,7 @@ import VideoLayout from '../videolayout/VideoLayout';
import Feedback from '../Feedback.js'; import Feedback from '../Feedback.js';
import Toolbar from '../toolbars/Toolbar'; import Toolbar from '../toolbars/Toolbar';
import BottomToolbar from '../toolbars/BottomToolbar'; import BottomToolbar from '../toolbars/BottomToolbar';
import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
/** /**
* The dialog for user input. * The dialog for user input.
@ -306,13 +307,16 @@ var Recording = {
selector.click(function () { selector.click(function () {
if (dialog) if (dialog)
return; return;
AnalyticsAdapter.sendEvent('recording.clicked');
switch (self.currentState) { switch (self.currentState) {
case Status.ON: case Status.ON:
case Status.RETRYING: case Status.RETRYING:
case Status.PENDING: { case Status.PENDING: {
_showStopRecordingPrompt(recordingType).then(() => _showStopRecordingPrompt(recordingType).then(
self.eventEmitter.emit(UIEvents.RECORDING_TOGGLED), () => {
self.eventEmitter.emit(UIEvents.RECORDING_TOGGLED);
AnalyticsAdapter.sendEvent('recording.stopped');
},
() => {}); () => {});
break; break;
} }
@ -322,26 +326,35 @@ var Recording = {
_requestLiveStreamId().then((streamId) => { _requestLiveStreamId().then((streamId) => {
self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED, self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
{streamId: streamId}); {streamId: streamId});
AnalyticsAdapter.sendEvent('recording.started');
}).catch( }).catch(
reason => { reason => {
if (reason !== APP.UI.messageHandler.CANCEL) if (reason !== APP.UI.messageHandler.CANCEL)
console.error(reason); console.error(reason);
else
AnalyticsAdapter.sendEvent(
'recording.canceled');
} }
); );
else { else {
if (self.predefinedToken) { if (self.predefinedToken) {
self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED, self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
{token: self.predefinedToken}); {token: self.predefinedToken});
AnalyticsAdapter.sendEvent('recording.started');
return; return;
} }
_requestRecordingToken().then((token) => { _requestRecordingToken().then((token) => {
self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED, self.eventEmitter.emit( UIEvents.RECORDING_TOGGLED,
{token: token}); {token: token});
AnalyticsAdapter.sendEvent('recording.started');
}).catch( }).catch(
reason => { reason => {
if (reason !== APP.UI.messageHandler.CANCEL) if (reason !== APP.UI.messageHandler.CANCEL)
console.error(reason); console.error(reason);
else
AnalyticsAdapter.sendEvent(
'recording.canceled');
} }
); );
} }

View File

@ -8,6 +8,7 @@ import LargeContainer from '../videolayout/LargeContainer';
import SmallVideo from '../videolayout/SmallVideo'; import SmallVideo from '../videolayout/SmallVideo';
import FilmStrip from '../videolayout/FilmStrip'; import FilmStrip from '../videolayout/FilmStrip';
import ToolbarToggler from "../toolbars/ToolbarToggler"; import ToolbarToggler from "../toolbars/ToolbarToggler";
import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
export const SHARED_VIDEO_CONTAINER_TYPE = "sharedvideo"; export const SHARED_VIDEO_CONTAINER_TYPE = "sharedvideo";
@ -68,17 +69,25 @@ export default class SharedVideoManager {
if(!this.isSharedVideoShown) { if(!this.isSharedVideoShown) {
requestVideoLink().then( requestVideoLink().then(
url => this.emitter.emit( url => {
UIEvents.UPDATE_SHARED_VIDEO, url, 'start'), this.emitter.emit(
err => console.log('SHARED VIDEO CANCELED', err) UIEvents.UPDATE_SHARED_VIDEO, url, 'start');
AnalyticsAdapter.sendEvent('sharedvideo.started');
},
err => {
console.log('SHARED VIDEO CANCELED', err);
AnalyticsAdapter.sendEvent('sharedvideo.canceled');
}
); );
return; return;
} }
if(APP.conference.isLocalId(this.from)) { if(APP.conference.isLocalId(this.from)) {
showStopVideoPropmpt().then(() => showStopVideoPropmpt().then(() => {
this.emitter.emit( this.emitter.emit(
UIEvents.UPDATE_SHARED_VIDEO, this.url, 'stop'), UIEvents.UPDATE_SHARED_VIDEO, this.url, 'stop');
AnalyticsAdapter.sendEvent('sharedvideo.stoped');
},
() => {}); () => {});
} else { } else {
dialog = APP.UI.messageHandler.openMessageDialog( dialog = APP.UI.messageHandler.openMessageDialog(
@ -89,6 +98,7 @@ export default class SharedVideoManager {
dialog = null; dialog = null;
} }
); );
AnalyticsAdapter.sendEvent('sharedvideo.alreadyshared');
} }
} }
@ -192,6 +202,7 @@ export default class SharedVideoManager {
self.smartAudioMute(); self.smartAudioMute();
} else if (event.data == YT.PlayerState.PAUSED) { } else if (event.data == YT.PlayerState.PAUSED) {
self.smartAudioUnmute(); self.smartAudioUnmute();
AnalyticsAdapter.sendEvent('sharedvideo.paused');
} }
self.fireSharedVideoEvent(event.data == YT.PlayerState.PAUSED); self.fireSharedVideoEvent(event.data == YT.PlayerState.PAUSED);
}; };
@ -221,6 +232,7 @@ export default class SharedVideoManager {
else if (event.data.volume <=0 || event.data.muted) { else if (event.data.volume <=0 || event.data.muted) {
self.smartAudioUnmute(); self.smartAudioUnmute();
} }
AnalyticsAdapter.sendEvent('sharedvideo.volumechanged');
}; };
window.onPlayerReady = function(event) { window.onPlayerReady = function(event) {

View File

@ -82,6 +82,7 @@ const buttonHandlers = {
} }
}, },
"toolbar_button_security": function () { "toolbar_button_security": function () {
AnalyticsAdapter.sendEvent('toolbar.lock.clicked');
emitter.emit(UIEvents.ROOM_LOCK_CLICKED); emitter.emit(UIEvents.ROOM_LOCK_CLICKED);
}, },
"toolbar_button_link": function () { "toolbar_button_link": function () {

View File

@ -160,25 +160,6 @@ SmallVideo.createStreamElement = function (stream) {
element.id = SmallVideo.getStreamElementID(stream); element.id = SmallVideo.getStreamElementID(stream);
element.onplay = function () {
var type = (isVideo ? 'video' : 'audio');
var now = APP.connectionTimes[type + ".render"]
= window.performance.now();
console.log("(TIME) Render " + type + ":\t",
now);
AnalyticsAdapter.sendEvent('render.' + type, now);
// Time to first media, a number that can be used for comparision of
// time fot rendering media. It can be used for the first and
// the rest participants. It subtracts the period of waiting for the
// second participant to join (time between join and first
// session initiate).
var ttfm = now - APP.connectionTimes["document.ready"]
- (APP.conference.getConnectionTimes()["session.initiate"]
- APP.conference.getConnectionTimes()["muc.joined"]);
console.log("(TIME) TTFM " + type + ":\t", ttfm);
AnalyticsAdapter.sendEvent('ttfm.' + type, ttfm);
};
return element; return element;
}; };

View File

@ -1,4 +1,5 @@
/* global APP, $ */ /* global APP, $ */
import AnalyticsAdapter from '../statistics/AnalyticsAdapter';
//maps keycode to character, id of popover for given function and function //maps keycode to character, id of popover for given function and function
var shortcuts = {}; var shortcuts = {};
function initShortcutHandlers() { function initShortcutHandlers() {
@ -13,6 +14,7 @@ function initShortcutHandlers() {
character: "C", character: "C",
id: "toggleChatPopover", id: "toggleChatPopover",
function: function() { function: function() {
AnalyticsAdapter.sendEvent('shortcut.chat.toggled');
APP.UI.toggleChat(); APP.UI.toggleChat();
} }
}, },
@ -20,6 +22,7 @@ function initShortcutHandlers() {
character: "D", character: "D",
id: "toggleDesktopSharingPopover", id: "toggleDesktopSharingPopover",
function: function () { function: function () {
AnalyticsAdapter.sendEvent('shortcut.screen.toggled');
APP.conference.toggleScreenSharing(); APP.conference.toggleScreenSharing();
} }
}, },
@ -27,6 +30,7 @@ function initShortcutHandlers() {
character: "F", character: "F",
id: "filmstripPopover", id: "filmstripPopover",
function: function() { function: function() {
AnalyticsAdapter.sendEvent('shortcut.film.toggled');
APP.UI.toggleFilmStrip(); APP.UI.toggleFilmStrip();
} }
}, },
@ -34,12 +38,14 @@ function initShortcutHandlers() {
character: "M", character: "M",
id: "mutePopover", id: "mutePopover",
function: function() { function: function() {
AnalyticsAdapter.sendEvent('shortcut.audiomute.toggled');
APP.conference.toggleAudioMuted(); APP.conference.toggleAudioMuted();
} }
}, },
"R": { "R": {
character: "R", character: "R",
function: function() { function: function() {
AnalyticsAdapter.sendEvent('shortcut.raisedhand.toggled');
APP.conference.maybeToggleRaisedHand(); APP.conference.maybeToggleRaisedHand();
} }
@ -47,6 +53,7 @@ function initShortcutHandlers() {
"T": { "T": {
character: "T", character: "T",
function: function() { function: function() {
AnalyticsAdapter.sendEvent('shortcut.talk.clicked');
APP.conference.muteAudio(true); APP.conference.muteAudio(true);
} }
}, },
@ -54,12 +61,14 @@ function initShortcutHandlers() {
character: "V", character: "V",
id: "toggleVideoPopover", id: "toggleVideoPopover",
function: function() { function: function() {
AnalyticsAdapter.sendEvent('shortcut.videomute.toggled');
APP.conference.toggleVideoMuted(); APP.conference.toggleVideoMuted();
} }
}, },
"?": { "?": {
character: "?", character: "?",
function: function(e) { function: function(e) {
AnalyticsAdapter.sendEvent('shortcut.shortcut.help');
APP.UI.toggleKeyboardShortcutsPanel(); APP.UI.toggleKeyboardShortcutsPanel();
} }
} }

View File

@ -15,32 +15,4 @@ if (config.disableThirdPartyRequests !== true) {
/* prepend */ false); /* prepend */ false);
} }
class NoopAnalytics { export default JitsiMeetJS.analytics;
sendEvent () {}
}
// XXX Since we asynchronously load the integration of the analytics API and the
// analytics API may asynchronously load its implementation (e.g. Google
// Analytics), we cannot make the decision with respect to which analytics
// implementation we will use here and we have to postpone it i.e. we will make
// a lazy decision.
class AnalyticsAdapter {
constructor () {
}
sendEvent (...args) {
var a = this.analytics;
if (a === null || typeof a === 'undefined') {
var AnalyticsImpl = window.Analytics || NoopAnalytics;
this.analytics = a = new AnalyticsImpl();
}
try {
a.sendEvent(...args);
} catch (ignored) {}
}
}
export default new AnalyticsAdapter();