Feature: add showMenubarIcon setting (#1366)

This commit is contained in:
PiEgg
2025-12-23 18:06:17 +08:00
committed by GitHub
parent eef736ff57
commit d0eb3da45a
19 changed files with 228 additions and 139 deletions
+23 -8
View File
@@ -10,11 +10,11 @@
## 2. 能否支持图床远端同步删除
不能。有些图床(比如微博图床、SM.MS、Imgur 等)不支持后台管理,为了架构统一不支持远端删除。
暂时不支持。有些图床(比如微博图床、SM.MS、Imgur 等)不支持后台管理,为了架构统一不支持远端删除。
## 3. 能否支持上传视频文件
目前不能。如果有人开发了相应的插件理论可以支持任意文件上传
目前部分图床支持上传视频文件,但并非所有图床都支持,请以实际使用的图床以及插件为准
## 4. 微博图床上传之后无法显示预览图
@@ -50,6 +50,27 @@
PicGo 在 Mac 上是一个顶部栏应用,在 dock 栏是不会有图标的。要打开主窗口,请右键或者双指点按顶部栏 PicGo 图标,选择「打开详细窗口」即可打开主窗口。
从 v2.4.1 开始,PicGo 支持在 macOS 下分别隐藏 Dock 栏图标(`showDockIcon`)和顶部栏图标(`showMenubarIcon`)。如果你把这两个配置都关闭(都设为 `false`),将会导致你无法通过 Dock 或顶部栏找到 PicGo 主界面。
手动恢复方法:
1. 找到并编辑 PicGo 的配置文件 `data.json`
- 如果还能打开设置页:PicGo 设置 -> 「打开配置文件」。
- 如果已经找不到界面:默认配置文件通常在 `~/Library/Application Support/PicGo/data.json`(如果你曾配置过自定义路径,则以配置里的 `configPath` 为准)。
2. 把以下任意一个字段改为 `true`(建议至少保留一个为 `true`),同时不要删改其他字段:
```json
{
"settings": {
// other settings ...
"showDockIcon": true,
"showMenubarIcon": true
}
}
```
3. 保存后重启 PicGo。
## 9. 上传失败,或者是服务器出错
1. PicGo 自带的图床都经过测试,上传出错一般都不是 PicGo 自身的原因。如果你用的是 GitHub 图床请参考上面的第 7 点。
@@ -117,12 +138,6 @@ options:
```
执行命令
```
xattr -c /Applications/PicGo.app/*
```
如果上述命令依然没有效果,可以尝试下面的命令:
```
sudo xattr -d com.apple.quarantine /Applications/PicGo.app/
```
+4 -4
View File
@@ -28,9 +28,9 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.2",
"@numairawan/video-duration": "^1.0.0",
"@picgo/i18n": "^1.0.0",
"@picgo/store": "^2.1.0",
"@picgo/video-duration": "^1.0.1",
"axios": "^0.19.0",
"clip-filepaths": "^0.3.0",
"compare-versions": "^4.1.3",
@@ -48,7 +48,7 @@
"mime-types": "^3.0.2",
"mitt": "^3.0.1",
"multer": "^1.4.5-lts.1",
"picgo": "^1.6.2",
"picgo": "^1.6.4",
"qrcode.vue": "^3.3.3",
"semver": "^7.7.3",
"shell-path": "2.1.0",
@@ -86,7 +86,7 @@
"autoprefixer": "^10.4.14",
"commitizen": "^4.3.1",
"conventional-changelog": "^3.1.18",
"cz-customizable": "^6.2.0",
"cz-customizable": "^7.5.1",
"dotenv": "^16.0.1",
"dpdm": "^3.13.1",
"electron": "^38",
@@ -123,4 +123,4 @@
"commit-msg": "npm run lint:dpdm && commitlint -E HUSKY_GIT_PARAMS"
}
}
}
}
+16 -49
View File
@@ -11,15 +11,15 @@ importers:
'@element-plus/icons-vue':
specifier: ^2.3.2
version: 2.3.2(vue@3.5.25(typescript@5.9.3))
'@numairawan/video-duration':
specifier: ^1.0.0
version: 1.0.0
'@picgo/i18n':
specifier: ^1.0.0
version: 1.0.0
'@picgo/store':
specifier: ^2.1.0
version: 2.1.0
'@picgo/video-duration':
specifier: ^1.0.1
version: 1.0.1
axios:
specifier: ^0.19.0
version: 0.19.2
@@ -72,8 +72,8 @@ importers:
specifier: ^1.4.5-lts.1
version: 1.4.5-lts.2
picgo:
specifier: ^1.6.2
version: 1.6.2
specifier: ^1.6.4
version: 1.6.4
qrcode.vue:
specifier: ^3.3.3
version: 3.6.0(vue@3.5.25(typescript@5.9.3))
@@ -181,8 +181,8 @@ importers:
specifier: ^3.1.18
version: 3.1.25
cz-customizable:
specifier: ^6.2.0
version: 6.9.2
specifier: ^7.5.1
version: 7.5.1
dotenv:
specifier: ^16.0.1
version: 16.6.1
@@ -1043,9 +1043,6 @@ packages:
resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==}
engines: {node: ^18.17.0 || >=20.5.0}
'@numairawan/video-duration@1.0.0':
resolution: {integrity: sha512-C819BxippZk2ajzfJt/S8kD5NJqAxuDZc1W4rqHVjzgoUI5Wjo7ehoH4dTIGesUEOxTobIXh6iOKAhhvGEDYpg==}
'@picgo/bump-version@2.0.0':
resolution: {integrity: sha512-7ClH+1f0vNchLOzUq7OlYXic3dIDH154aC809BIwHFkVzoj4z4YPT5TrR1syICFDCJVixg8Tvlli0z891iO0vg==}
engines: {node: '>=20.0.0'}
@@ -1057,6 +1054,10 @@ packages:
'@picgo/store@2.1.0':
resolution: {integrity: sha512-oD/+4hGaioSVqWmaV5/LEXJ/xfpDrwUYPDGgJx3gEYoNPG2IdIZiO++asSZsafAc03TGPlvtR3L9eOTqPaKj9w==}
'@picgo/video-duration@1.0.1':
resolution: {integrity: sha512-onab36wVAuEDSnyyXYwSrRt672urJnSeY5MwXwk6NLYLUU1UTld2uazfYAZVnCnR6u69sfUeDdefL51RG5jcoA==}
hasBin: true
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@@ -1865,9 +1866,6 @@ packages:
axios@0.27.2:
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
axios@1.13.2:
resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==}
babel-polyfill@6.26.0:
resolution: {integrity: sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==}
@@ -2424,10 +2422,6 @@ packages:
resolution: {integrity: sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==}
engines: {node: '>= 10'}
cz-customizable@6.9.2:
resolution: {integrity: sha512-33Y0eHAp40sb7K346Shm07X+ZIckPKV8pBHUH5Lh2tI4fi0mjHkrYDrwQyJMS8095Ri+H+xkxOmblzQ64wT/Fg==}
hasBin: true
cz-customizable@7.5.1:
resolution: {integrity: sha512-eGUfpyD6/YdnPomAMMbbwmofeHAR9D4OsXS5Kmr9+uEOxdop32tdmHy6sx4Bhpms6V8HohQ17p/fYvlIllrdmQ==}
hasBin: true
@@ -4465,8 +4459,8 @@ packages:
pend@1.2.0:
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
picgo@1.6.2:
resolution: {integrity: sha512-8o7ldUGHNywDX3keHeuiuSZZHt/hCyHepzzGA3Y3OdAZLIWdHI7NRjgUIQ2fsspQnkKaB4bm5xphoENhDiHuig==}
picgo@1.6.4:
resolution: {integrity: sha512-3RIcRVArRNqZKeRvFnClqr+JzJI4tjtYjpdgpCAhdtqr5cpT6HTp0C0d5GMExTCXjXc313Vdo4/W4S0fQVw2Zw==}
engines: {node: '>= 20.0.0'}
hasBin: true
@@ -4602,9 +4596,6 @@ packages:
proto-list@1.2.4:
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
pseudomap@1.0.2:
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
@@ -6886,13 +6877,6 @@ snapshots:
dependencies:
semver: 7.7.3
'@numairawan/video-duration@1.0.0':
dependencies:
axios: 1.13.2
mime-types: 2.1.35
transitivePeerDependencies:
- debug
'@picgo/bump-version@2.0.0(@types/node@20.19.26)(typescript@5.9.3)':
dependencies:
'@commitlint/cli': 7.6.1
@@ -6929,6 +6913,8 @@ snapshots:
lodash-id: 0.14.1
write-file-atomic: 4.0.2
'@picgo/video-duration@1.0.1': {}
'@pkgjs/parseargs@0.11.0':
optional: true
@@ -7926,14 +7912,6 @@ snapshots:
transitivePeerDependencies:
- debug
axios@1.13.2:
dependencies:
follow-redirects: 1.15.11
form-data: 4.0.5
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
babel-polyfill@6.26.0:
dependencies:
babel-runtime: 6.26.0
@@ -8594,15 +8572,6 @@ snapshots:
- '@types/node'
- typescript
cz-customizable@6.9.2:
dependencies:
editor: 1.0.0
find-config: 1.0.0
inquirer: 6.5.2
lodash: 4.17.21
temp: 0.9.4
word-wrap: 1.2.5
cz-customizable@7.5.1:
dependencies:
editor: 1.0.0
@@ -10899,7 +10868,7 @@ snapshots:
pend@1.2.0: {}
picgo@1.6.2:
picgo@1.6.4:
dependencies:
'@picgo/i18n': 1.0.0
'@picgo/store': 2.1.0
@@ -11033,8 +11002,6 @@ snapshots:
proto-list@1.2.4: {}
proxy-from-env@1.1.0: {}
pseudomap@1.0.2: {}
pump@3.0.3:
+2
View File
@@ -121,6 +121,8 @@ UPLOADER_CONFIG_PLACEHOLDER: Please Enter Configuration Name
SELECTED_SETTING_HINT: Selected
SETTINGS_ENCODE_OUTPUT_URL: Encode Output(or Copyed) URL
SETTINGS_SHOW_DOCK_ICON: Show Dock icon
SETTINGS_SHOW_MENUBAR_ICON: Show Menubar icon
SETTINGS_SHOW_MENUBAR_ICON_TIPS: If both "Show Dock icon" and "Show Menubar icon" are turned off, you won't be able to find PicGo's main window. Edit the config file and set showDockIcon or showMenubarIcon to true to recover.
SETTINGS_STARTUP_MODE: Startup Mode
SETTINGS_STARTUP_MODE_MAIN_WINDOW: Open Main Window
SETTINGS_STARTUP_MODE_MINI_WINDOW: Open Mini Window
+2
View File
@@ -121,6 +121,8 @@ UPLOADER_CONFIG_PLACEHOLDER: 请输入配置名称
SELECTED_SETTING_HINT: 已选中
SETTINGS_ENCODE_OUTPUT_URL: 输出(复制) URL 时进行转义
SETTINGS_SHOW_DOCK_ICON: 显示 Dock 栏图标
SETTINGS_SHOW_MENUBAR_ICON: 显示顶部栏图标
SETTINGS_SHOW_MENUBAR_ICON_TIPS: 若“显示 Dock 栏图标”和“显示顶部栏图标”都关闭,将会无法找到 PicGo 主界面。需要手动修改配置文件里的 showDockIcon 或 showMenubarIcon 为 true 才能恢复。
SETTINGS_STARTUP_MODE: 启动模式
SETTINGS_STARTUP_MODE_MAIN_WINDOW: 打开主窗口
SETTINGS_STARTUP_MODE_MINI_WINDOW: 打开 Mini 窗口
+2
View File
@@ -121,6 +121,8 @@ UPLOADER_CONFIG_PLACEHOLDER: 請輸入配置名稱
SELECTED_SETTING_HINT: 已選中
SETTINGS_ENCODE_OUTPUT_URL: 輸出(複製) URL 時進行轉義
SETTINGS_SHOW_DOCK_ICON: 顯示 Dock 欄圖示
SETTINGS_SHOW_MENUBAR_ICON: 顯示頂部欄圖示
SETTINGS_SHOW_MENUBAR_ICON_TIPS: 若「顯示 Dock 欄圖示」與「顯示頂部欄圖示」都關閉,將會無法找到 PicGo 主介面。需要手動修改配置檔案裡的 showDockIcon 或 showMenubarIcon 為 true 才能恢復。
SETTINGS_STARTUP_MODE: 啟動模式
SETTINGS_STARTUP_MODE_MAIN_WINDOW: 打開主視窗
SETTINGS_STARTUP_MODE_MINI_WINDOW: 打開 Mini 視窗
+33 -1
View File
@@ -17,7 +17,7 @@ import { ensureFilePath, getClipboardFilePathList, handleCopyUrl } from '~/main/
import { privacyManager } from '~/main/utils/privacyManager'
import { T } from '~/main/i18n'
import { isMacOSVersionGreaterThanOrEqualTo } from '~/main/utils/getMacOSVersion'
import { buildPicBedListMenu } from '~/main/events/remotes/menu'
import { buildPicBedListMenu } from '~/main/events/remotes/picBedListMenu'
import { isLinux, isMacOS } from '~/universal/utils/common'
import { getStaticPath } from '#/utils/staticPath'
let contextMenu: Menu | null
@@ -251,6 +251,38 @@ export function createTray () {
}
}
const destroyTray = () => {
if (tray) {
tray.removeAllListeners()
tray.destroy()
tray = null
}
if (windowManager.has(IWindowList.TRAY_WINDOW)) {
windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
}
}
/**
* macOS only: show/hide the menubar (tray) icon.
* For other platforms this keeps the existing behavior (always show tray).
*/
export function handleMenubarIcon (visible?: boolean) {
if (!isMacOS) {
if (!tray) {
createTray()
}
return
}
const shouldShow = visible !== undefined ? visible : (db.get('settings.showMenubarIcon') !== false)
if (shouldShow) {
if (!tray) {
createTray()
}
} else {
destroyTray()
}
}
export function handleDockIcon () {
if (isMacOS) {
if (db.get('settings.showDockIcon') !== false) {
+1 -57
View File
@@ -1,7 +1,6 @@
import windowManager from 'apis/app/window/windowManager'
import { IWindowList } from '#/types/enum'
import { Menu, BrowserWindow, app, dialog } from 'electron'
import getPicBeds from '~/main/utils/getPicBeds'
import picgo from '@core/picgo'
import {
uploadClipboardFiles
@@ -13,7 +12,7 @@ import { PICGO_CONFIG_PLUGIN, PICGO_HANDLE_PLUGIN_DONE, PICGO_HANDLE_PLUGIN_ING,
import picgoCoreIPC from '~/main/events/picgoCoreIPC'
import { PicGo as PicGoCore } from 'picgo'
import { T } from '~/main/i18n'
import { changeCurrentUploader } from '~/main/utils/handleUploaderConfig'
import { buildPicBedListMenu } from './picBedListMenu'
interface GuiMenuItem {
label: string
@@ -121,61 +120,6 @@ const buildMainPageMenu = (win: BrowserWindow) => {
return Menu.buildFromTemplate(template)
}
const buildPicBedListMenu = () => {
const picBeds = getPicBeds()
const currentPicBed = picgo.getConfig('picBed.uploader')
const currentPicBedName = picBeds.find(item => item.type === currentPicBed)?.name
const picBedConfigList = picgo.getConfig<IUploaderConfig>('uploader')
const currentPicBedMenuItem = [{
label: `${T('CURRENT_PICBED')} - ${currentPicBedName}`,
enabled: false
}, {
type: 'separator'
}]
let submenu = picBeds.filter(item => item.visible).map(item => {
const configList = picBedConfigList?.[item.type]?.configList
const defaultId = picBedConfigList?.[item.type]?.defaultId
const hasSubmenu = !!configList
return {
label: item.name,
type: !hasSubmenu ? 'checkbox' : undefined,
checked: !hasSubmenu ? (currentPicBed === item.type) : undefined,
submenu: hasSubmenu
? configList.map((config) => {
return {
label: config._configName || 'Default',
// if only one config, use checkbox, or radio will checked as default
// see: https://github.com/electron/electron/issues/21292
type: 'checkbox',
checked: config._id === defaultId && (item.type === currentPicBed),
click: function () {
changeCurrentUploader(item.type, config, config._id)
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
}
}
}
})
: undefined,
click: !hasSubmenu
? function () {
picgo.saveConfig({
'picBed.current': item.type,
'picBed.uploader': item.type
})
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
}
}
: undefined
}
})
// @ts-ignore
submenu = currentPicBedMenuItem.concat(submenu)
// @ts-ignore
return Menu.buildFromTemplate(submenu)
}
// TODO: separate to single file
const handleRestoreState = (item: string, name: string): void => {
+62
View File
@@ -0,0 +1,62 @@
import windowManager from 'apis/app/window/windowManager'
import { IWindowList } from '#/types/enum'
import { Menu } from 'electron'
import getPicBeds from '~/main/utils/getPicBeds'
import picgo from '@core/picgo'
import { T } from '~/main/i18n'
import { changeCurrentUploader } from '~/main/utils/handleUploaderConfig'
export const buildPicBedListMenu = () => {
const picBeds = getPicBeds()
const currentPicBed = picgo.getConfig('picBed.uploader')
const currentPicBedName = picBeds.find(item => item.type === currentPicBed)?.name
const picBedConfigList = picgo.getConfig<IUploaderConfig>('uploader')
const currentPicBedMenuItem = [{
label: `${T('CURRENT_PICBED')} - ${currentPicBedName}`,
enabled: false
}, {
type: 'separator'
}]
let submenu = picBeds.filter(item => item.visible).map(item => {
const configList = picBedConfigList?.[item.type]?.configList
const defaultId = picBedConfigList?.[item.type]?.defaultId
const hasSubmenu = !!configList
return {
label: item.name,
type: !hasSubmenu ? 'checkbox' : undefined,
checked: !hasSubmenu ? (currentPicBed === item.type) : undefined,
submenu: hasSubmenu
? configList.map((config) => {
return {
label: config._configName || 'Default',
// if only one config, use checkbox, or radio will checked as default
// see: https://github.com/electron/electron/issues/21292
type: 'checkbox',
checked: config._id === defaultId && (item.type === currentPicBed),
click: function () {
changeCurrentUploader(item.type, config, config._id)
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
}
}
}
})
: undefined,
click: !hasSubmenu
? function () {
picgo.saveConfig({
'picBed.current': item.type,
'picBed.uploader': item.type
})
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
}
}
: undefined
}
})
// @ts-ignore
submenu = currentPicBedMenuItem.concat(submenu)
// @ts-ignore
return Menu.buildFromTemplate(submenu)
}
+5
View File
@@ -2,6 +2,7 @@ import { IRPCActionType, IWindowList } from '~/universal/types/enum'
import { RPCRouter } from '../router'
import { app, clipboard, shell } from 'electron'
import windowManager from '~/main/apis/app/window/windowManager'
import { handleMenubarIcon } from '~/main/apis/app/system'
const systemRouter = new RPCRouter()
@@ -30,6 +31,10 @@ systemRouter
win?.setSkipTaskbar(false)
}
})
.add(IRPCActionType.SHOW_MENUBAR_ICON, async (args) => {
const [visible] = args as IShowMenubarIconArgs
handleMenubarIcon(visible)
})
export {
systemRouter
+2 -2
View File
@@ -20,7 +20,7 @@ import {
uploadClipboardFiles
} from 'apis/app/uploader/apis'
import {
createTray, handleDockIcon
handleDockIcon, handleMenubarIcon
} from 'apis/app/system'
import server from '~/main/server/index'
import updateChecker from '~/main/utils/updateChecker'
@@ -96,7 +96,7 @@ class LifeCycle {
miniWindow?.focus()
}
}
createTray()
handleMenubarIcon()
handleDockIcon()
db.set('needReload', false)
updateChecker()
+45 -17
View File
@@ -5,9 +5,7 @@ import type { IImgInfo } from "picgo";
import { calcUploadBigFileSizeRange, calcUploadProcessDurationRange, calcVideoDurationRange } from "./common";
import { app } from "electron/main";
import db from "~/main/apis/core/datastore";
import fs from 'fs-extra'
// @ts-ignore
import { videoDuration } from "@numairawan/video-duration";
import { getVideoDuration } from "@picgo/video-duration";
import { MB, SECOND } from "./constants";
export interface IReportUploadDataOptions {
@@ -41,7 +39,8 @@ class DataReportManager {
return {
fileName: item.fileName,
filePath: item.filePath,
mimeType: item.mimeType
mimeType: item.mimeType,
size: item.size || 0
}
})
const uploadEventData: ITalkingDataOptions = {
@@ -52,31 +51,34 @@ class DataReportManager {
count: fileList.length, // 上传的数量
duration: calcUploadProcessDurationRange(duration || 0), // 上传耗时
type: db.get('picBed.uploader') || db.get('picBed.current') || 'smms',
deviceId: this.deviceId,
version: app.getVersion()
}
}
webContents.send(TALKING_DATA_EVENT, uploadEventData)
this.reportDataToWebContents(webContents, uploadEventData);
fileList.forEach(async file => {
if (file?.mimeType?.startsWith('video/') && file.filePath) {
const [stats, metadata] = await Promise.all([
fs.stat(file.filePath),
videoDuration(file.filePath)
]);
// report video duration and size range
const sizeMB = stats.size / MB;
const durationSec = (metadata.ms / SECOND) || 0;
const metadata = await getVideoDuration(file.filePath);
const sizeMB = metadata.size / MB;
const durationSec = (metadata.duration / SECOND) || 0;
const videoEventData: ITalkingDataOptions = {
EventId: 'upload_video',
Label: '',
MapKv: {
deviceId: this.deviceId,
sizeRange: calcUploadBigFileSizeRange(sizeMB),
durationRange: calcVideoDurationRange(durationSec),
version: app.getVersion()
}
};
webContents.send(TALKING_DATA_EVENT, videoEventData);
this.reportDataToWebContents(webContents, videoEventData);
} else if (file?.mimeType?.startsWith('image/') || fromClipboard) {
const imageEventData: ITalkingDataOptions = {
EventId: 'upload_image',
Label: '',
MapKv: {
type: db.get('picBed.uploader') || db.get('picBed.current') || 'smms',
mimeType: file.mimeType,
sizeRange: calcUploadBigFileSizeRange(file.size / MB)
}
};
this.reportDataToWebContents(webContents, imageEventData);
}
});
}
@@ -86,6 +88,32 @@ class DataReportManager {
await this.init();
webContents.send(REGISTER_DEVICE_ID, this.deviceId);
}
private reportDataToWebContents(webContents: WebContents, data: ITalkingDataOptions) {
webContents.send(TALKING_DATA_EVENT, {
...data,
MapKv: {
...data.MapKv,
deviceId: this.deviceId,
version: app.getVersion(),
area: this.getAreaFromTimezone()
}
});
}
private getAreaFromTimezone() {
try {
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (!timeZone) return 'UNKNOWN';
if (timeZone === 'Asia/Shanghai') return 'CN';
const region = timeZone.split('/')[0]; // Asia, America, Europe
return region;
} catch (e) {
return 'UNKNOWN';
}
}
}
export const dataReportManager = new DataReportManager()
@@ -7,9 +7,14 @@
<el-tooltip
class="item"
effect="dark"
:content="props.tooltips"
:open="true"
placement="right"
>
<template #content>
<div class="picgo-tooltip-content">
{{ props.tooltips }}
</div>
</template>
<el-icon class="ml-[4px] cursor-pointer hover:text-blue">
<QuestionFilled />
</el-icon>
@@ -59,4 +64,10 @@ export default {
}
</script>
<style lang='stylus'>
.picgo-tooltip-content
max-width: 360px
max-height: 200px
overflow: auto
white-space: normal
word-break: break-word
</style>
+2
View File
@@ -74,6 +74,7 @@ const form = reactive<ISettingForm>({
logFileSizeLimit: 10,
encodeOutputURL: true,
showDockIcon: true,
showMenubarIcon: true,
customLink: '$url',
npmProxy: '',
npmRegistry: '',
@@ -115,6 +116,7 @@ async function initData () {
form.server = settings.server
form.logFileSizeLimit = enforceNumber(settings.logFileSizeLimit) || 10
form.showDockIcon = settings.showDockIcon === undefined ? true : settings.showDockIcon
form.showMenubarIcon = settings.showMenubarIcon === undefined ? true : settings.showMenubarIcon
form.startupMode = settings.startupMode || (isLinux ? IStartupMode.SHOW_MINI_WINDOW : IStartupMode.HIDE)
}
}
@@ -61,6 +61,14 @@
:label="$T('SETTINGS_SHOW_DOCK_ICON')"
@change="handleShowDockIcon"
/>
<SwitchFormItem
v-if="os === 'darwin'"
v-model="form.showMenubarIcon"
setting-props="showMenubarIcon"
:label="$T('SETTINGS_SHOW_MENUBAR_ICON')"
:tooltips="$T('SETTINGS_SHOW_MENUBAR_ICON_TIPS')"
@change="handleShowMenubarIcon"
/>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
@@ -92,6 +100,10 @@ function handleShowDockIcon (val: ISwitchValueType) {
sendRPC(IRPCActionType.SHOW_DOCK_ICON, val)
}
function handleShowMenubarIcon (val: ISwitchValueType) {
sendRPC(IRPCActionType.SHOW_MENUBAR_ICON, val)
}
</script>
<script lang="ts">
export default {
+1
View File
@@ -72,6 +72,7 @@ export enum IRPCActionType {
OPEN_FILE = 'OPEN_FILE',
COPY_TEXT = 'COPY_TEXT',
SHOW_DOCK_ICON = 'SHOW_DOCK_ICON',
SHOW_MENUBAR_ICON = 'SHOW_MENUBAR_ICON',
// gallery and toolbox rpc
UPDATE_GALLERY = 'UPDATE_GALLERY',
+2
View File
@@ -116,6 +116,8 @@ interface ILocales {
SELECTED_SETTING_HINT: string
SETTINGS_ENCODE_OUTPUT_URL: string
SETTINGS_SHOW_DOCK_ICON: string
SETTINGS_SHOW_MENUBAR_ICON: string
SETTINGS_SHOW_MENUBAR_ICON_TIPS: string
SETTINGS_STARTUP_MODE: string
SETTINGS_STARTUP_MODE_MAIN_WINDOW: string
SETTINGS_STARTUP_MODE_MINI_WINDOW: string
+1
View File
@@ -8,6 +8,7 @@ type IToolboxCheckArgs = [type: import('./enum').IToolboxItemType]
type IOpenFileArgs = [filePath: string]
type ICopyTextArgs = [text: string]
type IShowDockIconArgs = [visible: boolean]
type IShowMenubarIconArgs = [visible: boolean]
type IGetGalleryMenuListArgs = [selectedList: IGalleryItem[]]
interface IRPCServer {
+1
View File
@@ -14,6 +14,7 @@ interface ISettingForm {
logFileSizeLimit: number
encodeOutputURL: boolean
showDockIcon: boolean
showMenubarIcon: boolean
customLink: string
npmProxy: string
npmRegistry: string