mirror of
https://github.com/Molunerfinn/PicGo.git
synced 2026-09-20 03:16:37 +00:00
✨ Feature: add showMenubarIcon setting (#1366)
This commit is contained in:
@@ -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
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+16
-49
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 窗口
|
||||
|
||||
@@ -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 視窗
|
||||
|
||||
@@ -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,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 => {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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',
|
||||
|
||||
Vendored
+2
@@ -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
|
||||
|
||||
Vendored
+1
@@ -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 {
|
||||
|
||||
Vendored
+1
@@ -14,6 +14,7 @@ interface ISettingForm {
|
||||
logFileSizeLimit: number
|
||||
encodeOutputURL: boolean
|
||||
showDockIcon: boolean
|
||||
showMenubarIcon: boolean
|
||||
customLink: string
|
||||
npmProxy: string
|
||||
npmRegistry: string
|
||||
|
||||
Reference in New Issue
Block a user