send/app/metrics.js

186 lines
4.3 KiB
JavaScript

import storage from './storage';
import { platform, locale } from './utils';
import { sendMetrics } from './api';
let appState = null;
let experiment = null;
const HOUR = 1000 * 60 * 60;
const events = [];
let session_id = Date.now();
const lang = locale();
export default function initialize(state, emitter) {
appState = state;
emitter.on('DOMContentLoaded', () => {
experiment = storage.enrolled;
if (!appState.user.firstAction) {
appState.user.firstAction =
appState.route === '/' ? 'upload' : 'download';
}
const query = appState.query;
addEvent('client_visit', {
entrypoint: appState.route === '/' ? 'upload' : 'download',
referrer: document.referrer,
utm_campaign: query.utm_campaign,
utm_content: query.utm_content,
utm_medium: query.utm_medium,
utm_source: query.utm_source,
utm_term: query.utm_term
});
});
emitter.on('experiment', experimentEvent);
window.addEventListener('unload', submitEvents);
}
function sizeOrder(n) {
return Math.floor(Math.log10(n));
}
function submitEvents() {
if (navigator.doNotTrack === '1') {
return;
}
sendMetrics(
new Blob(
[
JSON.stringify({
now: Date.now(),
session_id,
lang,
platform: platform(),
events
})
],
{ type: 'text/plain' } // see http://crbug.com/490015
)
);
events.splice(0);
}
async function addEvent(event_type, event_properties) {
const user_id = await appState.user.metricId();
const device_id = await appState.user.deviceId();
const ab_id = Object.keys(experiment)[0];
if (ab_id) {
event_properties.experiment = ab_id;
event_properties.variant = experiment[ab_id];
}
events.push({
device_id,
event_properties,
event_type,
time: Date.now(),
user_id,
user_properties: {
anonymous: !appState.user.loggedIn,
first_action: appState.user.firstAction,
active_count: storage.files.length
}
});
if (events.length === 25) {
submitEvents();
}
}
function cancelledUpload(archive, duration) {
return addEvent('client_upload', {
download_limit: archive.dlimit,
duration: sizeOrder(duration),
file_count: archive.numFiles,
password_protected: !!archive.password,
size: sizeOrder(archive.size),
status: 'cancel',
time_limit: archive.timeLimit
});
}
function completedUpload(archive, duration) {
return addEvent('client_upload', {
download_limit: archive.dlimit,
duration: sizeOrder(duration),
file_count: archive.numFiles,
password_protected: !!archive.password,
size: sizeOrder(archive.size),
status: 'ok',
time_limit: archive.timeLimit
});
}
function stoppedUpload(archive, duration = 0) {
return addEvent('client_upload', {
download_limit: archive.dlimit,
duration: sizeOrder(duration),
file_count: archive.numFiles,
password_protected: !!archive.password,
size: sizeOrder(archive.size),
status: 'error',
time_limit: archive.timeLimit
});
}
function stoppedDownload(params) {
return addEvent('client_download', {
duration: sizeOrder(params.duration),
password_protected: params.password_protected,
size: sizeOrder(params.size),
status: 'error'
});
}
function completedDownload(params) {
return addEvent('client_download', {
duration: sizeOrder(params.duration),
password_protected: params.password_protected,
size: sizeOrder(params.size),
status: 'ok'
});
}
function deletedUpload(ownedFile) {
return addEvent('client_delete', {
age: Math.floor((Date.now() - ownedFile.createdAt) / HOUR),
downloaded: ownedFile.dtotal > 0,
status: 'ok'
});
}
function experimentEvent(params) {
return addEvent('client_experiment', params);
}
function submittedSignup(params) {
return addEvent('client_login', {
status: 'ok',
trigger: params.trigger
});
}
function canceledSignup(params) {
return addEvent('client_login', {
status: 'cancel',
trigger: params.trigger
});
}
function loggedOut(params) {
addEvent('client_logout', {
status: 'ok',
trigger: params.trigger
});
// flush events and start new anon session
submitEvents();
session_id = Date.now();
}
export {
cancelledUpload,
stoppedUpload,
completedUpload,
deletedUpload,
stoppedDownload,
completedDownload,
submittedSignup,
canceledSignup,
loggedOut
};