mirror of
https://github.com/Molunerfinn/PicGo.git
synced 2024-04-21 10:31:33 +00:00
✨ Feature: add picgo toolbox for auto detect & fix problems
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
"@types/node": "^16.10.2",
|
||||
"@types/request-promise-native": "^1.0.17",
|
||||
"@types/semver": "^7.3.8",
|
||||
"@types/tunnel": "^0.0.3",
|
||||
"@types/write-file-atomic": "^4.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
||||
"@typescript-eslint/parser": "^5.48.0",
|
||||
|
||||
@@ -54,6 +54,8 @@ CHANGE_IMAGE_URL_SUCCEED: Change Image URL Succeed
|
||||
COPY_LINK_SUCCEED: Copy Link Succeed
|
||||
BATCH_COPY_LINK_SUCCEED: Batch Copy Link Succeed
|
||||
FILE_RENAME: File Rename
|
||||
COPY_FILE_PATH: Copy file path
|
||||
OPEN_FILE_PATH: Open file path
|
||||
|
||||
# settings
|
||||
|
||||
@@ -161,6 +163,30 @@ PLUGIN_IMPORT_LOCAL: Import Local Plugins
|
||||
|
||||
# toolbox
|
||||
TOOLBOX: Toolbox
|
||||
TOOLBOX_TITLE: Troubleshoot PicGo runtime issues
|
||||
TOOLBOX_SUB_TITLE: Scan the following items immediately to fix usage issues
|
||||
TOOLBOX_CHECK_CONFIG_FILE_BROKEN: Check if the configuration file is damaged
|
||||
TOOLBOX_CHECK_GALLERY_FILE_BROKEN: Check if the album file is damaged
|
||||
TOOLBOX_CHECK_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD: Check if there is a problem with clipboard picture upload
|
||||
TOOLBOX_CHECK_PROBLEM_WITH_PROXY: Check if the proxy settings are normal
|
||||
TOOLBOX_FIX_DONE_NEED_RELOAD: Repair completed, need to restart to take effect, restart or not
|
||||
TOOLBOX_CANT_AUTO_FIX: Unable to automatically repair, please repair the following problems yourself
|
||||
TOOLBOX_START_SCAN: Start scanning
|
||||
TOOLBOX_RE_SCAN: Re scanning
|
||||
TOOLBOX_START_FIX: Start fixing
|
||||
TOOLBOX_SUCCESS_TIPS: Congratulations, no problems were found
|
||||
TOOLBOX_CHECK_CONFIG_FILE_PATH_TIPS: "The configuration file path is: ${path}"
|
||||
TOOLBOX_CHECK_CONFIG_FILE_BROKEN_TIPS: The configuration file is damaged
|
||||
TOOLBOX_CHECK_GALLERY_FILE_PATH_TIPS: "The album file path is: ${path}"
|
||||
TOOLBOX_CHECK_GALLERY_FILE_BROKEN_TIPS: The album file is damaged
|
||||
TOOLBOX_CHECK_PROXY_SUCCESS_TIPS: Proxy settings normal
|
||||
TOOLBOX_CHECK_PROXY_NO_PROXY_TIPS: No proxy settings
|
||||
TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_CORRECT: Proxy settings incorrect
|
||||
TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_WORKING: Proxy settings unavailable
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_TIPS: "The temporary folder path for clipboard pictures is: ${path}"
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_NOT_EXIST_TIPS: "The temporary folder for clipboard pictures does not exist: ${path}"
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_ERROR_TIPS: "Please create the folder yourself: ${path}"
|
||||
|
||||
|
||||
# tips
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ CHANGE_IMAGE_URL_SUCCEED: 修改图片URL成功
|
||||
COPY_LINK_SUCCEED: 复制链接成功
|
||||
BATCH_COPY_LINK_SUCCEED: 批量复制链接成功
|
||||
FILE_RENAME: 文件改名
|
||||
COPY_FILE_PATH: 复制文件路径
|
||||
OPEN_FILE_PATH: 打开文件路径
|
||||
|
||||
# settings
|
||||
|
||||
@@ -190,6 +192,29 @@ UPDATE_PLUGIN: 更新插件
|
||||
|
||||
# toolbox
|
||||
TOOLBOX: 工具箱
|
||||
TOOLBOX_TITLE: 排查 PicGo 运行时问题
|
||||
TOOLBOX_SUB_TITLE: 立即扫描以下项目,修复使用问题
|
||||
TOOLBOX_CHECK_CONFIG_FILE_BROKEN: 检查配置文件是否损坏
|
||||
TOOLBOX_CHECK_GALLERY_FILE_BROKEN: 检查相册文件是否损坏
|
||||
TOOLBOX_CHECK_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD: 检查剪贴板图片上传是否存在问题
|
||||
TOOLBOX_CHECK_PROBLEM_WITH_PROXY: 检查代理设置是否正常
|
||||
TOOLBOX_FIX_DONE_NEED_RELOAD: 修复完成,需要重启生效,是否重启
|
||||
TOOLBOX_CANT_AUTO_FIX: 无法自动修复,请自行修复以下问题
|
||||
TOOLBOX_START_SCAN: 开始扫描
|
||||
TOOLBOX_RE_SCAN: 重新扫描
|
||||
TOOLBOX_START_FIX: 开始修复
|
||||
TOOLBOX_SUCCESS_TIPS: 恭喜你,没有检查出问题
|
||||
TOOLBOX_CHECK_CONFIG_FILE_PATH_TIPS: 配置文件路径是:${path}
|
||||
TOOLBOX_CHECK_CONFIG_FILE_BROKEN_TIPS: 配置文件已损坏
|
||||
TOOLBOX_CHECK_GALLERY_FILE_PATH_TIPS: 相册文件路径是:${path}
|
||||
TOOLBOX_CHECK_GALLERY_FILE_BROKEN_TIPS: 相册文件已损坏
|
||||
TOOLBOX_CHECK_PROXY_SUCCESS_TIPS: 代理设置正常
|
||||
TOOLBOX_CHECK_PROXY_NO_PROXY_TIPS: 无代理设置
|
||||
TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_CORRECT: 代理设置不正确
|
||||
TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_WORKING: 代理设置不可用
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_TIPS: 剪贴板图片临时文件夹路径是:${path}
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_NOT_EXIST_TIPS: 剪贴板图片临时文件夹不存在:${path}
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_ERROR_TIPS: 请自行创建文件夹:${path}
|
||||
|
||||
# tips
|
||||
TIPS_NOTICE: 注意
|
||||
|
||||
+27
-1
@@ -53,7 +53,9 @@ CHANGE_IMAGE_URL: 修改圖片URL
|
||||
CHANGE_IMAGE_URL_SUCCEED: 修改圖片URL成功
|
||||
COPY_LINK_SUCCEED: 複製連結成功
|
||||
BATCH_COPY_LINK_SUCCEED: 批量複製連結成功
|
||||
FILE_RENAME: 文件改名
|
||||
FILE_RENAME: 檔案改名
|
||||
COPY_FILE_PATH: 複製檔案路徑
|
||||
OPEN_FILE_PATH: 打開檔案路徑
|
||||
|
||||
# settings
|
||||
|
||||
@@ -161,6 +163,30 @@ PLUGIN_IMPORT_LOCAL: 導入本地插件
|
||||
|
||||
# toolbox
|
||||
TOOLBOX: 工具箱
|
||||
TOOLBOX_TITLE: 排查 PicGo 執行時問題
|
||||
TOOLBOX_SUB_TITLE: 立即掃描以下項目,修復使用問題
|
||||
TOOLBOX_CHECK_CONFIG_FILE_BROKEN: 檢查配置文件是否損壞
|
||||
TOOLBOX_CHECK_GALLERY_FILE_BROKEN: 檢查相冊文件是否損壞
|
||||
TOOLBOX_CHECK_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD: 檢查剪貼板圖片上傳是否存在問題
|
||||
TOOLBOX_CHECK_PROBLEM_WITH_PROXY: 檢查代理設置是否正常
|
||||
TOOLBOX_FIX_DONE_NEED_RELOAD: 修復完成,需要重啓生效,是否重啓
|
||||
TOOLBOX_CANT_AUTO_FIX: 無法自動修復,請自行修復以下問題
|
||||
TOOLBOX_START_SCAN: 開始掃描
|
||||
TOOLBOX_RE_SCAN: 重新掃描
|
||||
TOOLBOX_START_FIX: 開始修復
|
||||
TOOLBOX_SUCCESS_TIPS: 恭喜你,沒有檢查出問題
|
||||
TOOLBOX_CHECK_CONFIG_FILE_PATH_TIPS: 配置文件路徑是:${path}
|
||||
TOOLBOX_CHECK_CONFIG_FILE_BROKEN_TIPS: 配置文件已損壞
|
||||
TOOLBOX_CHECK_GALLERY_FILE_PATH_TIPS: 相冊文件路徑是:${path}
|
||||
TOOLBOX_CHECK_GALLERY_FILE_BROKEN_TIPS: 相冊文件已損壞
|
||||
TOOLBOX_CHECK_PROXY_SUCCESS_TIPS: 代理設置正常
|
||||
TOOLBOX_CHECK_PROXY_NO_PROXY_TIPS: 無代理設置
|
||||
TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_CORRECT: 代理設置不正確
|
||||
TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_WORKING: 代理設置不可用
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_TIPS: 剪貼板圖片臨時文件夾路徑是:${path}
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_NOT_EXIST_TIPS: 剪貼板圖片臨時文件夾不存在:${path}
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_ERROR_TIPS: 請自行創建文件夾:${path}
|
||||
|
||||
|
||||
# tips
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ if (!fs.pathExistsSync(STORE_PATH)) {
|
||||
fs.mkdirpSync(STORE_PATH)
|
||||
}
|
||||
const CONFIG_PATH: string = dbPathChecker()
|
||||
const DB_PATH: string = getGalleryDBPath().dbPath
|
||||
export const DB_PATH: string = getGalleryDBPath().dbPath
|
||||
|
||||
class ConfigStore {
|
||||
private db: JSONStore
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
SHOW_UPLOAD_PAGE_MENU,
|
||||
OPEN_USER_STORE_FILE,
|
||||
OPEN_URL,
|
||||
RELOAD_APP,
|
||||
SHOW_PLUGIN_PAGE_MENU,
|
||||
SET_MINI_WINDOW_POS,
|
||||
GET_PICBEDS
|
||||
@@ -218,10 +217,6 @@ export default {
|
||||
ipcMain.on(OPEN_URL, (evt: IpcMainEvent, url: string) => {
|
||||
shell.openExternal(url)
|
||||
})
|
||||
ipcMain.on(RELOAD_APP, () => {
|
||||
app.relaunch()
|
||||
app.exit(0)
|
||||
})
|
||||
ipcMain.on(SET_MINI_WINDOW_POS, (evt: IpcMainEvent, pos: IMiniWindowPos) => {
|
||||
const window = BrowserWindow.getFocusedWindow()
|
||||
window?.setBounds(pos)
|
||||
|
||||
@@ -1,95 +1,59 @@
|
||||
import { ipcMain, IpcMainEvent } from 'electron'
|
||||
import { IRPCActionType } from '~/universal/types/enum'
|
||||
import { RPC_ACTIONS } from '#/events/constants'
|
||||
import {
|
||||
deleteUploaderConfig,
|
||||
getUploaderConfigList,
|
||||
selectUploaderConfig,
|
||||
updateUploaderConfig
|
||||
} from '~/main/utils/handleUploaderConfig'
|
||||
import { getLatestVersion } from '~/main/utils/getLatestVersion'
|
||||
import { configRouter } from './routes/config'
|
||||
import { versionRouter } from './routes/version'
|
||||
import { toolboxRouter } from './routes/toolbox'
|
||||
import { systemRouter } from './routes/system'
|
||||
|
||||
class RPCServer {
|
||||
start () {
|
||||
ipcMain.on(RPC_ACTIONS, async (event: IpcMainEvent, action: IRPCActionType, args: any[], callbackId: string) => {
|
||||
try {
|
||||
switch (action) {
|
||||
case IRPCActionType.GET_PICBED_CONFIG_LIST: {
|
||||
const configList = this.getPicBedConfigList(args as IGetUploaderConfigListArgs)
|
||||
this.sendBack(event, action, configList, callbackId)
|
||||
break
|
||||
}
|
||||
case IRPCActionType.DELETE_PICBED_CONFIG: {
|
||||
const res = this.deleteUploaderConfig(args as IDeleteUploaderConfigArgs)
|
||||
this.sendBack(event, action, res, callbackId)
|
||||
break
|
||||
}
|
||||
case IRPCActionType.SELECT_UPLOADER: {
|
||||
this.selectUploaderConfig(args as ISelectUploaderConfigArgs)
|
||||
this.sendBack(event, action, true, callbackId)
|
||||
break
|
||||
}
|
||||
case IRPCActionType.UPDATE_UPLOADER_CONFIG: {
|
||||
this.updateUploaderConfig(args as IUpdateUploaderConfigArgs)
|
||||
this.sendBack(event, action, true, callbackId)
|
||||
break
|
||||
}
|
||||
case IRPCActionType.GET_LATEST_VERSION: {
|
||||
const res = await this.getLastestVersion(args as IGetLatestVersionArgs)
|
||||
this.sendBack(event, action, res, callbackId)
|
||||
break
|
||||
}
|
||||
default: {
|
||||
this.sendBack(event, action, null, callbackId)
|
||||
break
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
this.sendBack(event, action, null, callbackId)
|
||||
class RPCServer implements IRPCServer {
|
||||
private routes: IRPCRoutes = new Map()
|
||||
|
||||
private rpcEventHandler = async (event: IpcMainEvent, action: IRPCActionType, args: any[], callbackId: string) => {
|
||||
try {
|
||||
const handler = this.routes.get(action)
|
||||
if (!handler) {
|
||||
return this.sendBack(event, action, null, callbackId)
|
||||
}
|
||||
})
|
||||
const res = await handler?.(args, event)
|
||||
this.sendBack(event, action, res, callbackId)
|
||||
} catch (e) {
|
||||
this.sendBack(event, action, null, callbackId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if sendback data is null, then it means that the action is not supported or error occurs
|
||||
* if there is no callbackId, then do not send back
|
||||
*/
|
||||
private sendBack (event: IpcMainEvent, action: IRPCActionType, data: any, callbackId: string) {
|
||||
event.sender.send(RPC_ACTIONS, data, action, callbackId)
|
||||
if (callbackId) {
|
||||
event.sender.send(RPC_ACTIONS, data, action, callbackId)
|
||||
}
|
||||
}
|
||||
|
||||
private getPicBedConfigList (args: IGetUploaderConfigListArgs) {
|
||||
const [type] = args
|
||||
const config = getUploaderConfigList(type)
|
||||
return config
|
||||
start () {
|
||||
ipcMain.on(RPC_ACTIONS, this.rpcEventHandler)
|
||||
}
|
||||
|
||||
private deleteUploaderConfig (args: IDeleteUploaderConfigArgs) {
|
||||
const [type, id] = args
|
||||
const config = deleteUploaderConfig(type, id)
|
||||
return config
|
||||
use (routes: IRPCRoutes) {
|
||||
for (const [action, handler] of routes) {
|
||||
this.routes.set(action, handler)
|
||||
}
|
||||
}
|
||||
|
||||
private selectUploaderConfig (args: ISelectUploaderConfigArgs) {
|
||||
const [type, id] = args
|
||||
const config = selectUploaderConfig(type, id)
|
||||
return config
|
||||
}
|
||||
|
||||
private updateUploaderConfig (args: IUpdateUploaderConfigArgs) {
|
||||
const [type, id, config] = args
|
||||
const res = updateUploaderConfig(type, id, config)
|
||||
return res
|
||||
}
|
||||
|
||||
private async getLastestVersion (args: IGetLatestVersionArgs) {
|
||||
const [isCheckBetaUpdate] = args
|
||||
const version = await getLatestVersion(isCheckBetaUpdate)
|
||||
return version
|
||||
stop () {
|
||||
ipcMain.off(RPC_ACTIONS, this.rpcEventHandler)
|
||||
}
|
||||
}
|
||||
|
||||
const rpcServer = new RPCServer()
|
||||
|
||||
rpcServer.use(configRouter.routes())
|
||||
rpcServer.use(versionRouter.routes())
|
||||
rpcServer.use(toolboxRouter.routes())
|
||||
rpcServer.use(systemRouter.routes())
|
||||
|
||||
export {
|
||||
rpcServer
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { IRPCActionType } from '~/universal/types/enum'
|
||||
|
||||
export class RPCRouter implements IRPCRouter {
|
||||
private routeMap: IRPCRoutes = new Map()
|
||||
add = <T>(action: IRPCActionType, handler: IRPCHandler<T>) => {
|
||||
this.routeMap.set(action, handler)
|
||||
return this
|
||||
}
|
||||
|
||||
routes () {
|
||||
return this.routeMap
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { IRPCActionType } from '~/universal/types/enum'
|
||||
import { RPCRouter } from '../router'
|
||||
import { deleteUploaderConfig, getUploaderConfigList, selectUploaderConfig, updateUploaderConfig } from '~/main/utils/handleUploaderConfig'
|
||||
|
||||
const configRouter = new RPCRouter()
|
||||
|
||||
configRouter
|
||||
.add(IRPCActionType.GET_PICBED_CONFIG_LIST, async (args) => {
|
||||
const [type] = args as IGetUploaderConfigListArgs
|
||||
const config = getUploaderConfigList(type)
|
||||
return config
|
||||
})
|
||||
.add(IRPCActionType.DELETE_PICBED_CONFIG, async (args) => {
|
||||
const [type, id] = args as IDeleteUploaderConfigArgs
|
||||
const config = deleteUploaderConfig(type, id)
|
||||
return config
|
||||
})
|
||||
.add(IRPCActionType.SELECT_UPLOADER, async (args) => {
|
||||
const [type, id] = args as ISelectUploaderConfigArgs
|
||||
selectUploaderConfig(type, id)
|
||||
return true
|
||||
})
|
||||
.add(IRPCActionType.UPDATE_UPLOADER_CONFIG, async (args) => {
|
||||
const [type, id, config] = args as IUpdateUploaderConfigArgs
|
||||
updateUploaderConfig(type, id, config)
|
||||
return true
|
||||
})
|
||||
|
||||
export {
|
||||
configRouter
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { IRPCActionType } from '~/universal/types/enum'
|
||||
import { RPCRouter } from '../router'
|
||||
import { app, clipboard, shell } from 'electron'
|
||||
|
||||
const systemRouter = new RPCRouter()
|
||||
|
||||
systemRouter
|
||||
.add(IRPCActionType.RELOAD_APP, async () => {
|
||||
app.relaunch()
|
||||
app.exit(0)
|
||||
})
|
||||
.add(IRPCActionType.OPEN_FILE, async (args) => {
|
||||
const [filePath] = args as IOpenFileArgs
|
||||
shell.openPath(filePath)
|
||||
})
|
||||
.add(IRPCActionType.COPY_TEXT, async (args) => {
|
||||
const [text] = args as ICopyTextArgs
|
||||
return clipboard.writeText(text)
|
||||
})
|
||||
|
||||
export {
|
||||
systemRouter
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import fs from 'fs-extra'
|
||||
import path from 'path'
|
||||
import { dbPathChecker, defaultConfigPath } from '~/main/apis/core/datastore/dbChecker'
|
||||
import { IToolboxItemCheckStatus, IToolboxItemType } from '~/universal/types/enum'
|
||||
import { CLIPBOARD_IMAGE_FOLDER } from '~/universal/utils/static'
|
||||
import { sendToolboxResWithType } from './utils'
|
||||
import { T } from '~/main/i18n'
|
||||
|
||||
const sendToolboxRes = sendToolboxResWithType(IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD)
|
||||
|
||||
const defaultClipboardImagePath = path.join(defaultConfigPath, CLIPBOARD_IMAGE_FOLDER)
|
||||
|
||||
export const checkClipboardUploadMap: IToolboxCheckerMap<
|
||||
IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD
|
||||
> = {
|
||||
[IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD]: async (event) => {
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.LOADING
|
||||
})
|
||||
const configFilePath = dbPathChecker()
|
||||
if (fs.existsSync(configFilePath)) {
|
||||
const dirPath = path.dirname(configFilePath)
|
||||
const clipboardImagePath = path.join(dirPath, CLIPBOARD_IMAGE_FOLDER)
|
||||
if (fs.existsSync(clipboardImagePath)) {
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.SUCCESS,
|
||||
msg: T('TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_TIPS', {
|
||||
path: clipboardImagePath
|
||||
}),
|
||||
value: clipboardImagePath
|
||||
})
|
||||
} else {
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.ERROR,
|
||||
msg: T('TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_NOT_EXIST_TIPS', {
|
||||
path: clipboardImagePath
|
||||
}),
|
||||
value: path.dirname(clipboardImagePath)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.ERROR,
|
||||
msg: T('TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_NOT_EXIST_TIPS', {
|
||||
path: defaultClipboardImagePath
|
||||
}),
|
||||
value: path.dirname(defaultClipboardImagePath)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const fixClipboardUploadMap: IToolboxFixMap<
|
||||
IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD
|
||||
> = {
|
||||
[IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD]: async () => {
|
||||
const configFilePath = dbPathChecker()
|
||||
const dirPath = path.dirname(configFilePath)
|
||||
const clipboardImagePath = path.join(dirPath, CLIPBOARD_IMAGE_FOLDER)
|
||||
try {
|
||||
fs.mkdirsSync(clipboardImagePath)
|
||||
return {
|
||||
type: IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD,
|
||||
status: IToolboxItemCheckStatus.SUCCESS
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
type: IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD,
|
||||
status: IToolboxItemCheckStatus.ERROR,
|
||||
msg: T('TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_ERROR_TIPS', {
|
||||
path: clipboardImagePath
|
||||
}),
|
||||
value: path.dirname(clipboardImagePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import fs from 'fs-extra'
|
||||
import { IpcMainEvent } from 'electron'
|
||||
import { IToolboxItemCheckStatus, IToolboxItemType } from '~/universal/types/enum'
|
||||
import { sendToolboxResWithType } from './utils'
|
||||
import { dbPathChecker } from '~/main/apis/core/datastore/dbChecker'
|
||||
import { GalleryDB, DB_PATH } from '~/main/apis/core/datastore'
|
||||
import path from 'path'
|
||||
import { T } from '~/main/i18n'
|
||||
|
||||
export const checkFileMap: IToolboxCheckerMap<
|
||||
IToolboxItemType.IS_CONFIG_FILE_BROKEN | IToolboxItemType.IS_GALLERY_FILE_BROKEN
|
||||
> = {
|
||||
[IToolboxItemType.IS_CONFIG_FILE_BROKEN]: async (event: IpcMainEvent) => {
|
||||
const sendToolboxRes = sendToolboxResWithType(IToolboxItemType.IS_CONFIG_FILE_BROKEN)
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.LOADING
|
||||
})
|
||||
const configFilePath = dbPathChecker()
|
||||
try {
|
||||
if (fs.existsSync(configFilePath)) {
|
||||
await fs.readJSON(configFilePath)
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.SUCCESS,
|
||||
msg: T('TOOLBOX_CHECK_CONFIG_FILE_PATH_TIPS', {
|
||||
path: configFilePath
|
||||
}),
|
||||
value: configFilePath
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.ERROR,
|
||||
msg: T('TOOLBOX_CHECK_CONFIG_FILE_BROKEN_TIPS'),
|
||||
value: path.dirname(configFilePath)
|
||||
})
|
||||
}
|
||||
},
|
||||
[IToolboxItemType.IS_GALLERY_FILE_BROKEN]: async (event) => {
|
||||
const sendToolboxRes = sendToolboxResWithType(IToolboxItemType.IS_GALLERY_FILE_BROKEN)
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.LOADING
|
||||
})
|
||||
const galleryDB = GalleryDB.getInstance()
|
||||
if (galleryDB.errorList.length === 0) {
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.SUCCESS,
|
||||
msg: T('TOOLBOX_CHECK_GALLERY_FILE_PATH_TIPS', {
|
||||
path: DB_PATH
|
||||
}),
|
||||
value: path.dirname(DB_PATH)
|
||||
})
|
||||
} else {
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.ERROR,
|
||||
msg: T('TOOLBOX_CHECK_GALLERY_FILE_BROKEN_TIPS'),
|
||||
value: path.dirname(DB_PATH)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const fixFileMap: IToolboxFixMap<
|
||||
IToolboxItemType.IS_CONFIG_FILE_BROKEN | IToolboxItemType.IS_GALLERY_FILE_BROKEN
|
||||
> = {
|
||||
[IToolboxItemType.IS_CONFIG_FILE_BROKEN]: async () => {
|
||||
try {
|
||||
fs.unlinkSync(dbPathChecker())
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
return {
|
||||
type: IToolboxItemType.IS_CONFIG_FILE_BROKEN,
|
||||
status: IToolboxItemCheckStatus.SUCCESS
|
||||
}
|
||||
},
|
||||
[IToolboxItemType.IS_GALLERY_FILE_BROKEN]: async () => {
|
||||
try {
|
||||
fs.unlinkSync(DB_PATH)
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
return {
|
||||
type: IToolboxItemType.IS_GALLERY_FILE_BROKEN,
|
||||
status: IToolboxItemCheckStatus.SUCCESS
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import fs from 'fs-extra'
|
||||
import { IToolboxItemCheckStatus, IToolboxItemType } from '~/universal/types/enum'
|
||||
import { sendToolboxResWithType } from './utils'
|
||||
import tunnel from 'tunnel'
|
||||
import { dbPathChecker } from '~/main/apis/core/datastore/dbChecker'
|
||||
import { IConfig } from 'picgo'
|
||||
import axios, { AxiosRequestConfig } from 'axios'
|
||||
import { T } from '~/main/i18n'
|
||||
|
||||
const getProxy = (proxyStr: string): AxiosRequestConfig['proxy'] | false => {
|
||||
if (proxyStr) {
|
||||
try {
|
||||
const proxyOptions = new URL(proxyStr)
|
||||
return {
|
||||
host: proxyOptions.hostname,
|
||||
port: parseInt(proxyOptions.port || '0', 10),
|
||||
protocol: proxyOptions.protocol
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const sendToolboxRes = sendToolboxResWithType(IToolboxItemType.HAS_PROBLEM_WITH_PROXY)
|
||||
|
||||
export const checkProxyMap: IToolboxCheckerMap<
|
||||
IToolboxItemType.HAS_PROBLEM_WITH_PROXY
|
||||
> = {
|
||||
[IToolboxItemType.HAS_PROBLEM_WITH_PROXY]: async (event) => {
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.LOADING
|
||||
})
|
||||
const configFilePath = dbPathChecker()
|
||||
if (fs.existsSync(configFilePath)) {
|
||||
let config: IConfig | undefined
|
||||
try {
|
||||
config = await fs.readJSON(configFilePath) as IConfig
|
||||
} catch (e) {
|
||||
}
|
||||
if (!config) {
|
||||
return sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.SUCCESS,
|
||||
msg: T('TOOLBOX_CHECK_PROXY_NO_PROXY_TIPS')
|
||||
})
|
||||
}
|
||||
|
||||
const proxy = config.picBed?.proxy
|
||||
if (!proxy) {
|
||||
return sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.SUCCESS,
|
||||
msg: T('TOOLBOX_CHECK_PROXY_NO_PROXY_TIPS')
|
||||
})
|
||||
} else {
|
||||
const proxyOptions = getProxy(proxy)
|
||||
if (!proxyOptions) {
|
||||
return sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.ERROR,
|
||||
msg: T('TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_CORRECT')
|
||||
})
|
||||
} else {
|
||||
const httpsAgent = tunnel.httpsOverHttp({
|
||||
proxy: {
|
||||
host: proxyOptions.host,
|
||||
port: proxyOptions.port
|
||||
}
|
||||
})
|
||||
try {
|
||||
await axios.get('https://www.google.com', {
|
||||
httpsAgent
|
||||
})
|
||||
return sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.SUCCESS,
|
||||
msg: T('TOOLBOX_CHECK_PROXY_SUCCESS_TIPS')
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
return sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.ERROR,
|
||||
msg: T('TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_WORKING')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendToolboxRes(event, {
|
||||
status: IToolboxItemCheckStatus.SUCCESS,
|
||||
msg: T('TOOLBOX_CHECK_PROXY_NO_PROXY_TIPS')
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { IRPCActionType, IToolboxItemType } from '~/universal/types/enum'
|
||||
import { RPCRouter } from '../../router'
|
||||
import { checkFileMap, fixFileMap } from './checkFile'
|
||||
import { checkClipboardUploadMap, fixClipboardUploadMap } from './checkClipboardUpload'
|
||||
import { checkProxyMap } from './checkProxy'
|
||||
|
||||
const toolboxRouter = new RPCRouter()
|
||||
|
||||
const toolboxCheckMap: Partial<IToolboxCheckerMap<IToolboxItemType>> = {
|
||||
...checkFileMap,
|
||||
...checkClipboardUploadMap,
|
||||
...checkProxyMap
|
||||
}
|
||||
|
||||
const toolboxFixMap: Partial<IToolboxFixMap<IToolboxItemType>> = {
|
||||
...fixFileMap,
|
||||
...fixClipboardUploadMap
|
||||
}
|
||||
|
||||
toolboxRouter
|
||||
.add(IRPCActionType.TOOLBOX_CHECK, async (args, event) => {
|
||||
const [type] = args as IToolboxCheckArgs
|
||||
if (type) {
|
||||
const handler = toolboxCheckMap[type]
|
||||
if (handler) {
|
||||
handler(event)
|
||||
}
|
||||
} else {
|
||||
// do check all
|
||||
for (const key in toolboxCheckMap) {
|
||||
const handler = toolboxCheckMap[key as IToolboxItemType]
|
||||
if (handler) {
|
||||
handler(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.add(IRPCActionType.TOOLBOX_CHECK_FIX, async (args, event) => {
|
||||
const [type] = args as IToolboxCheckArgs
|
||||
const handler = toolboxFixMap[type]
|
||||
if (handler) {
|
||||
return await handler(event)
|
||||
}
|
||||
})
|
||||
|
||||
export {
|
||||
toolboxRouter
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { IpcMainEvent } from 'electron'
|
||||
import { IRPCActionType, IToolboxItemType } from '~/universal/types/enum'
|
||||
|
||||
export const sendToolboxResWithType = (type: IToolboxItemType) => (event: IpcMainEvent, res?: Omit<IToolboxCheckRes, 'type'>) => {
|
||||
return event.sender.send(IRPCActionType.TOOLBOX_CHECK_RES, {
|
||||
...res,
|
||||
type
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { IRPCActionType } from '~/universal/types/enum'
|
||||
import { RPCRouter } from '../router'
|
||||
import { getLatestVersion } from '~/main/utils/getLatestVersion'
|
||||
|
||||
const versionRouter = new RPCRouter()
|
||||
|
||||
versionRouter
|
||||
.add(IRPCActionType.GET_LATEST_VERSION, async (args) => {
|
||||
const [type] = args as IGetLatestVersionArgs
|
||||
const config = await getLatestVersion(type)
|
||||
return config
|
||||
})
|
||||
|
||||
export {
|
||||
versionRouter
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="toolbox-handler">
|
||||
<ElButton
|
||||
type="text"
|
||||
@click="() => props.handler(value)"
|
||||
>
|
||||
{{ props.handlerText }}
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { IToolboxItemCheckStatus } from '~/universal/types/enum'
|
||||
interface IProps {
|
||||
status: IToolboxItemCheckStatus
|
||||
value: any
|
||||
handlerText: string
|
||||
handler: (value: any) => void | Promise<void>
|
||||
}
|
||||
|
||||
const props = defineProps<IProps>()
|
||||
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'ToolboxHandler'
|
||||
}
|
||||
</script>
|
||||
<style lang='stylus'>
|
||||
</style>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<el-icon
|
||||
:color="color"
|
||||
class="toolbox-status-icon"
|
||||
>
|
||||
<template v-if="props.status === IToolboxItemCheckStatus.SUCCESS">
|
||||
<SuccessFilled />
|
||||
</template>
|
||||
<template v-if="props.status === IToolboxItemCheckStatus.ERROR">
|
||||
<CircleCloseFilled />
|
||||
</template>
|
||||
<template v-if="props.status === IToolboxItemCheckStatus.LOADING">
|
||||
<Loading />
|
||||
</template>
|
||||
</el-icon>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { CircleCloseFilled, Loading, SuccessFilled } from '@element-plus/icons-vue'
|
||||
import { computed } from 'vue'
|
||||
import { IToolboxItemCheckStatus } from '~/universal/types/enum'
|
||||
interface IProps {
|
||||
status: IToolboxItemCheckStatus
|
||||
}
|
||||
|
||||
const props = defineProps<IProps>()
|
||||
|
||||
const color = computed(() => {
|
||||
switch (props.status) {
|
||||
case IToolboxItemCheckStatus.SUCCESS:
|
||||
return '#67C23A'
|
||||
case IToolboxItemCheckStatus.ERROR:
|
||||
return '#F56C6C'
|
||||
default:
|
||||
return '#909399'
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'ToolboxStatusIcon'
|
||||
}
|
||||
</script>
|
||||
<style lang='stylus'>
|
||||
.toolbox-status-icon {
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,29 @@
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { onUnmounted } from 'vue'
|
||||
import { IRPCActionType } from '~/universal/types/enum'
|
||||
|
||||
export const useIPCOn = (channel: string, listener: IpcRendererListener) => {
|
||||
ipcRenderer.on(channel, listener)
|
||||
|
||||
onUnmounted(() => {
|
||||
ipcRenderer.removeListener(channel, listener)
|
||||
})
|
||||
}
|
||||
|
||||
export const useIPCOnce = (channel: string, listener: IpcRendererListener) => {
|
||||
ipcRenderer.once(channel, listener)
|
||||
|
||||
onUnmounted(() => {
|
||||
ipcRenderer.removeListener(channel, listener)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* will auto removeListener when component unmounted
|
||||
*/
|
||||
export const useIPC = () => {
|
||||
return {
|
||||
on: (channel: IRPCActionType, listener: IpcRendererListener) => useIPCOn(channel, listener),
|
||||
once: (channel: IRPCActionType, listener: IpcRendererListener) => useIPCOnce(channel, listener)
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,6 @@ import {
|
||||
import { handleStreamlinePluginName } from '~/universal/utils/common'
|
||||
import {
|
||||
OPEN_URL,
|
||||
RELOAD_APP,
|
||||
PICGO_CONFIG_PLUGIN,
|
||||
PICGO_HANDLE_PLUGIN_ING,
|
||||
PICGO_TOGGLE_PLUGIN,
|
||||
@@ -215,9 +214,10 @@ import {
|
||||
PICGO_HANDLE_PLUGIN_DONE
|
||||
} from '#/events/constants'
|
||||
import { computed, ref, onBeforeMount, onBeforeUnmount, watch } from 'vue'
|
||||
import { getConfig, saveConfig, sendToMain } from '@/utils/dataSender'
|
||||
import { getConfig, saveConfig, sendRPC, sendToMain } from '@/utils/dataSender'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import { IRPCActionType } from '~/universal/types/enum'
|
||||
const $confirm = ElMessageBox.confirm
|
||||
const searchText = ref('')
|
||||
const pluginList = ref<IPicGoPlugin[]>([])
|
||||
@@ -399,7 +399,7 @@ function installPlugin (item: IPicGoPlugin) {
|
||||
// }
|
||||
|
||||
function reloadApp () {
|
||||
sendToMain(RELOAD_APP)
|
||||
sendRPC(IRPCActionType.RELOAD_APP)
|
||||
}
|
||||
|
||||
async function handleReload () {
|
||||
|
||||
+184
-35
@@ -11,20 +11,53 @@
|
||||
>
|
||||
<el-row class="toolbox-header__text">
|
||||
<el-row class="toolbox-header__title">
|
||||
排查 PicGo 运行时问题
|
||||
{{ $T('TOOLBOX_TITLE') }}
|
||||
</el-row>
|
||||
<el-row class="toolbox-header__sub-title">
|
||||
立即扫描以下项目,修复使用问题
|
||||
{{ $T('TOOLBOX_SUB_TITLE') }}
|
||||
</el-row>
|
||||
</el-row>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
>
|
||||
开始扫描
|
||||
</el-button>
|
||||
<template v-if="progress !== 100">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
:disabled="isLoading"
|
||||
@click="handleCheck"
|
||||
>
|
||||
{{ $T('TOOLBOX_START_SCAN') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-else-if="isAllSuccess">
|
||||
<div class="toolbox-tips">
|
||||
{{ $T('TOOLBOX_SUCCESS_TIPS') }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="!isAllSuccess">
|
||||
<template v-if="canFixLength !== 0">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
@click="handleFix"
|
||||
>
|
||||
{{ $T('TOOLBOX_START_FIX') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="toolbox-cant-fix toolbox-tips">
|
||||
{{ $T('TOOLBOX_CANT_AUTO_FIX') }}
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
class="toolbox-cant-fix__btn"
|
||||
@click="handleCheck"
|
||||
>
|
||||
{{ $T('TOOLBOX_RE_SCAN') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</el-row>
|
||||
@@ -34,48 +67,152 @@
|
||||
:format="format"
|
||||
/>
|
||||
</el-row>
|
||||
<el-collapse accordion>
|
||||
<el-collapse
|
||||
v-model="activeTypes"
|
||||
accordion
|
||||
>
|
||||
<el-collapse-item
|
||||
v-for="item in fixList"
|
||||
:key="item.id"
|
||||
:title="item.title"
|
||||
v-for="(item, key) in fixList"
|
||||
:key="key"
|
||||
:name="key"
|
||||
>
|
||||
123
|
||||
<template #title>
|
||||
{{ item.title }} <toolbox-status-icon :status="item.status" />
|
||||
</template>
|
||||
<div class="toolbox-item-msg">
|
||||
{{ item.msg || '' }}
|
||||
<template v-if="item.handler && item.handlerText && item.value">
|
||||
<toolbox-handler
|
||||
:value="item.value"
|
||||
:status="item.status"
|
||||
:handler="item.handler"
|
||||
:handler-text="item.handlerText"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { IToolboxItemType } from '~/universal/types/enum'
|
||||
// import { T as $T } from '@/i18n'
|
||||
import { useIPC } from '@/hooks/useIPC'
|
||||
import { sendRPC, triggerRPC } from '@/utils/dataSender'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { IToolboxItemType, IToolboxItemCheckStatus, IRPCActionType } from '~/universal/types/enum'
|
||||
import { T as $T } from '@/i18n'
|
||||
import ToolboxStatusIcon from '@/components/ToolboxStatusIcon.vue'
|
||||
import ToolboxHandler from '@/components/ToolboxHandler.vue'
|
||||
|
||||
const $confirm = ElMessageBox.confirm
|
||||
const defaultLogo = ref(`file://${__static.replace(/\\/g, '/')}/roundLogo.png`)
|
||||
const fixList = ref<IToolboxItem[]>([
|
||||
{
|
||||
id: IToolboxItemType.IS_CONFIG_FILE_BROKEN,
|
||||
title: '检查配置文件是否损坏',
|
||||
status: 'init'
|
||||
const activeTypes = ref<IToolboxItemType[]>([])
|
||||
const fixList = reactive<IToolboxMap>({
|
||||
[IToolboxItemType.IS_CONFIG_FILE_BROKEN]: {
|
||||
title: $T('TOOLBOX_CHECK_CONFIG_FILE_BROKEN'),
|
||||
status: IToolboxItemCheckStatus.INIT,
|
||||
handlerText: $T('SETTINGS_OPEN_CONFIG_FILE'),
|
||||
handler (value: string) {
|
||||
sendRPC(IRPCActionType.OPEN_FILE, value)
|
||||
}
|
||||
},
|
||||
{
|
||||
id: IToolboxItemType.IS_GALLERY_FILE_BROKEN,
|
||||
title: '检查相册文件是否损坏',
|
||||
status: 'init'
|
||||
[IToolboxItemType.IS_GALLERY_FILE_BROKEN]: {
|
||||
title: $T('TOOLBOX_CHECK_GALLERY_FILE_BROKEN'),
|
||||
status: IToolboxItemCheckStatus.INIT
|
||||
},
|
||||
{
|
||||
id: IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD,
|
||||
title: '检查剪贴板图片上传是否存在问题',
|
||||
status: 'init'
|
||||
[IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD]: {
|
||||
title: $T('TOOLBOX_CHECK_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD'), // picgo-image-clipboard folder
|
||||
status: IToolboxItemCheckStatus.INIT,
|
||||
handlerText: $T('OPEN_FILE_PATH'),
|
||||
handler (value: string) {
|
||||
sendRPC(IRPCActionType.OPEN_FILE, value)
|
||||
}
|
||||
},
|
||||
{
|
||||
id: IToolboxItemType.HAS_PROBLEM_WITH_PROXY,
|
||||
title: '检查代理设置是否正常',
|
||||
status: 'init'
|
||||
[IToolboxItemType.HAS_PROBLEM_WITH_PROXY]: {
|
||||
title: $T('TOOLBOX_CHECK_PROBLEM_WITH_PROXY'),
|
||||
status: IToolboxItemCheckStatus.INIT,
|
||||
hasNoFixMethod: true
|
||||
}
|
||||
])
|
||||
const progress = ref(0)
|
||||
})
|
||||
|
||||
const progress = computed(() => {
|
||||
const total = Object.keys(fixList).length
|
||||
const done = Object.keys(fixList).filter(key => {
|
||||
const status = fixList[key as IToolboxItemType].status
|
||||
return status !== IToolboxItemCheckStatus.INIT && status !== IToolboxItemCheckStatus.LOADING
|
||||
}).length
|
||||
return done / total * 100
|
||||
})
|
||||
|
||||
const isAllSuccess = computed(() => {
|
||||
return Object.keys(fixList).every(key => {
|
||||
const status = fixList[key as IToolboxItemType].status
|
||||
return status === IToolboxItemCheckStatus.SUCCESS
|
||||
})
|
||||
})
|
||||
|
||||
const isLoading = computed(() => {
|
||||
return Object.keys(fixList).some(key => {
|
||||
const status = fixList[key as IToolboxItemType].status
|
||||
return status === IToolboxItemCheckStatus.LOADING
|
||||
})
|
||||
})
|
||||
|
||||
const canFixLength = computed(() => {
|
||||
return Object.keys(fixList).filter(key => {
|
||||
const status = fixList[key as IToolboxItemType].status
|
||||
return status === IToolboxItemCheckStatus.ERROR && !fixList[key as IToolboxItemType].hasNoFixMethod
|
||||
}).length
|
||||
})
|
||||
|
||||
const format = (percentage: number) => ''
|
||||
|
||||
const ipc = useIPC()
|
||||
|
||||
ipc.on(IRPCActionType.TOOLBOX_CHECK_RES, (event, { type, msg = '', status, value = '' }: IToolboxCheckRes) => {
|
||||
fixList[type].status = status
|
||||
fixList[type].msg = msg
|
||||
fixList[type].value = value
|
||||
if (status === IToolboxItemCheckStatus.ERROR) {
|
||||
activeTypes.value.push(type)
|
||||
}
|
||||
})
|
||||
|
||||
const handleCheck = () => {
|
||||
activeTypes.value = []
|
||||
Object.keys(fixList).forEach(key => {
|
||||
fixList[key as IToolboxItemType].status = IToolboxItemCheckStatus.LOADING
|
||||
fixList[key as IToolboxItemType].msg = ''
|
||||
fixList[key as IToolboxItemType].value = ''
|
||||
})
|
||||
sendRPC(IRPCActionType.TOOLBOX_CHECK)
|
||||
}
|
||||
|
||||
const handleFix = async () => {
|
||||
const fixRes = await Promise.all(Object.keys(fixList).filter(key => {
|
||||
const status = fixList[key as IToolboxItemType].status
|
||||
return status === IToolboxItemCheckStatus.ERROR && !fixList[key as IToolboxItemType].hasNoFixMethod
|
||||
}).map(async key => {
|
||||
return triggerRPC<IToolboxCheckRes>(IRPCActionType.TOOLBOX_CHECK_FIX, key as IToolboxItemType)
|
||||
}))
|
||||
|
||||
fixRes.filter(item => item !== null).forEach(item => {
|
||||
if (item) {
|
||||
fixList[item.type].status = item.status
|
||||
fixList[item.type].msg = item.msg
|
||||
fixList[item.type].value = item.value
|
||||
}
|
||||
})
|
||||
|
||||
$confirm($T('TOOLBOX_FIX_DONE_NEED_RELOAD'), $T('TIPS_NOTICE'), {
|
||||
confirmButtonText: $T('CONFIRM'),
|
||||
cancelButtonText: $T('CANCEL'),
|
||||
type: 'info'
|
||||
}).then(() => {
|
||||
sendRPC(IRPCActionType.RELOAD_APP)
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
@@ -121,4 +258,16 @@ export default {
|
||||
--el-collapse-content-bg-color: transparent;
|
||||
--el-collapse-content-font-size: 13px;
|
||||
--el-collapse-content-text-color: #ddd;
|
||||
&-item__content
|
||||
padding-bottom: 12px
|
||||
&-item-msg
|
||||
color: #aaa
|
||||
&-tips
|
||||
padding: 12px 0
|
||||
&-cant-fix
|
||||
display flex
|
||||
justify-content center
|
||||
align-items center
|
||||
&__btn
|
||||
margin-left: 8px
|
||||
</style>
|
||||
|
||||
@@ -49,6 +49,19 @@ export function triggerRPC<T> (action: IRPCActionType, ...args: any[]): Promise<
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* send a rpc request & do not need to wait for the response
|
||||
*
|
||||
* or the response will be handled by other listener
|
||||
*/
|
||||
export function sendRPC (action: IRPCActionType, ...args: any[]): void {
|
||||
const data = getRawData(args)
|
||||
ipcRenderer.send(RPC_ACTIONS, action, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated will be replaced by sendRPC in the future
|
||||
*/
|
||||
export function sendToMain (channel: string, ...args: any[]) {
|
||||
const data = getRawData(args)
|
||||
ipcRenderer.send(channel, ...data)
|
||||
|
||||
@@ -22,7 +22,6 @@ export const MINIMIZE_WINDOW = 'MINIMIZE_WINDOW'
|
||||
export const CLOSE_WINDOW = 'CLOSE_WINDOW'
|
||||
export const OPEN_USER_STORE_FILE = 'OPEN_USER_STORE_FILE'
|
||||
export const OPEN_URL = 'OPEN_URL'
|
||||
export const RELOAD_APP = 'RELOAD_APP'
|
||||
export const PICGO_CONFIG_PLUGIN = 'PICGO_CONFIG_PLUGIN'
|
||||
export const PICGO_HANDLE_PLUGIN_ING = 'PICGO_HANDLE_PLUGIN_ING'
|
||||
export const PICGO_HANDLE_PLUGIN_DONE = 'PICGO_HANDLE_PLUGIN_DONE'
|
||||
|
||||
Vendored
+2
@@ -17,3 +17,5 @@ declare interface IWindowManager {
|
||||
deleteById: (id: number) => void
|
||||
getAvailableWindow: () => BrowserWindow
|
||||
}
|
||||
|
||||
type IpcRendererListener = (event: import('electron').IpcRendererEvent, ...args: any[]) => void
|
||||
|
||||
@@ -52,12 +52,25 @@ export enum IRemoteNoticeTriggerCount {
|
||||
* renderer trigger action from main
|
||||
*/
|
||||
export enum IRPCActionType {
|
||||
// config rpc
|
||||
GET_PICBED_CONFIG_LIST = 'GET_PICBED_CONFIG_LIST',
|
||||
DELETE_PICBED_CONFIG = 'DELETE_PICBED_CONFIG',
|
||||
CHANGE_CURRENT_UPLOADER = 'CHANGE_CURRENT_UPLOADER',
|
||||
SELECT_UPLOADER = 'SELECT_UPLOADER',
|
||||
UPDATE_UPLOADER_CONFIG = 'UPDATE_UPLOADER_CONFIG',
|
||||
|
||||
// version rpc
|
||||
GET_LATEST_VERSION = 'GET_LATEST_VERSION',
|
||||
|
||||
// toolbox rpc
|
||||
TOOLBOX_CHECK = 'TOOLBOX_CHECK',
|
||||
TOOLBOX_CHECK_RES = 'TOOLBOX_CHECK_RES',
|
||||
TOOLBOX_CHECK_FIX = 'TOOLBOX_CHECK_FIX',
|
||||
|
||||
// system rpc
|
||||
RELOAD_APP = 'RELOAD_APP',
|
||||
OPEN_FILE = 'OPEN_FILE',
|
||||
COPY_TEXT = 'COPY_TEXT'
|
||||
}
|
||||
|
||||
export enum IToolboxItemType {
|
||||
@@ -66,3 +79,10 @@ export enum IToolboxItemType {
|
||||
HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD = 'HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD',
|
||||
HAS_PROBLEM_WITH_PROXY = 'HAS_PROBLEM_WITH_PROXY',
|
||||
}
|
||||
|
||||
export enum IToolboxItemCheckStatus {
|
||||
INIT = 'init',
|
||||
LOADING = 'loading',
|
||||
SUCCESS = 'success',
|
||||
ERROR = 'error',
|
||||
}
|
||||
|
||||
Vendored
+25
@@ -52,6 +52,8 @@ interface ILocales {
|
||||
COPY_LINK_SUCCEED: string
|
||||
BATCH_COPY_LINK_SUCCEED: string
|
||||
FILE_RENAME: string
|
||||
COPY_FILE_PATH: string
|
||||
OPEN_FILE_PATH: string
|
||||
SETTINGS: string
|
||||
SETTINGS_OPEN_CONFIG_FILE: string
|
||||
SETTINGS_CLICK_TO_OPEN: string
|
||||
@@ -164,6 +166,29 @@ interface ILocales {
|
||||
UNINSTALL_PLUGIN: string
|
||||
UPDATE_PLUGIN: string
|
||||
TOOLBOX: string
|
||||
TOOLBOX_TITLE: string
|
||||
TOOLBOX_SUB_TITLE: string
|
||||
TOOLBOX_CHECK_CONFIG_FILE_BROKEN: string
|
||||
TOOLBOX_CHECK_GALLERY_FILE_BROKEN: string
|
||||
TOOLBOX_CHECK_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD: string
|
||||
TOOLBOX_CHECK_PROBLEM_WITH_PROXY: string
|
||||
TOOLBOX_FIX_DONE_NEED_RELOAD: string
|
||||
TOOLBOX_CANT_AUTO_FIX: string
|
||||
TOOLBOX_START_SCAN: string
|
||||
TOOLBOX_RE_SCAN: string
|
||||
TOOLBOX_START_FIX: string
|
||||
TOOLBOX_SUCCESS_TIPS: string
|
||||
TOOLBOX_CHECK_CONFIG_FILE_PATH_TIPS: string
|
||||
TOOLBOX_CHECK_CONFIG_FILE_BROKEN_TIPS: string
|
||||
TOOLBOX_CHECK_GALLERY_FILE_PATH_TIPS: string
|
||||
TOOLBOX_CHECK_GALLERY_FILE_BROKEN_TIPS: string
|
||||
TOOLBOX_CHECK_PROXY_SUCCESS_TIPS: string
|
||||
TOOLBOX_CHECK_PROXY_NO_PROXY_TIPS: string
|
||||
TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_CORRECT: string
|
||||
TOOLBOX_CHECK_PROXY_PROXY_IS_NOT_WORKING: string
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_TIPS: string
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_NOT_EXIST_TIPS: string
|
||||
TOOLBOX_CHECK_CLIPBOARD_FILE_PATH_ERROR_TIPS: string
|
||||
TIPS_NOTICE: string
|
||||
TIPS_WARNING: string
|
||||
TIPS_ERROR: string
|
||||
|
||||
Vendored
+36
@@ -1,5 +1,41 @@
|
||||
|
||||
type IGetUploaderConfigListArgs = [type: string]
|
||||
type IDeleteUploaderConfigArgs = [type: string, id: string]
|
||||
type ISelectUploaderConfigArgs = [type: string, id: string]
|
||||
type IUpdateUploaderConfigArgs = [type: string, id: string, config: IStringKeyMap]
|
||||
type IGetLatestVersionArgs = [isCheckBetaVersion: boolean]
|
||||
type IToolboxCheckArgs = [type: import('./enum').IToolboxItemType]
|
||||
type IOpenFileArgs = [filePath: string]
|
||||
type ICopyTextArgs = [text: string]
|
||||
|
||||
interface IRPCServer {
|
||||
start: () => void
|
||||
stop: () => void
|
||||
use: (routes: IRPCRoutes) => void
|
||||
}
|
||||
|
||||
type IRPCRoutes = Map<import('./enum').IRPCActionType, IRPCHandler<any>>
|
||||
|
||||
type IRPCHandler<T> = (args: any[], event: import('electron').IpcMainEvent) => Promise<T>
|
||||
|
||||
interface IRPCRouter {
|
||||
add<T>(action: import('./enum').IRPCActionType, handler: IRPCHandler<T>): IRPCRouter
|
||||
routes: () => IRPCRoutes
|
||||
}
|
||||
|
||||
type IToolboxChecker<T = any> = (event: import('electron').IpcMainEvent) => Promise<T>
|
||||
|
||||
type IToolboxCheckerMap<T extends import('./enum').IToolboxItemType> = {
|
||||
[type in T]: IToolboxChecker
|
||||
}
|
||||
|
||||
type IToolboxFixMap<T extends import('./enum').IToolboxItemType> = {
|
||||
[type in T]: IToolboxChecker<IToolboxCheckRes>
|
||||
}
|
||||
|
||||
type IToolboxCheckRes = {
|
||||
type: import('./enum').IToolboxItemType
|
||||
status: import('./enum').IToolboxItemCheckStatus,
|
||||
msg?: string
|
||||
value?: any
|
||||
}
|
||||
|
||||
-5
@@ -3,8 +3,3 @@ declare module '*.vue' {
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
// // third-party
|
||||
// declare module 'fix-path' {
|
||||
// function fixPath(): void
|
||||
// export default fixPath
|
||||
// }
|
||||
|
||||
Vendored
+10
-3
@@ -20,8 +20,15 @@ interface IShortKeyMap {
|
||||
}
|
||||
|
||||
interface IToolboxItem {
|
||||
id: import('#/types/enum').IToolboxItemType
|
||||
title: string
|
||||
status: 'loading' | 'success' | 'error' | 'init'
|
||||
errorTips?: string[]
|
||||
status: import('#/types/enum').IToolboxItemCheckStatus
|
||||
msg?: string
|
||||
value?: any // for handler
|
||||
hasNoFixMethod?: boolean
|
||||
handler?: (value: any) => Promise<void> | void
|
||||
handlerText?: string
|
||||
}
|
||||
|
||||
type IToolboxMap = {
|
||||
[id in import('#/types/enum').IToolboxItemType]: IToolboxItem
|
||||
}
|
||||
|
||||
@@ -2982,6 +2982,13 @@
|
||||
resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40"
|
||||
integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==
|
||||
|
||||
"@types/tunnel@^0.0.3":
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.3.tgz#f109e730b072b3136347561fc558c9358bb8c6e9"
|
||||
integrity sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/uuid@8.3.1":
|
||||
version "8.3.1"
|
||||
resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f"
|
||||
|
||||
Reference in New Issue
Block a user