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 };