Implement analytics
This commit is contained in:
parent
fc4ce8e69e
commit
fe32505873
3 changed files with 91 additions and 8 deletions
46
src/analytics.ts
Normal file
46
src/analytics.ts
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import {getBackend, getFrontend} from "siyuan";
|
||||||
|
import {JSON_MIME} from "@/const";
|
||||||
|
import packageJson from '../package.json' assert { type: 'json' };
|
||||||
|
|
||||||
|
export class Analytics {
|
||||||
|
|
||||||
|
private readonly enabled: boolean;
|
||||||
|
|
||||||
|
private static readonly ENDPOINT = 'https://stats.massive.box/api/send_noua';
|
||||||
|
private static readonly WEBSITE_ID = '0a1ebbc1-d702-4f64-86ed-f62dcde9b522';
|
||||||
|
|
||||||
|
constructor(enabled: boolean) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendEvent(name: string) {
|
||||||
|
|
||||||
|
if(!this.enabled) return;
|
||||||
|
|
||||||
|
const sendData = (name == 'load' || name == 'install') ?
|
||||||
|
{
|
||||||
|
'appVersion': window.navigator.userAgent.split(' ')[0],
|
||||||
|
'pluginVersion': packageJson.version,
|
||||||
|
'frontend': getFrontend(),
|
||||||
|
'backend': getBackend(),
|
||||||
|
'language': navigator.language,
|
||||||
|
} : {};
|
||||||
|
|
||||||
|
await fetch(Analytics.ENDPOINT, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': JSON_MIME,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: 'event',
|
||||||
|
payload: {
|
||||||
|
website: Analytics.WEBSITE_ID,
|
||||||
|
name: name,
|
||||||
|
data: sendData,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import {SettingUtils} from "@/libs/setting-utils";
|
||||||
import {validateColor} from "@/helper";
|
import {validateColor} from "@/helper";
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
autoResize: boolean,
|
autoResize: boolean
|
||||||
background: string
|
background: string
|
||||||
analytics: boolean
|
analytics: boolean
|
||||||
};
|
};
|
||||||
|
@ -15,12 +15,16 @@ export class PluginConfig {
|
||||||
private file: PluginFile;
|
private file: PluginFile;
|
||||||
|
|
||||||
options: Options;
|
options: Options;
|
||||||
|
private firstRun: boolean;
|
||||||
|
|
||||||
|
getFirstRun() { return this.firstRun }
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.file = new PluginFile(STORAGE_PATH, CONFIG_FILENAME, JSON_MIME);
|
this.file = new PluginFile(STORAGE_PATH, CONFIG_FILENAME, JSON_MIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
|
this.firstRun = false;
|
||||||
await this.file.loadFromSiYuanFS();
|
await this.file.loadFromSiYuanFS();
|
||||||
this.options = JSON.parse(this.file.getContent());
|
this.options = JSON.parse(this.file.getContent());
|
||||||
if(this.options == null) {
|
if(this.options == null) {
|
||||||
|
@ -32,8 +36,9 @@ export class PluginConfig {
|
||||||
this.options = {
|
this.options = {
|
||||||
autoResize: true,
|
autoResize: true,
|
||||||
background: "#000000",
|
background: "#000000",
|
||||||
analytics: true
|
analytics: true,
|
||||||
};
|
};
|
||||||
|
this.firstRun = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async save() {
|
async save() {
|
||||||
|
@ -69,7 +74,11 @@ export class PluginConfigViewer {
|
||||||
this.settingUtils = new SettingUtils({
|
this.settingUtils = new SettingUtils({
|
||||||
plugin: this.plugin,
|
plugin: this.plugin,
|
||||||
callback: async (data) => {
|
callback: async (data) => {
|
||||||
this.config.setConfig(data);
|
this.config.setConfig({
|
||||||
|
analytics: data.analytics,
|
||||||
|
autoResize: data.autoResize,
|
||||||
|
background: data.background,
|
||||||
|
});
|
||||||
await this.config.save();
|
await this.config.save();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -95,7 +104,7 @@ export class PluginConfigViewer {
|
||||||
title: "Analytics",
|
title: "Analytics",
|
||||||
description: `
|
description: `
|
||||||
Enable to send anonymous usage data to the developer.
|
Enable to send anonymous usage data to the developer.
|
||||||
<a href='https://massive.box'>Privacy</a>
|
<a href='https://s.massive.box/jsdraw-plugin-privacy'>Privacy</a>
|
||||||
`,
|
`,
|
||||||
value: this.config.options.analytics,
|
value: this.config.options.analytics,
|
||||||
type: 'checkbox'
|
type: 'checkbox'
|
||||||
|
|
36
src/index.ts
36
src/index.ts
|
@ -9,10 +9,12 @@ import {
|
||||||
import {migrate} from "@/migration";
|
import {migrate} from "@/migration";
|
||||||
import {EditorManager, PluginEditor} from "@/editor";
|
import {EditorManager, PluginEditor} from "@/editor";
|
||||||
import {PluginConfig, PluginConfigViewer} from "@/config";
|
import {PluginConfig, PluginConfigViewer} from "@/config";
|
||||||
|
import {Analytics} from "@/analytics";
|
||||||
|
|
||||||
export default class DrawJSPlugin extends Plugin {
|
export default class DrawJSPlugin extends Plugin {
|
||||||
|
|
||||||
config: PluginConfig;
|
config: PluginConfig;
|
||||||
|
analytics: Analytics;
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
|
|
||||||
|
@ -20,16 +22,15 @@ export default class DrawJSPlugin extends Plugin {
|
||||||
EditorManager.registerTab(this);
|
EditorManager.registerTab(this);
|
||||||
migrate()
|
migrate()
|
||||||
|
|
||||||
this.config = new PluginConfig();
|
await this.startConfig();
|
||||||
await this.config.load();
|
await this.startAnalytics();
|
||||||
let configViewer = new PluginConfigViewer(this.config, this);
|
|
||||||
await configViewer.load();
|
|
||||||
|
|
||||||
this.protyleSlash = [{
|
this.protyleSlash = [{
|
||||||
id: "insert-drawing",
|
id: "insert-drawing",
|
||||||
filter: ["Insert Drawing", "Add drawing", "whiteboard", "freehand", "graphics", "jsdraw"],
|
filter: ["Insert Drawing", "Add drawing", "whiteboard", "freehand", "graphics", "jsdraw"],
|
||||||
html: getMenuHTML("iconDraw", this.i18n.insertDrawing),
|
html: getMenuHTML("iconDraw", this.i18n.insertDrawing),
|
||||||
callback: (protyle: Protyle) => {
|
callback: (protyle: Protyle) => {
|
||||||
|
void this.analytics.sendEvent('create');
|
||||||
const fileID = generateRandomString();
|
const fileID = generateRandomString();
|
||||||
const syncID = generateTimeString() + '-' + generateRandomString();
|
const syncID = generateTimeString() + '-' + generateRandomString();
|
||||||
protyle.insert(getMarkdownBlock(fileID, syncID), true, false);
|
protyle.insert(getMarkdownBlock(fileID, syncID), true, false);
|
||||||
|
@ -44,6 +45,7 @@ export default class DrawJSPlugin extends Plugin {
|
||||||
icon: "iconDraw",
|
icon: "iconDraw",
|
||||||
label: "Edit with js-draw",
|
label: "Edit with js-draw",
|
||||||
click: () => {
|
click: () => {
|
||||||
|
void this.analytics.sendEvent('edit');
|
||||||
new EditorManager(new PluginEditor(ids.fileID, ids.syncID)).open(this)
|
new EditorManager(new PluginEditor(ids.fileID, ids.syncID)).open(this)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -51,4 +53,30 @@ export default class DrawJSPlugin extends Plugin {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onunload() {
|
||||||
|
void this.analytics.sendEvent("unload");
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall() {
|
||||||
|
void this.analytics.sendEvent("uninstall");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async startConfig() {
|
||||||
|
this.config = new PluginConfig();
|
||||||
|
await this.config.load();
|
||||||
|
let configViewer = new PluginConfigViewer(this.config, this);
|
||||||
|
await configViewer.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async startAnalytics() {
|
||||||
|
this.analytics = new Analytics(this.config.options.analytics);
|
||||||
|
if(this.config.getFirstRun()) {
|
||||||
|
await this.config.save();
|
||||||
|
void this.analytics.sendEvent('install');
|
||||||
|
}else{
|
||||||
|
void this.analytics.sendEvent('load');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue