mirror of
https://github.com/scratchfoundation/scratch-desktop.git
synced 2025-07-23 20:39:10 -04:00
120 lines
3.7 KiB
JavaScript
120 lines
3.7 KiB
JavaScript
import {app, ipcMain} from 'electron';
|
|
import defaultsDeep from 'lodash.defaultsdeep';
|
|
import {version} from '../../package.json';
|
|
|
|
import TelemetryClient from './telemetry/TelemetryClient';
|
|
|
|
const EVENT_TEMPLATE = {
|
|
version,
|
|
projectName: '',
|
|
language: '',
|
|
metadata: {
|
|
scriptCount: -1,
|
|
spriteCount: -1,
|
|
variablesCount: -1,
|
|
blocksCount: -1,
|
|
costumesCount: -1,
|
|
listsCount: -1,
|
|
soundsCount: -1
|
|
}
|
|
};
|
|
|
|
const APP_ID = 'scratch-desktop';
|
|
const APP_VERSION = app.getVersion();
|
|
const APP_INFO = Object.freeze({
|
|
projectName: `${APP_ID} ${APP_VERSION}`
|
|
});
|
|
|
|
class ScratchDesktopTelemetry {
|
|
constructor () {
|
|
this._telemetryClient = new TelemetryClient();
|
|
}
|
|
|
|
get didOptIn () {
|
|
return this._telemetryClient.didOptIn;
|
|
}
|
|
set didOptIn (value) {
|
|
this._telemetryClient.didOptIn = value;
|
|
}
|
|
clearDidOptIn () {
|
|
this._telemetryClient.clearDidOptIn();
|
|
}
|
|
|
|
appWasOpened () {
|
|
this._telemetryClient.addEvent('app::open', {...EVENT_TEMPLATE, ...APP_INFO});
|
|
}
|
|
|
|
appWillClose () {
|
|
this._telemetryClient.addEvent('app::close', {...EVENT_TEMPLATE, ...APP_INFO});
|
|
}
|
|
|
|
projectDidLoad (metadata = {}) {
|
|
this._telemetryClient.addEvent('project::load', this._buildMetadata(metadata));
|
|
}
|
|
|
|
projectDidSave (metadata = {}) {
|
|
// Since the save dialog appears on the main process the GUI does not wait for the actual save to complete.
|
|
// That means the GUI sends this event before we know the file name used for the save, which is where the new
|
|
// project title comes from. Instead, just hold on to this metadata pending a `projectSaveCompleted` event
|
|
// from the save code on the main process. If the user cancels the save this data will be cleared.
|
|
this._pendingProjectSave = metadata;
|
|
}
|
|
|
|
projectSaveCompleted (newProjectTitle) {
|
|
const metadata = this._pendingProjectSave;
|
|
this._pendingProjectSave = null;
|
|
|
|
metadata.projectName = newProjectTitle;
|
|
this._telemetryClient.addEvent('project::save', this._buildMetadata(metadata));
|
|
}
|
|
|
|
projectSaveCanceled () {
|
|
this._pendingProjectSave = null;
|
|
}
|
|
|
|
projectWasCreated (metadata = {}) {
|
|
this._telemetryClient.addEvent('project::create', this._buildMetadata(metadata));
|
|
}
|
|
|
|
projectWasUploaded (metadata = {}) {
|
|
this._telemetryClient.addEvent('project::upload', this._buildMetadata(metadata));
|
|
}
|
|
|
|
_buildMetadata (metadata) {
|
|
const {projectName, language, ...codeMetadata} = metadata;
|
|
return defaultsDeep({
|
|
projectName,
|
|
language,
|
|
metadata: codeMetadata
|
|
}, EVENT_TEMPLATE);
|
|
}
|
|
}
|
|
|
|
// make a singleton so it's easy to share across both Electron processes
|
|
const scratchDesktopTelemetrySingleton = new ScratchDesktopTelemetry();
|
|
|
|
// `handle` works with `invoke`
|
|
ipcMain.handle('getTelemetryDidOptIn', () =>
|
|
scratchDesktopTelemetrySingleton.didOptIn
|
|
);
|
|
// `on` works with `sendSync` (and `send`)
|
|
ipcMain.on('getTelemetryDidOptIn', event => {
|
|
event.returnValue = scratchDesktopTelemetrySingleton.didOptIn;
|
|
});
|
|
ipcMain.on('setTelemetryDidOptIn', (event, arg) => {
|
|
scratchDesktopTelemetrySingleton.didOptIn = arg;
|
|
});
|
|
ipcMain.on('projectDidLoad', (event, arg) => {
|
|
scratchDesktopTelemetrySingleton.projectDidLoad(arg);
|
|
});
|
|
ipcMain.on('projectDidSave', (event, arg) => {
|
|
scratchDesktopTelemetrySingleton.projectDidSave(arg);
|
|
});
|
|
ipcMain.on('projectWasCreated', (event, arg) => {
|
|
scratchDesktopTelemetrySingleton.projectWasCreated(arg);
|
|
});
|
|
ipcMain.on('projectWasUploaded', (event, arg) => {
|
|
scratchDesktopTelemetrySingleton.projectWasUploaded(arg);
|
|
});
|
|
|
|
export default scratchDesktopTelemetrySingleton;
|