diff --git a/src/main.ts b/src/main.ts
index adac019..75c620a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -6,6 +6,7 @@ import router from './renderer/router'
import ElementUI from 'element-plus'
import 'element-plus/dist/index.css'
import VueLazyLoad from 'vue3-lazyload'
+import { initTalkingData } from './renderer/utils/analytic'
import vue3PhotoPreview from 'vue3-photo-preview'
import 'vue3-photo-preview/dist/index.css'
import VueVideoPlayer from '@videojs-player/vue'
@@ -83,3 +84,5 @@ console.log(hljsCommon.highlightAuto('
Highlight.js has been registered succe
app.use(hljsVuePlugin)
app.use(VueVideoPlayer)
app.mount('#app')
+
+initTalkingData()
diff --git a/src/main/apis/app/uploader/index.ts b/src/main/apis/app/uploader/index.ts
index e45b75e..8815ace 100644
--- a/src/main/apis/app/uploader/index.ts
+++ b/src/main/apis/app/uploader/index.ts
@@ -18,7 +18,7 @@ import {
import picgo from '@core/picgo'
import db from '~/main/apis/core/datastore'
import windowManager from 'apis/app/window/windowManager'
-import { showNotification, getClipboardFilePath } from '~/main/utils/common'
+import { showNotification, getClipboardFilePath, calcDurationRange } from '~/main/utils/common'
import logger from '@core/picgo/logger'
import { T } from '~/main/i18n'
import { CLIPBOARD_IMAGE_FOLDER } from '~/universal/utils/static'
@@ -30,7 +30,8 @@ import { IWindowList } from '#/types/enum'
import { IPicGo } from 'piclist'
import {
GET_RENAME_FILE_NAME,
- RENAME_FILE_NAME
+ RENAME_FILE_NAME,
+ TALKING_DATA_EVENT
} from '~/universal/events/constants'
const waitForRename = (window: BrowserWindow, id: number): Promise => {
@@ -48,6 +49,20 @@ const waitForRename = (window: BrowserWindow, id: number): Promise
})
}
+const handleTalkingData = (webContents: WebContents, options: IAnalyticsData) => {
+ const data: ITalkingDataOptions = {
+ EventId: 'upload',
+ Label: options.type,
+ MapKv: {
+ by: options.fromClipboard ? 'clipboard' : 'files', // 上传剪贴板图片还是选择的文文件
+ count: options.count, // 上传的数量
+ duration: calcDurationRange(options.duration || 0), // 上传耗时
+ type: options.type
+ }
+ }
+ webContents.send(TALKING_DATA_EVENT, data)
+}
+
class Uploader {
private webContents: WebContents | null = null
// private uploading: boolean = false
@@ -142,8 +157,17 @@ class Uploader {
async upload (img?: IUploadOption): Promise {
try {
+ const startTime = Date.now()
const output = await picgo.upload(img)
if (Array.isArray(output) && output.some((item: ImgInfo) => item.imgUrl)) {
+ if (this.webContents) {
+ handleTalkingData(this.webContents, {
+ fromClipboard: !img,
+ type: db.get('picBed.uploader') || db.get('picBed.current') || 'smms',
+ count: img ? img.length : 1,
+ duration: Date.now() - startTime
+ } as IAnalyticsData)
+ }
output.forEach((item: ImgInfo) => {
item.config = JSON.parse(JSON.stringify(db.get(`picBed.${item.type}`)))
})
diff --git a/src/main/utils/common.ts b/src/main/utils/common.ts
index 67450e3..e958380 100644
--- a/src/main/utils/common.ts
+++ b/src/main/utils/common.ts
@@ -57,6 +57,30 @@ export const showMessageBox = (options: any) => {
})
}
+export const calcDurationRange = (duration: number) => {
+ if (duration < 1000) {
+ return 500
+ } else if (duration < 1500) {
+ return 1000
+ } else if (duration < 3000) {
+ return 2000
+ } else if (duration < 5000) {
+ return 3000
+ } else if (duration < 7000) {
+ return 5000
+ } else if (duration < 10000) {
+ return 8000
+ } else if (duration < 12000) {
+ return 10000
+ } else if (duration < 20000) {
+ return 15000
+ } else if (duration < 30000) {
+ return 20000
+ }
+ // max range
+ return 100000
+}
+
/**
* macOS public.file-url will get encoded file path,
* so we need to decode it
diff --git a/src/renderer/utils/analytic.ts b/src/renderer/utils/analytic.ts
new file mode 100644
index 0000000..1c85a4d
--- /dev/null
+++ b/src/renderer/utils/analytic.ts
@@ -0,0 +1,23 @@
+/* eslint-disable camelcase */
+import {
+ TALKING_DATA_APPID, TALKING_DATA_EVENT
+} from '~/universal/events/constants'
+import pkg from 'root/package.json'
+import { ipcRenderer } from 'electron'
+import { handleTalkingDataEvent } from './common'
+const { version } = pkg
+
+export const initTalkingData = () => {
+ setTimeout(() => {
+ const talkingDataScript = document.createElement('script')
+
+ talkingDataScript.src = `http://sdk.talkingdata.com/app/h5/v1?appid=${TALKING_DATA_APPID}&vn=${version}&vc=${version}`
+
+ const head = document.getElementsByTagName('head')[0]
+ head.appendChild(talkingDataScript)
+ }, 0)
+}
+
+ipcRenderer.on(TALKING_DATA_EVENT, (_, data: ITalkingDataOptions) => {
+ handleTalkingDataEvent(data)
+})
diff --git a/src/renderer/utils/common.ts b/src/renderer/utils/common.ts
index 7021872..a846f28 100644
--- a/src/renderer/utils/common.ts
+++ b/src/renderer/utils/common.ts
@@ -2,6 +2,16 @@ import { isReactive, isRef, toRaw, unref } from 'vue'
import { ipcRenderer } from 'electron'
import { OPEN_URL } from '~/universal/events/constants'
+const isDevelopment = process.env.NODE_ENV !== 'production'
+export const handleTalkingDataEvent = (data: ITalkingDataOptions) => {
+ const { EventId, Label = '', MapKv = {} } = data
+ MapKv.from = window.location.href
+ window.TDAPP.onEvent(EventId, Label, MapKv)
+ if (isDevelopment) {
+ console.log('talkingData', data)
+ }
+}
+
/**
* get raw data from reactive or ref
*/
diff --git a/src/universal/events/constants.ts b/src/universal/events/constants.ts
index 6867181..b2062a4 100644
--- a/src/universal/events/constants.ts
+++ b/src/universal/events/constants.ts
@@ -1,6 +1,8 @@
export const SHOW_INPUT_BOX = 'SHOW_INPUT_BOX'
export const SHOW_INPUT_BOX_RESPONSE = 'SHOW_INPUT_BOX_RESPONSE'
export const TOGGLE_SHORTKEY_MODIFIED_MODE = 'TOGGLE_SHORTKEY_MODIFIED_MODE'
+export const TALKING_DATA_APPID = 'B743C16E2989419A9B02EDE9D1E6A530'
+export const TALKING_DATA_EVENT = 'TALKING_DATA_EVENT'
export const C1N = 'WjJoeFdWWklhVTlXYVRKTU5EUmFOVkEwUlVRPQ=='
export const PICGO_SAVE_CONFIG = 'PICGO_SAVE_CONFIG'
export const PICGO_GET_CONFIG = 'PICGO_GET_CONFIG'
diff --git a/src/universal/types/types.d.ts b/src/universal/types/types.d.ts
index 3482907..62fe170 100644
--- a/src/universal/types/types.d.ts
+++ b/src/universal/types/types.d.ts
@@ -128,6 +128,12 @@ interface IBounds {
y: number
}
+interface ITalkingDataOptions {
+ EventId: string
+ Label?: string
+ MapKv?: IStringKeyMap
+}
+
// PicGo Types
type ICtx = import('piclist').PicGo
interface IPicGoPlugin {