mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-20 14:55:15 +03:00
Added Google analytics collection.
This commit is contained in:
parent
5b0a6349a7
commit
8d5d81f9cf
10 changed files with 277 additions and 4 deletions
64
src/js/Analytics.js
Normal file
64
src/js/Analytics.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
'use strict';
|
||||
|
||||
var Analytics = function (serviceName, trackingId, operatingSystem) {
|
||||
this.eventBuilder = analytics.EventBuilder;
|
||||
this.service = analytics.getService(serviceName);
|
||||
this.tracker = this.service.getTracker(trackingId);
|
||||
|
||||
this.DATA = {
|
||||
BOARD_TYPE: 'boardType',
|
||||
FIRMWARE_TYPE: 'firmwareType',
|
||||
FIRMWARE_VERSION: 'firmwareVersion',
|
||||
API_VERSION: 'apiVersion',
|
||||
MCU_ID: 'mcuId',
|
||||
};
|
||||
|
||||
this.DIMENSIONS = {
|
||||
OS: 1,
|
||||
BOARD_TYPE: 2,
|
||||
FIRMWARE_TYPE: 3,
|
||||
FIRMWARE_VERSION: 4,
|
||||
API_VERSION: 5,
|
||||
};
|
||||
|
||||
this.APPLICATION_EVENT = this.eventBuilder.builder()
|
||||
.category('Application')
|
||||
.dimension(this.DIMENSIONS.OS, operatingSystem);
|
||||
|
||||
this.resetFlightControllerData();
|
||||
};
|
||||
|
||||
Analytics.prototype.setTrackingPermitted = function (permitted) {
|
||||
this.service.getConfig().addCallback(function(config) {
|
||||
config.setTrackingPermitted(permitted);
|
||||
});
|
||||
}
|
||||
|
||||
Analytics.prototype.send = function (event) {
|
||||
this.tracker.send(event);
|
||||
}
|
||||
|
||||
Analytics.prototype.sendAppView = function (viewName) {
|
||||
this.tracker.sendAppView(viewName);
|
||||
}
|
||||
|
||||
Analytics.prototype.rebuildFlightControllerEvent = function () {
|
||||
this.FLIGHT_CONTROLLER_EVENT = this.eventBuilder.builder()
|
||||
.category('FlightController')
|
||||
.dimension(this.DIMENSIONS.BOARD_TYPE, this.flightControllerData[this.DATA.BOARD_TYPE])
|
||||
.dimension(this.DIMENSIONS.FIRMWARE_TYPE, this.flightControllerData[this.DATA.FIRMWARE_TYPE])
|
||||
.dimension(this.DIMENSIONS.FIRMWARE_VERSION, this.flightControllerData[this.DATA.FIRMWARE_VERSION])
|
||||
.dimension(this.DIMENSIONS.API_VERSION, this.flightControllerData[this.DATA.API_VERSION]);
|
||||
}
|
||||
|
||||
Analytics.prototype.setFlightControllerData = function (property, value) {
|
||||
this.flightControllerData[property] = value;
|
||||
|
||||
this.rebuildFlightControllerEvent();
|
||||
}
|
||||
|
||||
Analytics.prototype.resetFlightControllerData = function () {
|
||||
this.flightControllerData = {};
|
||||
|
||||
this.rebuildFlightControllerEvent();
|
||||
}
|
|
@ -1,19 +1,60 @@
|
|||
'use strict';
|
||||
|
||||
var analytics;
|
||||
|
||||
openNewWindowsInExternalBrowser();
|
||||
|
||||
//Asynchronous configuration to be done.
|
||||
//When finish the startProcess() function must be called
|
||||
$(document).ready(function () {
|
||||
i18n.init(function() {
|
||||
startProcess();
|
||||
setupAnalytics();
|
||||
initializeSerialBackend();
|
||||
});
|
||||
});
|
||||
|
||||
function setupAnalytics() {
|
||||
analytics = new Analytics('com.betaflight.configurator', 'UA-123002063-1', GUI.operating_system);
|
||||
chrome.storage.local.get('userId', function (result) {
|
||||
var userId;
|
||||
if (result.userId) {
|
||||
userId = result.userId;
|
||||
} else {
|
||||
var uid = new ShortUniqueId();
|
||||
userId = uid.randomUUID(13);
|
||||
|
||||
chrome.storage.local.set({'userId': userId});
|
||||
}
|
||||
|
||||
analytics.tracker.set('userId', userId);
|
||||
|
||||
analytics.tracker.set('sessionControl', 'start');
|
||||
analytics.send(analytics.APPLICATION_EVENT.action('AppStart'))
|
||||
|
||||
function sendCloseEvent() {
|
||||
analytics.send(analytics.APPLICATION_EVENT.action('AppClose'))
|
||||
analytics.tracker.set('sessionControl', 'end');
|
||||
}
|
||||
|
||||
try {
|
||||
var gui = require('nw.gui');
|
||||
var win = gui.Window.get();
|
||||
win.on('close', function () {
|
||||
sendCloseEvent();
|
||||
|
||||
this.close(true);
|
||||
});
|
||||
} catch (ex) {
|
||||
// Looks like we're in Chrome - but the event does not actually get fired
|
||||
chrome.runtime.onSuspend.addListener(sendCloseEvent);
|
||||
}
|
||||
|
||||
startProcess();
|
||||
});
|
||||
}
|
||||
|
||||
//Process to execute to real start the app
|
||||
function startProcess() {
|
||||
|
||||
// translate to user-selected language
|
||||
i18n.localizePage();
|
||||
|
||||
|
@ -113,6 +154,8 @@ function startProcess() {
|
|||
GUI.tab_switch_in_progress = false;
|
||||
}
|
||||
|
||||
analytics.sendAppView(tab);
|
||||
|
||||
switch (tab) {
|
||||
case 'landing':
|
||||
TABS.landing.initialize(content_ready);
|
||||
|
@ -249,6 +292,28 @@ function startProcess() {
|
|||
$('div.checkForConfiguratorUnstableVersions').hide();
|
||||
}
|
||||
|
||||
chrome.storage.local.get('analyticsOptOut', function (result) {
|
||||
if (result.analyticsOptOut) {
|
||||
$('div.analyticsOptOut input').prop('checked', true);
|
||||
}
|
||||
|
||||
$('div.analyticsOptOut input').change(function () {
|
||||
var checked = $(this).is(':checked');
|
||||
|
||||
chrome.storage.local.set({'analyticsOptOut': checked});
|
||||
|
||||
if (checked) {
|
||||
analytics.send(analytics.APPLICATION_EVENT.action('OptOut'));
|
||||
}
|
||||
|
||||
analytics.setTrackingPermitted(!checked);
|
||||
|
||||
if (!checked) {
|
||||
analytics.send(analytics.APPLICATION_EVENT.action('OptIn'));
|
||||
}
|
||||
}).change();
|
||||
});
|
||||
|
||||
chrome.storage.local.get('userLanguageSelect', function (result) {
|
||||
|
||||
var userLanguage_e = $('div.userLanguage select');
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
'use strict';
|
||||
var mspHelper;
|
||||
|
||||
var analyticsTimer;
|
||||
|
||||
function initializeSerialBackend() {
|
||||
|
||||
GUI.updateManualPortVisibility = function(){
|
||||
|
@ -124,6 +126,14 @@ function initializeSerialBackend() {
|
|||
function finishClose(finishedCallback) {
|
||||
var wasConnected = CONFIGURATOR.connectionValid;
|
||||
|
||||
analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('Disconnected'));
|
||||
if (analyticsTimer) {
|
||||
analyticsTimer.send();
|
||||
|
||||
analyticsTimer = undefined;
|
||||
}
|
||||
analytics.resetFlightControllerData();
|
||||
|
||||
serial.disconnect(onClosed);
|
||||
|
||||
MSP.disconnect_cleanup();
|
||||
|
@ -200,13 +210,17 @@ function onOpen(openInfo) {
|
|||
|
||||
// request configuration data
|
||||
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, function () {
|
||||
analytics.setFlightControllerData(analytics.DATA.API_VERSION, CONFIG.apiVersion);
|
||||
|
||||
GUI.log(i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion]));
|
||||
|
||||
if (semver.gte(CONFIG.apiVersion, CONFIGURATOR.apiVersionAccepted)) {
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_FC_VARIANT, false, false, function () {
|
||||
analytics.setFlightControllerData(analytics.DATA.FIRMWARE_TYPE, CONFIG.flightControllerIdentifier);
|
||||
if (CONFIG.flightControllerIdentifier === 'BTFL') {
|
||||
MSP.send_message(MSPCodes.MSP_FC_VERSION, false, false, function () {
|
||||
analytics.setFlightControllerData(analytics.DATA.FIRMWARE_VERSION, CONFIG.flightControllerVersion);
|
||||
|
||||
GUI.log(i18n.getMessage('fcInfoReceived', [CONFIG.flightControllerIdentifier, CONFIG.flightControllerVersion]));
|
||||
updateStatusBarVersion(CONFIG.flightControllerVersion, CONFIG.flightControllerIdentifier);
|
||||
|
@ -217,13 +231,19 @@ function onOpen(openInfo) {
|
|||
GUI.log(i18n.getMessage('buildInfoReceived', [CONFIG.buildInfo]));
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_BOARD_INFO, false, false, function () {
|
||||
analytics.setFlightControllerData(analytics.DATA.BOARD_TYPE, CONFIG.boardIdentifier);
|
||||
|
||||
GUI.log(i18n.getMessage('boardInfoReceived', [CONFIG.boardIdentifier, CONFIG.boardVersion]));
|
||||
updateStatusBarVersion(CONFIG.flightControllerVersion, CONFIG.flightControllerIdentifier, CONFIG.boardIdentifier);
|
||||
updateTopBarVersion(CONFIG.flightControllerVersion, CONFIG.flightControllerIdentifier, CONFIG.boardIdentifier);
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_UID, false, false, function () {
|
||||
GUI.log(i18n.getMessage('uniqueDeviceIdReceived', [CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16)]));
|
||||
var uniqueDeviceIdentifier = CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16);
|
||||
|
||||
analytics.setFlightControllerData(analytics.DATA.MCU_ID, objectHash.sha1(uniqueDeviceIdentifier));
|
||||
analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('Connected'));
|
||||
analyticsTimer = analytics.tracker.startTiming('FlightController', 'Connected');
|
||||
GUI.log(i18n.getMessage('uniqueDeviceIdReceived', [uniqueDeviceIdentifier]));
|
||||
|
||||
if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_NAME, false, false, function () {
|
||||
|
@ -240,6 +260,8 @@ function onOpen(openInfo) {
|
|||
});
|
||||
});
|
||||
} else {
|
||||
analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('ConnectionRefused'));
|
||||
|
||||
var dialog = $('.dialogConnectWarning')[0];
|
||||
|
||||
$('.dialogConnectWarning-content').html(i18n.getMessage('firmwareTypeNotSupported'));
|
||||
|
@ -254,6 +276,8 @@ function onOpen(openInfo) {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('ConnectionRefused'));
|
||||
|
||||
var dialog = $('.dialogConnectWarning')[0];
|
||||
|
||||
$('.dialogConnectWarning-content').html(i18n.getMessage('firmwareVersionNotSupported', [CONFIGURATOR.apiVersionAccepted]));
|
||||
|
@ -268,6 +292,8 @@ function onOpen(openInfo) {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
analytics.send(analytics.APPLICATION_EVENT.action('SerialPortFailed'));
|
||||
|
||||
console.log('Failed to open serial port');
|
||||
GUI.log(i18n.getMessage('serialPortOpenFail'));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue