mirror of
https://github.com/Kuingsmile/PicList.git
synced 2025-03-13 00:18:13 -04:00
📦 Chore: update electron from v6 -> v16
This commit is contained in:
parent
459953f391
commit
ea20d3b971
22
.eslintrc.js
22
.eslintrc.js
@ -6,20 +6,32 @@ module.exports = {
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
parser: "vue-eslint-parser",
|
||||
'extends': [
|
||||
parser: 'vue-eslint-parser',
|
||||
extends: [
|
||||
'plugin:vue/essential',
|
||||
'@vue/standard',
|
||||
'@vue/typescript'
|
||||
],
|
||||
'plugins': ['@typescript-eslint'],
|
||||
plugins: ['@typescript-eslint'],
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'off' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
"indent": "off",
|
||||
"@typescript-eslint/indent": ["error", 2]
|
||||
indent: 'off',
|
||||
'no-async-promise-executor': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'@typescript-eslint/indent': ['error', 2]
|
||||
},
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser'
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts', '*.vue'],
|
||||
rules: {
|
||||
'no-undef': 'off' // https://typescript-eslint.io/docs/linting/troubleshooting/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
|
||||
}
|
||||
}
|
||||
],
|
||||
ignorePatterns: ['src/**/*.d.ts']
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
],
|
||||
plugins: ['@babel/plugin-proposal-optional-chaining']
|
||||
}
|
||||
|
37
package.json
37
package.json
@ -6,6 +6,7 @@
|
||||
"dev": "vue-cli-service electron:serve",
|
||||
"build": "vue-cli-service electron:build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"lint:fix": "eslint --fix --ext .js,.jsx,.ts,.tsx,.vue src/",
|
||||
"electron:build": "vue-cli-service electron:build",
|
||||
"electron:serve": "vue-cli-service electron:serve",
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
@ -39,7 +40,7 @@
|
||||
"core-js": "^3.3.2",
|
||||
"element-ui": "^2.13.0",
|
||||
"fix-path": "^2.1.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"keycode": "^2.2.0",
|
||||
"lodash-id": "^0.14.0",
|
||||
"lowdb": "^1.0.0",
|
||||
@ -52,36 +53,42 @@
|
||||
"vue-router": "^3.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^8.2.0",
|
||||
"@picgo/bump-version": "^1.0.3",
|
||||
"@types/fs-extra": "^8.0.1",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.16.7",
|
||||
"@picgo/bump-version": "^1.1.2",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/inquirer": "^6.5.0",
|
||||
"@types/lowdb": "^1.0.9",
|
||||
"@types/node": "10.17.6",
|
||||
"@types/node": "^16.10.2",
|
||||
"@types/request-promise-native": "^1.0.17",
|
||||
"@types/semver": "^7.3.8",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"@vue/cli-plugin-babel": "^4.0.0",
|
||||
"@vue/cli-plugin-eslint": "^4.0.0",
|
||||
"@vue/cli-plugin-router": "^4.0.0",
|
||||
"@vue/cli-plugin-typescript": "^4.0.0",
|
||||
"@vue/cli-plugin-typescript": "^4.5.13",
|
||||
"@vue/cli-service": "^4.0.0",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"@vue/eslint-config-typescript": "^4.0.0",
|
||||
"commitizen": "^4.0.3",
|
||||
"@vue/eslint-config-standard": "^6.1.0",
|
||||
"@vue/eslint-config-typescript": "^7.0.0",
|
||||
"conventional-changelog": "^3.1.18",
|
||||
"cz-customizable": "^6.2.0",
|
||||
"electron": "^6.0.0",
|
||||
"electron": "^16.0.6",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-standard": ">=16.0.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-vue": "^7.0.0",
|
||||
"husky": "^3.1.0",
|
||||
"stylus": "^0.54.7",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"typescript": "~3.7.3",
|
||||
"vue-cli-plugin-electron-builder": "^1.4.2",
|
||||
"typescript": "^4.4.3",
|
||||
"vue-cli-plugin-electron-builder": "^2.1.1",
|
||||
"vue-property-decorator": "^8.3.0",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/node": "12.0.2"
|
||||
"@types/node": "^16.10.2"
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import { initTalkingData } from './renderer/utils/analytics'
|
||||
import db from './renderer/utils/db'
|
||||
|
||||
webFrame.setVisualZoomLevelLimits(1, 1)
|
||||
webFrame.setLayoutZoomLevelLimits(0, 0)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$builtInPicBed = [
|
||||
|
@ -6,7 +6,7 @@ The lowest level APIs that are not dependent on each other. The upper APIs depen
|
||||
|
||||
## app
|
||||
|
||||
Provide key API interfaces for PicGo application, including uploader, window management, shortcut key system, etc
|
||||
Provide key API interfaces for PicGo application, including uploader, window management, shortcut key system, remotes handler, etc
|
||||
|
||||
## gui
|
||||
|
||||
|
@ -16,10 +16,12 @@ class ShortKeyHandler {
|
||||
this.isInModifiedMode = flag
|
||||
})
|
||||
}
|
||||
|
||||
init () {
|
||||
this.initBuiltInShortKey()
|
||||
this.initPluginsShortKey()
|
||||
}
|
||||
|
||||
private initBuiltInShortKey () {
|
||||
const commands = db.get('settings.shortKey') as IShortKeyConfigs
|
||||
Object.keys(commands)
|
||||
@ -34,10 +36,11 @@ class ShortKeyHandler {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private initPluginsShortKey () {
|
||||
// get enabled plugin
|
||||
const pluginList = picgo.pluginLoader.getList()
|
||||
for (let item of pluginList) {
|
||||
for (const item of pluginList) {
|
||||
const plugin = picgo.pluginLoader.getPlugin(item)
|
||||
// if a plugin has commands
|
||||
if (plugin && plugin.commands) {
|
||||
@ -46,7 +49,7 @@ class ShortKeyHandler {
|
||||
continue
|
||||
}
|
||||
const commands = plugin.commands(picgo) as IPluginShortKeyConfig[]
|
||||
for (let cmd of commands) {
|
||||
for (const cmd of commands) {
|
||||
const command = `${item}:${cmd.name}`
|
||||
if (db.has(`settings.shortKey[${command}]`)) {
|
||||
const commandConfig = db.get(`settings.shortKey.${command}`) as IShortKeyConfig
|
||||
@ -63,6 +66,7 @@ class ShortKeyHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private registerShortKey (config: IShortKeyConfig | IPluginShortKeyConfig, command: string, handler: IShortKeyHandler, writeFlag: boolean) {
|
||||
shortKeyService.registerCommand(command, handler)
|
||||
if (config.key) {
|
||||
@ -85,6 +89,7 @@ class ShortKeyHandler {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// enable or disable shortKey
|
||||
bindOrUnbindShortKey (item: IShortKeyConfig, from: string): boolean {
|
||||
const command = `${from}:${item.name}`
|
||||
@ -108,6 +113,7 @@ class ShortKeyHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update shortKey bindings
|
||||
updateShortKey (item: IShortKeyConfig, oldKey: string, from: string): boolean {
|
||||
const command = `${from}:${item.name}`
|
||||
@ -121,6 +127,7 @@ class ShortKeyHandler {
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
private async handler (command: string) {
|
||||
if (this.isInModifiedMode) {
|
||||
return
|
||||
@ -136,6 +143,7 @@ class ShortKeyHandler {
|
||||
logger.warn(`can not find command: ${command}`)
|
||||
}
|
||||
}
|
||||
|
||||
registerPluginShortKey (pluginName: string) {
|
||||
const plugin = picgo.pluginLoader.getPlugin(pluginName)
|
||||
if (plugin && plugin.commands) {
|
||||
@ -144,7 +152,7 @@ class ShortKeyHandler {
|
||||
return
|
||||
}
|
||||
const commands = plugin.commands(picgo) as IPluginShortKeyConfig[]
|
||||
for (let cmd of commands) {
|
||||
for (const cmd of commands) {
|
||||
const command = `${pluginName}:${cmd.name}`
|
||||
if (db.has(`settings.shortKey[${command}]`)) {
|
||||
const commandConfig = db.get(`settings.shortKey[${command}]`) as IShortKeyConfig
|
||||
@ -155,6 +163,7 @@ class ShortKeyHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unregisterPluginShortKey (pluginName: string) {
|
||||
const commands = db.get('settings.shortKey') as IShortKeyConfigs
|
||||
const keyList = Object.keys(commands)
|
||||
|
@ -4,15 +4,18 @@ class ShortKeyService {
|
||||
registerCommand (command: string, handler: IShortKeyHandler) {
|
||||
this.commandList.set(command, handler)
|
||||
}
|
||||
|
||||
unregisterCommand (command: string) {
|
||||
this.commandList.delete(command)
|
||||
}
|
||||
|
||||
getShortKeyHandler (command: string): IShortKeyHandler | null {
|
||||
const handler = this.commandList.get(command)
|
||||
if (handler) return handler
|
||||
logger.warn(`cannot find command: ${command}`)
|
||||
return null
|
||||
}
|
||||
|
||||
getCommandList () {
|
||||
return [...this.commandList.keys()]
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import db, { GalleryDB } from '~/main/apis/core/datastore'
|
||||
import windowManager from 'apis/app/window/windowManager'
|
||||
import { IWindowList } from 'apis/app/window/constants'
|
||||
import picgo from '@core/picgo'
|
||||
import pasteTemplate from '#/utils/pasteTemplate'
|
||||
import pasteTemplate from '~/main/utils/pasteTemplate'
|
||||
import pkg from 'root/package.json'
|
||||
import { handleCopyUrl } from '~/main/utils/common'
|
||||
import { privacyManager } from '~/main/utils/privacyManager'
|
||||
@ -162,8 +162,8 @@ export function createTray () {
|
||||
if (process.platform === 'darwin') {
|
||||
toggleWindow(bounds)
|
||||
setTimeout(() => {
|
||||
let img = clipboard.readImage()
|
||||
let obj: ImgInfo[] = []
|
||||
const img = clipboard.readImage()
|
||||
const obj: ImgInfo[] = []
|
||||
if (!img.isEmpty()) {
|
||||
// 从剪贴板来的图片默认转为png
|
||||
// @ts-ignore
|
||||
|
@ -5,13 +5,13 @@ import {
|
||||
import windowManager from 'apis/app/window/windowManager'
|
||||
import { IWindowList } from 'apis/app/window/constants'
|
||||
import uploader from '.'
|
||||
import pasteTemplate from '#/utils/pasteTemplate'
|
||||
import pasteTemplate from '~/main/utils/pasteTemplate'
|
||||
import db, { GalleryDB } from '~/main/apis/core/datastore'
|
||||
import { handleCopyUrl } from '~/main/utils/common'
|
||||
import { handleUrlEncode } from '#/utils/common'
|
||||
export const uploadClipboardFiles = async (): Promise<string> => {
|
||||
const win = windowManager.getAvailableWindow()
|
||||
let img = await uploader.setWebContents(win!.webContents).upload()
|
||||
const img = await uploader.setWebContents(win!.webContents).upload()
|
||||
if (img !== false) {
|
||||
if (img.length > 0) {
|
||||
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)
|
||||
|
@ -16,7 +16,7 @@ import { TALKING_DATA_EVENT } from '~/universal/events/constants'
|
||||
import logger from '@core/picgo/logger'
|
||||
|
||||
const waitForShow = (webcontent: WebContents) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
return new Promise<void>((resolve) => {
|
||||
webcontent.on('did-finish-load', () => {
|
||||
resolve()
|
||||
})
|
||||
@ -24,7 +24,7 @@ const waitForShow = (webcontent: WebContents) => {
|
||||
}
|
||||
|
||||
const waitForRename = (window: BrowserWindow, id: number): Promise<string|null> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
const windowId = window.id
|
||||
ipcMain.once(`rename${id}`, (evt: Event, newName: string) => {
|
||||
resolve(newName)
|
||||
@ -68,7 +68,7 @@ class Uploader {
|
||||
picgo.on('uploadProgress', progress => {
|
||||
this.webContents?.send('uploadProgress', progress)
|
||||
})
|
||||
picgo.on('beforeTransform', ctx => {
|
||||
picgo.on('beforeTransform', () => {
|
||||
if (db.get('settings.uploadNotification')) {
|
||||
const notification = new Notification({
|
||||
title: '上传进度',
|
||||
@ -125,7 +125,7 @@ class Uploader {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
logger.error(e)
|
||||
setTimeout(() => {
|
||||
showNotification({
|
||||
|
@ -9,16 +9,16 @@ const isDevelopment = process.env.NODE_ENV !== 'production'
|
||||
|
||||
export const TRAY_WINDOW_URL = isDevelopment
|
||||
? (process.env.WEBPACK_DEV_SERVER_URL as string)
|
||||
: `picgo://./index.html`
|
||||
: 'picgo://./index.html'
|
||||
|
||||
export const SETTING_WINDOW_URL = isDevelopment
|
||||
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#main-page/upload`
|
||||
: `picgo://./index.html#main-page/upload`
|
||||
: 'picgo://./index.html#main-page/upload'
|
||||
|
||||
export const MINI_WINDOW_URL = isDevelopment
|
||||
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#mini-page`
|
||||
: `picgo://./index.html#mini-page`
|
||||
: 'picgo://./index.html#mini-page'
|
||||
|
||||
export const RENAME_WINDOW_URL = process.env.NODE_ENV === 'development'
|
||||
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#rename-page`
|
||||
: `picgo://./index.html#rename-page`
|
||||
: 'picgo://./index.html#rename-page'
|
||||
|
@ -28,7 +28,8 @@ windowList.set(IWindowList.TRAY_WINDOW, {
|
||||
transparent: true,
|
||||
vibrancy: 'ultra-dark',
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
|
||||
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
|
||||
nodeIntegrationInWorker: true,
|
||||
backgroundThrottling: false
|
||||
}
|
||||
@ -60,7 +61,8 @@ windowList.set(IWindowList.SETTING_WINDOW, {
|
||||
titleBarStyle: 'hidden',
|
||||
webPreferences: {
|
||||
backgroundThrottling: false,
|
||||
nodeIntegration: true,
|
||||
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
|
||||
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
|
||||
nodeIntegrationInWorker: true,
|
||||
webSecurity: false
|
||||
}
|
||||
@ -93,7 +95,7 @@ windowList.set(IWindowList.MINI_WINDOW, {
|
||||
isValid: process.platform !== 'darwin',
|
||||
multiple: false,
|
||||
options () {
|
||||
let obj: IBrowserWindowOptions = {
|
||||
const obj: IBrowserWindowOptions = {
|
||||
height: 64,
|
||||
width: 64,
|
||||
show: process.platform === 'linux',
|
||||
@ -105,7 +107,8 @@ windowList.set(IWindowList.MINI_WINDOW, {
|
||||
icon: `${__static}/logo.png`,
|
||||
webPreferences: {
|
||||
backgroundThrottling: false,
|
||||
nodeIntegration: true,
|
||||
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
|
||||
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
|
||||
nodeIntegrationInWorker: true
|
||||
}
|
||||
}
|
||||
@ -124,7 +127,7 @@ windowList.set(IWindowList.RENAME_WINDOW, {
|
||||
isValid: true,
|
||||
multiple: true,
|
||||
options () {
|
||||
let options: IBrowserWindowOptions = {
|
||||
const options: IBrowserWindowOptions = {
|
||||
height: 175,
|
||||
width: 300,
|
||||
show: true,
|
||||
@ -132,7 +135,8 @@ windowList.set(IWindowList.RENAME_WINDOW, {
|
||||
resizable: false,
|
||||
vibrancy: 'ultra-dark',
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
|
||||
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
|
||||
nodeIntegrationInWorker: true,
|
||||
backgroundThrottling: false
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ class WindowManager implements IWindowManager {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
get (name: IWindowList) {
|
||||
if (this.has(name)) {
|
||||
return this.windowMap.get(name)!
|
||||
@ -42,9 +43,11 @@ class WindowManager implements IWindowManager {
|
||||
return window
|
||||
}
|
||||
}
|
||||
|
||||
has (name: IWindowList) {
|
||||
return this.windowMap.has(name)
|
||||
}
|
||||
|
||||
// useless
|
||||
// delete (name: IWindowList) {
|
||||
// const window = this.windowMap.get(name)
|
||||
@ -60,6 +63,7 @@ class WindowManager implements IWindowManager {
|
||||
this.windowIdMap.delete(id)
|
||||
}
|
||||
}
|
||||
|
||||
getAvailableWindow () {
|
||||
const miniWindow = this.windowMap.get(IWindowList.MINI_WINDOW)
|
||||
if (miniWindow && miniWindow.isVisible()) {
|
||||
|
@ -14,7 +14,7 @@ export const uploadWithClipboardFiles = (): Promise<{
|
||||
success: boolean,
|
||||
result?: string[]
|
||||
}> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
bus.once(UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE, (result: string) => {
|
||||
if (result) {
|
||||
return resolve({
|
||||
@ -35,7 +35,7 @@ export const uploadWithFiles = (pathList: IFileWithPath[]): Promise<{
|
||||
success: boolean,
|
||||
result?: string[]
|
||||
}> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
bus.once(UPLOAD_WITH_FILES_RESPONSE, (result: string[]) => {
|
||||
if (result.length) {
|
||||
return resolve({
|
||||
@ -55,7 +55,7 @@ export const uploadWithFiles = (pathList: IFileWithPath[]): Promise<{
|
||||
// get available window id:
|
||||
// miniWindow or settingWindow or trayWindow
|
||||
export const getWindowId = (): Promise<number> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
bus.once(GET_WINDOW_ID_REPONSE, (id: number) => {
|
||||
resolve(id)
|
||||
})
|
||||
@ -65,7 +65,7 @@ export const getWindowId = (): Promise<number> => {
|
||||
|
||||
// get settingWindow id:
|
||||
export const getSettingWindowId = (): Promise<number> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
bus.once(GET_SETTING_WINDOW_ID_RESPONSE, (id: number) => {
|
||||
resolve(id)
|
||||
})
|
||||
|
@ -1,9 +1,8 @@
|
||||
import fs from 'fs-extra'
|
||||
import path from 'path'
|
||||
import { remote, app } from 'electron'
|
||||
import dayjs from 'dayjs'
|
||||
import { app as APP } from 'electron'
|
||||
import { getLogger } from '@core/utils/localLogger'
|
||||
const APP = process.type === 'renderer' ? remote.app : app
|
||||
import dayjs from 'dayjs'
|
||||
const STORE_PATH = APP.getPath('userData')
|
||||
const configFilePath = path.join(STORE_PATH, 'data.json')
|
||||
const configFileBackupPath = path.join(STORE_PATH, 'data.bak.json')
|
||||
@ -36,7 +35,7 @@ function dbChecker () {
|
||||
return
|
||||
}
|
||||
let configFile: string = '{}'
|
||||
let optionsTpl = {
|
||||
const optionsTpl = {
|
||||
title: '注意',
|
||||
body: ''
|
||||
}
|
||||
@ -98,7 +97,7 @@ function dbPathChecker (): string {
|
||||
const picgoLogPath = path.join(defaultConfigPath, 'picgo.log')
|
||||
const logger = getLogger(picgoLogPath)
|
||||
if (!hasCheckPath) {
|
||||
let optionsTpl = {
|
||||
const optionsTpl = {
|
||||
title: '注意',
|
||||
body: '自定义文件解析出错,请检查路径内容是否正确'
|
||||
}
|
||||
|
@ -42,33 +42,42 @@ class ConfigStore {
|
||||
}).write()
|
||||
}
|
||||
}
|
||||
|
||||
read () {
|
||||
return this.db.read()
|
||||
}
|
||||
|
||||
get (key = '') {
|
||||
return this.read().get(key).value()
|
||||
}
|
||||
|
||||
set (key: string, value: any) {
|
||||
return this.read().set(key, value).write()
|
||||
}
|
||||
|
||||
has (key: string) {
|
||||
return this.read().has(key).value()
|
||||
}
|
||||
|
||||
insert (key: string, value: any): void {
|
||||
// @ts-ignore
|
||||
return this.read().get(key).insert(value).write()
|
||||
}
|
||||
|
||||
unset (key: string, value: any): boolean {
|
||||
return this.read().get(key).unset(value).value()
|
||||
}
|
||||
|
||||
getById (key: string, id: string) {
|
||||
// @ts-ignore
|
||||
return this.read().get(key).getById(id).value()
|
||||
}
|
||||
|
||||
removeById (key: string, id: string) {
|
||||
// @ts-ignore
|
||||
return this.read().get(key).removeById(id).write()
|
||||
}
|
||||
|
||||
getConfigPath () {
|
||||
return CONFIG_PATH
|
||||
}
|
||||
@ -82,6 +91,7 @@ class GalleryDB {
|
||||
private constructor () {
|
||||
console.log('init gallery db')
|
||||
}
|
||||
|
||||
public static getInstance (): DBStore {
|
||||
if (!GalleryDB.instance) {
|
||||
GalleryDB.instance = new DBStore(DB_PATH, 'gallery')
|
||||
|
@ -8,7 +8,7 @@ import path from 'path'
|
||||
import db, { GalleryDB } from 'apis/core/datastore'
|
||||
import { dbPathChecker, defaultConfigPath, getGalleryDBPath } from 'apis/core/datastore/dbChecker'
|
||||
import uploader from 'apis/app/uploader'
|
||||
import pasteTemplate from '#/utils/pasteTemplate'
|
||||
import pasteTemplate from '~/main/utils/pasteTemplate'
|
||||
import { handleCopyUrl } from '~/main/utils/common'
|
||||
import {
|
||||
getWindowId,
|
||||
@ -28,20 +28,22 @@ class GuiApi implements IGuiApi {
|
||||
private constructor () {
|
||||
console.log('init guiapi')
|
||||
}
|
||||
|
||||
public static getInstance (): GuiApi {
|
||||
if (!GuiApi.instance) {
|
||||
GuiApi.instance = new GuiApi()
|
||||
}
|
||||
return GuiApi.instance
|
||||
}
|
||||
|
||||
private async showSettingWindow () {
|
||||
this.settingWindowId = await getSettingWindowId()
|
||||
const settingWindow = BrowserWindow.fromId(this.settingWindowId)
|
||||
if (settingWindow.isVisible()) {
|
||||
if (settingWindow?.isVisible()) {
|
||||
return true
|
||||
}
|
||||
settingWindow.show()
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
settingWindow?.show()
|
||||
return new Promise<void>((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve()
|
||||
}, 1000) // TODO: a better way to wait page loaded.
|
||||
@ -49,7 +51,7 @@ class GuiApi implements IGuiApi {
|
||||
}
|
||||
|
||||
private getWebcontentsByWindowId (id: number) {
|
||||
return BrowserWindow.fromId(id).webContents
|
||||
return BrowserWindow.fromId(id)?.webContents
|
||||
}
|
||||
|
||||
async showInputBox (options: IShowInputBoxOption = {
|
||||
@ -57,28 +59,24 @@ class GuiApi implements IGuiApi {
|
||||
placeholder: ''
|
||||
}) {
|
||||
await this.showSettingWindow()
|
||||
this.getWebcontentsByWindowId(this.settingWindowId)
|
||||
.send(SHOW_INPUT_BOX, options)
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
this.getWebcontentsByWindowId(this.settingWindowId)?.send(SHOW_INPUT_BOX, options)
|
||||
return new Promise<string>((resolve) => {
|
||||
ipcMain.once(SHOW_INPUT_BOX, (event: Event, value: string) => {
|
||||
resolve(value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
showFileExplorer (options: IShowFileExplorerOption = {}) {
|
||||
return new Promise<string>(async (resolve, reject) => {
|
||||
async showFileExplorer (options: IShowFileExplorerOption = {}) {
|
||||
this.windowId = await getWindowId()
|
||||
dialog.showOpenDialog(BrowserWindow.fromId(this.windowId), options, (filename: string) => {
|
||||
resolve(filename)
|
||||
})
|
||||
})
|
||||
const res = await dialog.showOpenDialog(BrowserWindow.fromId(this.windowId)!, options)
|
||||
return res.filePaths?.[0]
|
||||
}
|
||||
|
||||
async upload (input: IUploadOption) {
|
||||
this.windowId = await getWindowId()
|
||||
const webContents = this.getWebcontentsByWindowId(this.windowId)
|
||||
const imgs = await uploader.setWebContents(webContents).upload(input)
|
||||
const imgs = await uploader.setWebContents(webContents!).upload(input)
|
||||
if (imgs !== false) {
|
||||
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
||||
const pasteText: string[] = []
|
||||
@ -95,8 +93,8 @@ class GuiApi implements IGuiApi {
|
||||
await GalleryDB.getInstance().insert(imgs[i])
|
||||
}
|
||||
handleCopyUrl(pasteText.join('\n'))
|
||||
webContents.send('uploadFiles', imgs)
|
||||
webContents.send('updateGallery')
|
||||
webContents?.send('uploadFiles', imgs)
|
||||
webContents?.send('updateGallery')
|
||||
return imgs
|
||||
}
|
||||
return []
|
||||
@ -119,10 +117,10 @@ class GuiApi implements IGuiApi {
|
||||
type: 'info',
|
||||
buttons: ['Yes', 'No']
|
||||
}) {
|
||||
return new Promise<IShowMessageBoxResult>(async (resolve, reject) => {
|
||||
return new Promise<IShowMessageBoxResult>(async (resolve) => {
|
||||
this.windowId = await getWindowId()
|
||||
dialog.showMessageBox(
|
||||
BrowserWindow.fromId(this.windowId),
|
||||
BrowserWindow.fromId(this.windowId)!,
|
||||
options
|
||||
).then((res) => {
|
||||
resolve({
|
||||
|
@ -28,7 +28,7 @@ function initEventCenter () {
|
||||
[GET_SETTING_WINDOW_ID]: busCallGetSettingWindowId,
|
||||
[CREATE_APP_MENU]: createMenu
|
||||
}
|
||||
for (let i in eventList) {
|
||||
for (const i in eventList) {
|
||||
bus.on(i, eventList[i])
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
import {
|
||||
app,
|
||||
ipcMain,
|
||||
shell,
|
||||
Notification,
|
||||
IpcMainEvent
|
||||
IpcMainEvent,
|
||||
BrowserWindow
|
||||
} from 'electron'
|
||||
import windowManager from 'apis/app/window/windowManager'
|
||||
import { IWindowList } from 'apis/app/window/constants'
|
||||
import uploader from 'apis/app/uploader'
|
||||
import pasteTemplate from '#/utils/pasteTemplate'
|
||||
import pasteTemplate from '~/main/utils/pasteTemplate'
|
||||
import db, { GalleryDB } from '~/main/apis/core/datastore'
|
||||
import server from '~/main/server'
|
||||
import getPicBeds from '~/main/utils/getPicBeds'
|
||||
@ -15,7 +17,16 @@ import shortKeyHandler from 'apis/app/shortKey/shortKeyHandler'
|
||||
import bus from '@core/bus'
|
||||
import {
|
||||
TOGGLE_SHORTKEY_MODIFIED_MODE,
|
||||
OPEN_DEVTOOLS
|
||||
OPEN_DEVTOOLS,
|
||||
SHOW_MINI_PAGE_MENU,
|
||||
MINIMIZE_WINDOW,
|
||||
CLOSE_WINDOW,
|
||||
SHOW_MAIN_PAGE_MENU,
|
||||
SHOW_UPLOAD_PAGE_MENU,
|
||||
OPEN_USER_STORE_FILE,
|
||||
OPEN_URL,
|
||||
RELOAD_APP,
|
||||
SHOW_PLUGIN_PAGE_MENU
|
||||
} from '#/events/constants'
|
||||
import {
|
||||
uploadClipboardFiles,
|
||||
@ -23,6 +34,10 @@ import {
|
||||
} from '~/main/apis/app/uploader/apis'
|
||||
import picgoCoreIPC from './picgoCoreIPC'
|
||||
import { handleCopyUrl } from '~/main/utils/common'
|
||||
import { buildMainPageMenu, buildMiniPageMenu, buildPluginPageMenu, buildUploadPageMenu } from './remotes/menu'
|
||||
import path from 'path'
|
||||
|
||||
const STORE_PATH = app.getPath('userData')
|
||||
|
||||
export default {
|
||||
listen () {
|
||||
@ -145,6 +160,58 @@ export default {
|
||||
ipcMain.on(OPEN_DEVTOOLS, (event: IpcMainEvent) => {
|
||||
event.sender.openDevTools()
|
||||
})
|
||||
// menu & window methods
|
||||
ipcMain.on(SHOW_MINI_PAGE_MENU, () => {
|
||||
const window = windowManager.get(IWindowList.MINI_WINDOW)!
|
||||
const menu = buildMiniPageMenu()
|
||||
menu.popup({
|
||||
window
|
||||
})
|
||||
})
|
||||
ipcMain.on(SHOW_MAIN_PAGE_MENU, () => {
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
const menu = buildMainPageMenu()
|
||||
menu.popup({
|
||||
window
|
||||
})
|
||||
})
|
||||
ipcMain.on(SHOW_UPLOAD_PAGE_MENU, () => {
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
const menu = buildUploadPageMenu()
|
||||
menu.popup({
|
||||
window
|
||||
})
|
||||
})
|
||||
ipcMain.on(SHOW_PLUGIN_PAGE_MENU, (evt: IpcMainEvent, plugin: IPicGoPlugin) => {
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
const menu = buildPluginPageMenu(plugin)
|
||||
menu.popup({
|
||||
window
|
||||
})
|
||||
})
|
||||
ipcMain.on(MINIMIZE_WINDOW, () => {
|
||||
const window = BrowserWindow.getFocusedWindow()
|
||||
window?.minimize()
|
||||
})
|
||||
ipcMain.on(CLOSE_WINDOW, () => {
|
||||
const window = BrowserWindow.getFocusedWindow()
|
||||
if (process.platform === 'linux') {
|
||||
window?.hide()
|
||||
} else {
|
||||
window?.close()
|
||||
}
|
||||
})
|
||||
ipcMain.on(OPEN_USER_STORE_FILE, (evt: IpcMainEvent, filePath: string) => {
|
||||
const abFilePath = path.join(STORE_PATH, filePath)
|
||||
shell.openPath(abFilePath)
|
||||
})
|
||||
ipcMain.on(OPEN_URL, (evt: IpcMainEvent, url: string) => {
|
||||
shell.openExternal(url)
|
||||
})
|
||||
ipcMain.on(RELOAD_APP, () => {
|
||||
app.relaunch()
|
||||
app.exit(0)
|
||||
})
|
||||
},
|
||||
dispose () {}
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ import {
|
||||
dialog,
|
||||
shell,
|
||||
IpcMainEvent,
|
||||
ipcMain
|
||||
ipcMain,
|
||||
clipboard
|
||||
} from 'electron'
|
||||
import PicGoCore from '~/universal/types/picgo'
|
||||
import { IPicGoHelperType } from '#/types/enum'
|
||||
import { IPasteStyle, IPicGoHelperType } from '#/types/enum'
|
||||
import shortKeyHandler from 'apis/app/shortKey/shortKeyHandler'
|
||||
import picgo from '@core/picgo'
|
||||
import { handleStreamlinePluginName } from '~/universal/utils/common'
|
||||
@ -25,11 +26,13 @@ import {
|
||||
PICGO_UPDATE_BY_ID_DB,
|
||||
PICGO_GET_BY_ID_DB,
|
||||
PICGO_REMOVE_BY_ID_DB,
|
||||
PICGO_OPEN_FILE
|
||||
PICGO_OPEN_FILE,
|
||||
PASTE_TEXT
|
||||
} from '#/events/constants'
|
||||
|
||||
import { GalleryDB } from 'apis/core/datastore'
|
||||
import { IObject, IFilter } from '@picgo/store/dist/types'
|
||||
import pasteTemplate from '../utils/pasteTemplate'
|
||||
|
||||
// eslint-disable-next-line
|
||||
const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
|
||||
@ -37,11 +40,6 @@ const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_re
|
||||
const STORE_PATH = path.dirname(dbPathChecker())
|
||||
// const CONFIG_PATH = path.join(STORE_PATH, '/data.json')
|
||||
|
||||
type PicGoNotice = {
|
||||
title: string,
|
||||
body: string[]
|
||||
}
|
||||
|
||||
interface GuiMenuItem {
|
||||
label: string
|
||||
handle: (arg0: PicGoCore, arg1: GuiApi) => Promise<void>
|
||||
@ -64,7 +62,7 @@ const getConfig = (name: string, type: IPicGoHelperType, ctx: PicGoCore) => {
|
||||
}
|
||||
|
||||
const handleConfigWithFunction = (config: any[]) => {
|
||||
for (let i in config) {
|
||||
for (const i in config) {
|
||||
if (typeof config[i].default === 'function') {
|
||||
config[i].default = config[i].default()
|
||||
}
|
||||
@ -78,7 +76,7 @@ const handleConfigWithFunction = (config: any[]) => {
|
||||
const getPluginList = (): IPicGoPlugin[] => {
|
||||
const pluginList = picgo.pluginLoader.getFullList()
|
||||
const list = []
|
||||
for (let i in pluginList) {
|
||||
for (const i in pluginList) {
|
||||
const plugin = picgo.pluginLoader.getPlugin(pluginList[i])!
|
||||
const pluginPath = path.join(STORE_PATH, `/node_modules/${pluginList[i]}`)
|
||||
const pluginPKG = requireFunc(path.join(pluginPath, 'package.json'))
|
||||
@ -156,12 +154,12 @@ const handlePluginInstall = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const handlePluginUninstall = () => {
|
||||
ipcMain.on('uninstallPlugin', async (event: IpcMainEvent, msg: string) => {
|
||||
const handlePluginUninstall = async (fullName: string) => {
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
const dispose = handleNPMError()
|
||||
const res = await picgo.pluginHandler.uninstall([msg])
|
||||
const res = await picgo.pluginHandler.uninstall([fullName])
|
||||
if (res.success) {
|
||||
event.sender.send('uninstallSuccess', res.body[0])
|
||||
window.webContents.send('uninstallSuccess', res.body[0])
|
||||
shortKeyHandler.unregisterPluginShortKey(res.body[0])
|
||||
} else {
|
||||
showNotification({
|
||||
@ -169,26 +167,24 @@ const handlePluginUninstall = () => {
|
||||
body: res.body as string
|
||||
})
|
||||
}
|
||||
event.sender.send('hideLoading')
|
||||
window.webContents.send('hideLoading')
|
||||
dispose()
|
||||
})
|
||||
}
|
||||
|
||||
const handlePluginUpdate = () => {
|
||||
ipcMain.on('updatePlugin', async (event: IpcMainEvent, msg: string) => {
|
||||
const handlePluginUpdate = async (fullName: string) => {
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
const dispose = handleNPMError()
|
||||
const res = await picgo.pluginHandler.update([msg])
|
||||
const res = await picgo.pluginHandler.update([fullName])
|
||||
if (res.success) {
|
||||
event.sender.send('updateSuccess', res.body[0])
|
||||
window.webContents.send('updateSuccess', res.body[0])
|
||||
} else {
|
||||
showNotification({
|
||||
title: '插件更新失败',
|
||||
body: res.body as string
|
||||
})
|
||||
}
|
||||
event.sender.send('hideLoading')
|
||||
window.webContents.send('hideLoading')
|
||||
dispose()
|
||||
})
|
||||
}
|
||||
|
||||
const handleNPMError = (): IDispose => {
|
||||
@ -221,6 +217,7 @@ const handleGetPicBedConfig = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: remove it
|
||||
const handlePluginActions = () => {
|
||||
ipcMain.on('pluginActions', (event: IpcMainEvent, name: string, label: string) => {
|
||||
const plugin = picgo.pluginLoader.getPlugin(name)
|
||||
@ -257,13 +254,14 @@ const handlePicGoGetConfig = () => {
|
||||
}
|
||||
|
||||
const handleImportLocalPlugin = () => {
|
||||
ipcMain.on('importLocalPlugin', (event: IpcMainEvent) => {
|
||||
ipcMain.on('importLocalPlugin', async (event: IpcMainEvent) => {
|
||||
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
dialog.showOpenDialog(settingWindow, {
|
||||
const res = await dialog.showOpenDialog(settingWindow, {
|
||||
properties: ['openDirectory']
|
||||
}, async (filePath: string[]) => {
|
||||
if (filePath.length > 0) {
|
||||
const res = await picgo.pluginHandler.install(filePath)
|
||||
})
|
||||
const filePaths = res.filePaths
|
||||
if (filePaths.length > 0) {
|
||||
const res = await picgo.pluginHandler.install(filePaths)
|
||||
if (res.success) {
|
||||
const list = getPluginList()
|
||||
event.sender.send('pluginList', list)
|
||||
@ -280,7 +278,6 @@ const handleImportLocalPlugin = () => {
|
||||
}
|
||||
event.sender.send('hideLoading')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const handlePicGoGalleryDB = () => {
|
||||
@ -319,12 +316,22 @@ const handlePicGoGalleryDB = () => {
|
||||
const res = await dbStore.removeById(id)
|
||||
event.sender.send(PICGO_REMOVE_BY_ID_DB, res, callbackId)
|
||||
})
|
||||
|
||||
ipcMain.handle(PASTE_TEXT, async (item: ImgInfo, copy = true) => {
|
||||
const pasteStyle = picgo.getConfig<IPasteStyle>('settings.pasteStyle') || IPasteStyle.MARKDOWN
|
||||
const customLink = picgo.getConfig<string>('settings.customLink')
|
||||
const txt = pasteTemplate(pasteStyle, item, customLink)
|
||||
if (copy) {
|
||||
clipboard.writeText(txt)
|
||||
}
|
||||
return txt
|
||||
})
|
||||
}
|
||||
|
||||
const handleOpenFile = () => {
|
||||
ipcMain.on(PICGO_OPEN_FILE, (event: IpcMainEvent, fileName: string) => {
|
||||
const abFilePath = path.join(STORE_PATH, fileName)
|
||||
shell.openItem(abFilePath)
|
||||
shell.openPath(abFilePath)
|
||||
})
|
||||
}
|
||||
|
||||
@ -332,8 +339,6 @@ export default {
|
||||
listen () {
|
||||
handleGetPluginList()
|
||||
handlePluginInstall()
|
||||
handlePluginUninstall()
|
||||
handlePluginUpdate()
|
||||
handleGetPicBedConfig()
|
||||
handlePluginActions()
|
||||
handleRemoveFiles()
|
||||
@ -342,5 +347,8 @@ export default {
|
||||
handlePicGoGalleryDB()
|
||||
handleImportLocalPlugin()
|
||||
handleOpenFile()
|
||||
}
|
||||
},
|
||||
// TODO: separate to single file
|
||||
handlePluginUninstall,
|
||||
handlePluginUpdate
|
||||
}
|
||||
|
286
src/main/events/remotes/menu.ts
Normal file
286
src/main/events/remotes/menu.ts
Normal file
@ -0,0 +1,286 @@
|
||||
import windowManager from 'apis/app/window/windowManager'
|
||||
import { IWindowList } from 'apis/app/window/constants'
|
||||
import { Menu, BrowserWindow, app, dialog } from 'electron'
|
||||
import getPicBeds from '~/main/utils/getPicBeds'
|
||||
import picgo from '@core/picgo'
|
||||
import {
|
||||
uploadClipboardFiles
|
||||
} from '~/main/apis/app/uploader/apis'
|
||||
import { privacyManager } from '~/main/utils/privacyManager'
|
||||
import pkg from 'root/package.json'
|
||||
import GuiApi from 'apis/gui'
|
||||
import PicGoCore from '~/universal/types/picgo'
|
||||
import { PICGO_CONFIG_PLUGIN, PICGO_HANDLE_PLUGIN_ING, PICGO_TOGGLE_PLUGIN } from '~/universal/events/constants'
|
||||
import picgoCoreIPC from '~/main/events/picgoCoreIPC'
|
||||
|
||||
interface GuiMenuItem {
|
||||
label: string
|
||||
handle: (arg0: PicGoCore, arg1: GuiApi) => Promise<void>
|
||||
}
|
||||
|
||||
const buildMiniPageMenu = () => {
|
||||
const picBeds = getPicBeds()
|
||||
const current = picgo.getConfig('picBed.uploader')
|
||||
const submenu = picBeds.filter(item => item.visible).map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
type: 'radio',
|
||||
checked: current === item.type,
|
||||
click () {
|
||||
picgo.saveConfig({
|
||||
'picBed.current': item.type,
|
||||
'picBed.uploader': item.type
|
||||
})
|
||||
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const template = [
|
||||
{
|
||||
label: '打开详细窗口',
|
||||
click () {
|
||||
windowManager.get(IWindowList.SETTING_WINDOW)!.show()
|
||||
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
||||
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '选择默认图床',
|
||||
type: 'submenu',
|
||||
submenu
|
||||
},
|
||||
{
|
||||
label: '剪贴板图片上传',
|
||||
click () {
|
||||
uploadClipboardFiles()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '隐藏窗口',
|
||||
click () {
|
||||
BrowserWindow.getFocusedWindow()!.hide()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '隐私协议',
|
||||
click () {
|
||||
privacyManager.show(false)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '重启应用',
|
||||
click () {
|
||||
app.relaunch()
|
||||
app.exit(0)
|
||||
}
|
||||
},
|
||||
{
|
||||
role: 'quit',
|
||||
label: '退出'
|
||||
}
|
||||
]
|
||||
// @ts-ignore
|
||||
return Menu.buildFromTemplate(template)
|
||||
}
|
||||
|
||||
const buildMainPageMenu = () => {
|
||||
const template = [
|
||||
{
|
||||
label: '关于',
|
||||
click () {
|
||||
dialog.showMessageBox({
|
||||
title: 'PicGo',
|
||||
message: 'PicGo',
|
||||
detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '赞助PicGo',
|
||||
click () {
|
||||
// TODO: show donation
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '生成图床配置二维码',
|
||||
click () {
|
||||
// TODO: qrcode
|
||||
// _this.qrcodeVisible = true
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '隐私协议',
|
||||
click () {
|
||||
privacyManager.show(false)
|
||||
}
|
||||
}
|
||||
]
|
||||
// @ts-ignore
|
||||
return Menu.buildFromTemplate(template)
|
||||
}
|
||||
|
||||
const buildUploadPageMenu = () => {
|
||||
const picBeds = getPicBeds()
|
||||
const currentPicBed = picgo.getConfig('picBed.uploader')
|
||||
const submenu = picBeds.filter(item => item.visible).map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
type: 'radio',
|
||||
checked: currentPicBed === item.type,
|
||||
click () {
|
||||
picgo.saveConfig({
|
||||
'picBed.current': item.type,
|
||||
'picBed.uploader': item.type
|
||||
})
|
||||
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
// @ts-ignore
|
||||
return Menu.buildFromTemplate(submenu)
|
||||
}
|
||||
|
||||
// TODO: separate to single file
|
||||
|
||||
const handleRestoreState = (item: string, name: string): void => {
|
||||
if (item === 'uploader') {
|
||||
const current = picgo.getConfig('picBed.current')
|
||||
if (current === name) {
|
||||
picgo.saveConfig({
|
||||
'picBed.current': 'smms',
|
||||
'picBed.uploader': 'smms'
|
||||
})
|
||||
}
|
||||
}
|
||||
if (item === 'transformer') {
|
||||
const current = picgo.getConfig('picBed.transformer')
|
||||
if (current === name) {
|
||||
picgo.saveConfig({
|
||||
'picBed.transformer': 'path'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const buildPluginPageMenu = (plugin: IPicGoPlugin) => {
|
||||
const menu = [{
|
||||
label: '启用插件',
|
||||
enabled: !plugin.enabled,
|
||||
click () {
|
||||
picgo.saveConfig({
|
||||
[`picgoPlugins.${plugin.fullName}`]: true
|
||||
})
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
window.webContents.send(PICGO_TOGGLE_PLUGIN, plugin.fullName, true)
|
||||
}
|
||||
}, {
|
||||
label: '禁用插件',
|
||||
enabled: plugin.enabled,
|
||||
click () {
|
||||
picgo.saveConfig({
|
||||
[`picgoPlugins.${plugin.fullName}`]: false
|
||||
})
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
window.webContents.send(PICGO_HANDLE_PLUGIN_ING, plugin.fullName)
|
||||
window.webContents.send(PICGO_TOGGLE_PLUGIN, plugin.fullName, false)
|
||||
if (plugin.config.transformer.name) {
|
||||
handleRestoreState('transformer', plugin.config.transformer.name)
|
||||
}
|
||||
if (plugin.config.uploader.name) {
|
||||
handleRestoreState('uploader', plugin.config.uploader.name)
|
||||
}
|
||||
}
|
||||
}, {
|
||||
label: '卸载插件',
|
||||
click () {
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
window.webContents.send(PICGO_HANDLE_PLUGIN_ING, plugin.fullName)
|
||||
picgoCoreIPC.handlePluginUninstall(plugin.fullName)
|
||||
}
|
||||
}, {
|
||||
label: '更新插件',
|
||||
click () {
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
window.webContents.send(PICGO_HANDLE_PLUGIN_ING, plugin.fullName)
|
||||
picgoCoreIPC.handlePluginUpdate(plugin.fullName)
|
||||
}
|
||||
}]
|
||||
for (const i in plugin.config) {
|
||||
if (plugin.config[i].config.length > 0) {
|
||||
const obj = {
|
||||
label: `配置${i} - ${plugin.config[i].fullName || plugin.config[i].name}`,
|
||||
click () {
|
||||
const window = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||
const currentType = i
|
||||
const configName = plugin.config[i].fullName || plugin.config[i].name
|
||||
const config = plugin.config[i].config
|
||||
window.webContents.send(PICGO_CONFIG_PLUGIN, currentType, configName, config)
|
||||
}
|
||||
}
|
||||
menu.push(obj)
|
||||
}
|
||||
}
|
||||
|
||||
// handle transformer
|
||||
if (plugin.config.transformer.name) {
|
||||
const currentTransformer = picgo.getConfig<string>('picBed.transformer') || 'path'
|
||||
const pluginTransformer = plugin.config.transformer.name
|
||||
const obj = {
|
||||
label: `${currentTransformer === pluginTransformer ? '禁用' : '启用'}transformer - ${plugin.config.transformer.name}`,
|
||||
click () {
|
||||
const transformer = plugin.config.transformer.name
|
||||
const currentTransformer = picgo.getConfig<string>('picBed.transformer') || 'path'
|
||||
if (currentTransformer === transformer) {
|
||||
picgo.saveConfig({
|
||||
'picBed.transformer': 'path'
|
||||
})
|
||||
} else {
|
||||
picgo.saveConfig({
|
||||
'picBed.transformer': transformer
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
menu.push(obj)
|
||||
}
|
||||
|
||||
// plugin custom menus
|
||||
if (plugin.guiMenu) {
|
||||
menu.push({
|
||||
// @ts-ignore
|
||||
type: 'separator'
|
||||
})
|
||||
for (const i of plugin.guiMenu) {
|
||||
menu.push({
|
||||
label: i.label,
|
||||
click () {
|
||||
// ipcRenderer.send('pluginActions', plugin.fullName, i.label)
|
||||
const picgPlugin = picgo.pluginLoader.getPlugin(plugin.fullName)
|
||||
if (picgPlugin?.guiMenu?.(picgo)?.length) {
|
||||
const menu: GuiMenuItem[] = picgPlugin.guiMenu(picgo)
|
||||
menu.forEach(item => {
|
||||
if (item.label === i.label) {
|
||||
item.handle(picgo, GuiApi.getInstance())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return Menu.buildFromTemplate(menu)
|
||||
}
|
||||
|
||||
export {
|
||||
buildMiniPageMenu,
|
||||
buildMainPageMenu,
|
||||
buildUploadPageMenu,
|
||||
buildPluginPageMenu
|
||||
}
|
@ -66,6 +66,7 @@ class LifeCycle {
|
||||
updateShortKeyFromVersion212(db, db.get('settings.shortKey'))
|
||||
await migrateGalleryFromVersion230(db, GalleryDB.getInstance(), picgo)
|
||||
}
|
||||
|
||||
private onReady () {
|
||||
const readyFunction = async () => {
|
||||
console.log('on ready')
|
||||
@ -74,7 +75,7 @@ class LifeCycle {
|
||||
// Install Vue Devtools
|
||||
try {
|
||||
await installExtension(VUEJS_DEVTOOLS)
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
console.error('Vue Devtools failed to install:', e.toString())
|
||||
}
|
||||
}
|
||||
@ -110,6 +111,7 @@ class LifeCycle {
|
||||
readyFunction()
|
||||
}
|
||||
}
|
||||
|
||||
private onRunning () {
|
||||
app.on('second-instance', (event, commandLine, workingDirectory) => {
|
||||
logger.info('detect second instance')
|
||||
@ -144,6 +146,7 @@ class LifeCycle {
|
||||
process.env.XDG_CURRENT_DESKTOP = 'Unity'
|
||||
}
|
||||
}
|
||||
|
||||
private onQuit () {
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
@ -171,6 +174,7 @@ class LifeCycle {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async launchApp () {
|
||||
const gotTheLock = app.requestSingleInstanceLock()
|
||||
if (!gotTheLock) {
|
||||
|
@ -29,6 +29,7 @@ class Server {
|
||||
}
|
||||
this.httpServer = http.createServer(this.handleRequest)
|
||||
}
|
||||
|
||||
private checkIfConfigIsValid (config: IObj | undefined) {
|
||||
if (config && config.port && config.host && (config.enable !== undefined)) {
|
||||
return true
|
||||
@ -36,6 +37,7 @@ class Server {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private handleRequest = (request: http.IncomingMessage, response: http.ServerResponse) => {
|
||||
if (request.method === 'POST') {
|
||||
if (!routers.getHandler(request.url!)) {
|
||||
@ -57,8 +59,8 @@ class Server {
|
||||
request.on('end', () => {
|
||||
try {
|
||||
postObj = (body === '') ? {} : JSON.parse(body)
|
||||
} catch (err) {
|
||||
logger.error(`[PicGo Server]`, err)
|
||||
} catch (err: any) {
|
||||
logger.error('[PicGo Server]', err)
|
||||
return handleResponse({
|
||||
response,
|
||||
body: {
|
||||
@ -67,7 +69,7 @@ class Server {
|
||||
}
|
||||
})
|
||||
}
|
||||
logger.info(`[PicGo Server] get the request`, body)
|
||||
logger.info('[PicGo Server] get the request', body)
|
||||
const handler = routers.getHandler(request.url!)
|
||||
handler!({
|
||||
...postObj,
|
||||
@ -81,6 +83,7 @@ class Server {
|
||||
response.end()
|
||||
}
|
||||
}
|
||||
|
||||
// port as string is a bug
|
||||
private listen = (port: number | string) => {
|
||||
logger.info(`[PicGo Server] is listening at ${port}`)
|
||||
@ -102,18 +105,21 @@ class Server {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
startup () {
|
||||
console.log('startup', this.config.enable)
|
||||
if (this.config.enable) {
|
||||
this.listen(this.config.port)
|
||||
}
|
||||
}
|
||||
|
||||
shutdown (hasStarted?: boolean) {
|
||||
this.httpServer.close()
|
||||
if (!hasStarted) {
|
||||
logger.info('[PicGo Server] shutdown')
|
||||
}
|
||||
}
|
||||
|
||||
restart () {
|
||||
this.config = picgo.getConfig('settings.server')
|
||||
this.shutdown()
|
||||
|
@ -4,6 +4,7 @@ class Router {
|
||||
get (url: string, callback: routeHandler): void {
|
||||
this.router.set(url, callback)
|
||||
}
|
||||
|
||||
post (url: string, callback: routeHandler): void {
|
||||
this.router.set(url, callback)
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ router.post('/upload', async ({
|
||||
})
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
logger.error(err)
|
||||
handleResponse({
|
||||
response,
|
||||
|
@ -33,7 +33,7 @@ function resolveMacWorkFlow () {
|
||||
* 初始化剪贴板生成图片的脚本
|
||||
*/
|
||||
function resolveClipboardImageGenerator () {
|
||||
let clipboardFiles = getClipboardFiles()
|
||||
const clipboardFiles = getClipboardFiles()
|
||||
if (!fs.pathExistsSync(path.join(CONFIG_DIR, 'windows10.ps1'))) {
|
||||
clipboardFiles.forEach(item => {
|
||||
fs.copyFileSync(item.origin, item.dest)
|
||||
@ -46,8 +46,8 @@ function resolveClipboardImageGenerator () {
|
||||
|
||||
function diffFilesAndUpdate (filePath1: string, filePath2: string) {
|
||||
try {
|
||||
let file1 = fs.existsSync(filePath1) && fs.readFileSync(filePath1)
|
||||
let file2 = fs.existsSync(filePath1) && fs.readFileSync(filePath2)
|
||||
const file1 = fs.existsSync(filePath1) && fs.readFileSync(filePath1)
|
||||
const file2 = fs.existsSync(filePath1) && fs.readFileSync(filePath2)
|
||||
|
||||
if (!file1 || !file2 || !file1.equals(file2)) {
|
||||
fs.copyFileSync(filePath1, filePath2)
|
||||
@ -59,7 +59,7 @@ function resolveClipboardImageGenerator () {
|
||||
}
|
||||
|
||||
function getClipboardFiles () {
|
||||
let files = [
|
||||
const files = [
|
||||
'/linux.sh',
|
||||
'/mac.applescript',
|
||||
'/windows.ps1',
|
||||
|
@ -34,7 +34,7 @@ export const showNotification = (options: IPrivateShowNotificationOption = {
|
||||
}
|
||||
|
||||
export const showMessageBox = (options: any) => {
|
||||
return new Promise<IShowMessageBoxResult>(async (resolve, reject) => {
|
||||
return new Promise<IShowMessageBoxResult>(async (resolve) => {
|
||||
dialog.showMessageBox(
|
||||
options
|
||||
).then((res) => {
|
||||
|
@ -39,7 +39,7 @@ const getUploadFiles = (argv = process.argv, cwd = process.cwd(), logger: Logger
|
||||
path: item
|
||||
}
|
||||
} else {
|
||||
let tempPath = path.join(cwd, item)
|
||||
const tempPath = path.join(cwd, item)
|
||||
if (fs.existsSync(tempPath)) {
|
||||
return {
|
||||
path: tempPath
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IPasteStyle } from '#/types/enum'
|
||||
|
||||
const formatCustomLink = (customLink: string, item: ImgInfo) => {
|
||||
let fileName = item.fileName!.replace(new RegExp(`\\${item.extname}$`), '')
|
||||
const fileName = item.fileName!.replace(new RegExp(`\\${item.extname}$`), '')
|
||||
const url = item.url || item.imgUrl
|
||||
const formatObj = {
|
||||
url,
|
||||
@ -10,7 +10,7 @@ const formatCustomLink = (customLink: string, item: ImgInfo) => {
|
||||
const keys = Object.keys(formatObj) as ['url', 'fileName']
|
||||
keys.forEach(item => {
|
||||
if (customLink.indexOf(`$${item}`) !== -1) {
|
||||
let reg = new RegExp(`\\$${item}`, 'g')
|
||||
const reg = new RegExp(`\\$${item}`, 'g')
|
||||
customLink = customLink.replace(reg, formatObj[item])
|
||||
}
|
||||
})
|
||||
@ -21,11 +21,11 @@ export default (style: IPasteStyle, item: ImgInfo, customLink: string | undefine
|
||||
const url = item.url || item.imgUrl
|
||||
const _customLink = customLink || '$url'
|
||||
const tpl = {
|
||||
'markdown': ``,
|
||||
'HTML': `<img src="${url}"/>`,
|
||||
'URL': url,
|
||||
'UBB': `[IMG]${url}[/IMG]`,
|
||||
'Custom': formatCustomLink(_customLink, item)
|
||||
markdown: ``,
|
||||
HTML: `<img src="${url}"/>`,
|
||||
URL: url,
|
||||
UBB: `[IMG]${url}[/IMG]`,
|
||||
Custom: formatCustomLink(_customLink, item)
|
||||
}
|
||||
return tpl[style]
|
||||
}
|
@ -23,7 +23,8 @@ export default class extends Vue {
|
||||
this.value = true
|
||||
}
|
||||
}
|
||||
choosePicBed (val: string) {
|
||||
|
||||
choosePicBed () {
|
||||
this.saveConfig({
|
||||
'picBed.current': this.type,
|
||||
'picBed.uploader': this.type
|
||||
|
@ -83,8 +83,9 @@ export default class extends Vue {
|
||||
handleConfigChange (val: any) {
|
||||
this.handleConfig(val)
|
||||
}
|
||||
|
||||
async validate () {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
// @ts-ignore
|
||||
this.$refs.form.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
@ -109,7 +110,7 @@ export default class extends Vue {
|
||||
return `transformer.${this.id}`
|
||||
}
|
||||
default:
|
||||
return `unknown`
|
||||
return 'unknown'
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,8 +120,10 @@ export default class extends Vue {
|
||||
if (val.length > 0) {
|
||||
this.configList = cloneDeep(val).map((item: any) => {
|
||||
let defaultValue = item.default !== undefined
|
||||
? item.default : item.type === 'checkbox'
|
||||
? [] : null
|
||||
? item.default
|
||||
: item.type === 'checkbox'
|
||||
? []
|
||||
: null
|
||||
if (item.type === 'checkbox') {
|
||||
const defaults = item.choices.filter((i: any) => {
|
||||
return i.checked
|
||||
|
@ -15,7 +15,7 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import { remote, ipcRenderer, IpcRendererEvent } from 'electron'
|
||||
import { ipcRenderer, IpcRendererEvent } from 'electron'
|
||||
import {
|
||||
SHOW_INPUT_BOX,
|
||||
SHOW_INPUT_BOX_RESPONSE
|
||||
@ -30,30 +30,36 @@ export default class extends Vue {
|
||||
title: '',
|
||||
placeholder: ''
|
||||
}
|
||||
|
||||
created () {
|
||||
ipcRenderer.on(SHOW_INPUT_BOX, this.ipcEventHandler)
|
||||
this.$bus.$on(SHOW_INPUT_BOX, this.initInputBoxValue)
|
||||
}
|
||||
|
||||
ipcEventHandler (evt: IpcRendererEvent, options: IShowInputBoxOption) {
|
||||
this.initInputBoxValue(options)
|
||||
}
|
||||
|
||||
initInputBoxValue (options: IShowInputBoxOption) {
|
||||
this.inputBoxValue = options.value || ''
|
||||
this.inputBoxOptions.title = options.title || ''
|
||||
this.inputBoxOptions.placeholder = options.placeholder || ''
|
||||
this.showInputBoxVisible = true
|
||||
}
|
||||
|
||||
handleInputBoxCancel () {
|
||||
// TODO: RPCServer
|
||||
this.showInputBoxVisible = false
|
||||
ipcRenderer.send(SHOW_INPUT_BOX, '')
|
||||
this.$bus.$emit(SHOW_INPUT_BOX_RESPONSE, '')
|
||||
}
|
||||
|
||||
handleInputBoxConfirm () {
|
||||
this.showInputBoxVisible = false
|
||||
ipcRenderer.send(SHOW_INPUT_BOX, this.inputBoxValue)
|
||||
this.$bus.$emit(SHOW_INPUT_BOX_RESPONSE, this.inputBoxValue)
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeListener(SHOW_INPUT_BOX, this.ipcEventHandler)
|
||||
this.$bus.$off(SHOW_INPUT_BOX)
|
||||
|
@ -148,29 +148,18 @@ import { Component, Vue, Watch } from 'vue-property-decorator'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import pick from 'lodash/pick'
|
||||
import pkg from 'root/package.json'
|
||||
import keyDetect from '@/utils/key-binding'
|
||||
import {
|
||||
remote,
|
||||
ipcRenderer,
|
||||
IpcRendererEvent,
|
||||
clipboard
|
||||
} from 'electron'
|
||||
// import db from '#/datastore'
|
||||
import mixin from '@/utils/mixin'
|
||||
import InputBoxDialog from '@/components/InputBoxDialog.vue'
|
||||
import {
|
||||
SHOW_PRIVACY_MESSAGE,
|
||||
OPEN_DEVTOOLS
|
||||
MINIMIZE_WINDOW,
|
||||
CLOSE_WINDOW,
|
||||
SHOW_MAIN_PAGE_MENU
|
||||
} from '~/universal/events/constants'
|
||||
import { IConfig } from 'picgo/dist/src/types/index'
|
||||
const { Menu, dialog, BrowserWindow } = remote
|
||||
const customLinkRule = (rule: string, value: string, callback: (arg0?: Error) => void) => {
|
||||
if (!/\$url/.test(value)) {
|
||||
return callback(new Error('必须含有$url'))
|
||||
} else {
|
||||
return callback()
|
||||
}
|
||||
}
|
||||
@Component({
|
||||
name: 'main-page',
|
||||
mixins: [mixin],
|
||||
@ -182,7 +171,6 @@ const customLinkRule = (rule: string, value: string, callback: (arg0?: Error) =>
|
||||
export default class extends Vue {
|
||||
version = process.env.NODE_ENV === 'production' ? pkg.version : 'Dev'
|
||||
defaultActive = 'upload'
|
||||
menu: Electron.Menu | null = null
|
||||
visible = false
|
||||
keyBindingVisible = false
|
||||
customLinkVisible = false
|
||||
@ -193,13 +181,13 @@ export default class extends Vue {
|
||||
choosedPicBedForQRCode: string[] = []
|
||||
created () {
|
||||
this.os = process.platform
|
||||
this.buildMenu()
|
||||
ipcRenderer.send('getPicBeds')
|
||||
ipcRenderer.on('getPicBeds', this.getPicBeds)
|
||||
this.handleGetPicPeds()
|
||||
}
|
||||
|
||||
@Watch('choosedPicBedForQRCode')
|
||||
choosedPicBedForQRCodeChange (val: string[], oldVal: string[]) {
|
||||
choosedPicBedForQRCodeChange (val: string[]) {
|
||||
if (val.length > 0) {
|
||||
this.$nextTick(async () => {
|
||||
const picBedConfig = await this.getConfig('picBed')
|
||||
@ -235,77 +223,38 @@ export default class extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
minimizeWindow () {
|
||||
const window = BrowserWindow.getFocusedWindow()
|
||||
window!.minimize()
|
||||
ipcRenderer.send(MINIMIZE_WINDOW)
|
||||
}
|
||||
|
||||
closeWindow () {
|
||||
const window = BrowserWindow.getFocusedWindow()
|
||||
if (process.platform === 'linux') {
|
||||
window!.hide()
|
||||
} else {
|
||||
window!.close()
|
||||
}
|
||||
}
|
||||
buildMenu () {
|
||||
const _this = this
|
||||
const template = [
|
||||
{
|
||||
label: '关于',
|
||||
click () {
|
||||
dialog.showMessageBox({
|
||||
title: 'PicGo',
|
||||
message: 'PicGo',
|
||||
detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '赞助PicGo',
|
||||
click () {
|
||||
_this.visible = true
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '生成图床配置二维码',
|
||||
click () {
|
||||
_this.qrcodeVisible = true
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '隐私协议',
|
||||
click () {
|
||||
ipcRenderer.send(SHOW_PRIVACY_MESSAGE)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '打开调试器',
|
||||
click () {
|
||||
ipcRenderer.send(OPEN_DEVTOOLS)
|
||||
}
|
||||
}
|
||||
]
|
||||
this.menu = Menu.buildFromTemplate(template)
|
||||
ipcRenderer.send(CLOSE_WINDOW)
|
||||
}
|
||||
|
||||
openDialog () {
|
||||
// this.menu!.popup(remote.getCurrentWindow())
|
||||
this.menu!.popup()
|
||||
ipcRenderer.send(SHOW_MAIN_PAGE_MENU)
|
||||
}
|
||||
|
||||
openMiniWindow () {
|
||||
ipcRenderer.send('openMiniWindow')
|
||||
}
|
||||
|
||||
handleCopyPicBedConfig () {
|
||||
clipboard.writeText(this.picBedConfigString)
|
||||
this.$message.success('图床配置复制成功')
|
||||
}
|
||||
|
||||
getPicBeds (event: IpcRendererEvent, picBeds: IPicBedType[]) {
|
||||
this.picBed = picBeds
|
||||
}
|
||||
beforeRouteEnter (to: any, from: any, next: any) {
|
||||
|
||||
beforeRouteEnter (to: any, next: any) {
|
||||
next((vm: this) => {
|
||||
vm.defaultActive = to.name
|
||||
})
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)
|
||||
}
|
||||
|
@ -110,10 +110,9 @@
|
||||
<script lang="ts">
|
||||
// @ts-ignore
|
||||
import gallerys from 'vue-gallery'
|
||||
import pasteStyle from '#/utils/pasteTemplate'
|
||||
import { IPasteStyle } from '#/types/enum'
|
||||
import { Component, Vue, Watch } from 'vue-property-decorator'
|
||||
import { IResult } from '@picgo/store/dist/types'
|
||||
import { PASTE_TEXT } from '#/events/constants'
|
||||
import {
|
||||
ipcRenderer,
|
||||
clipboard,
|
||||
@ -133,11 +132,13 @@ export default class extends Vue {
|
||||
urlProperty: 'imgUrl',
|
||||
closeOnSlideClick: true
|
||||
}
|
||||
|
||||
dialogVisible = false
|
||||
imgInfo = {
|
||||
id: '',
|
||||
imgUrl: ''
|
||||
}
|
||||
|
||||
choosedList: IObjT<boolean> = {}
|
||||
choosedPicBed: string[] = []
|
||||
lastChoosed: number = -1
|
||||
@ -152,6 +153,7 @@ export default class extends Vue {
|
||||
UBB: 'UBB',
|
||||
Custom: 'Custom'
|
||||
}
|
||||
|
||||
picBed: IPicBedType[] = []
|
||||
@Watch('$route')
|
||||
handleRouteUpdate (to: any, from: any) {
|
||||
@ -163,8 +165,9 @@ export default class extends Vue {
|
||||
this.updateGallery()
|
||||
}
|
||||
}
|
||||
|
||||
async created () {
|
||||
ipcRenderer.on('updateGallery', (event: IpcRendererEvent) => {
|
||||
ipcRenderer.on('updateGallery', () => {
|
||||
this.$nextTick(async () => {
|
||||
this.updateGallery()
|
||||
})
|
||||
@ -173,10 +176,12 @@ export default class extends Vue {
|
||||
ipcRenderer.on('getPicBeds', this.getPicBeds)
|
||||
this.updateGallery()
|
||||
}
|
||||
|
||||
mounted () {
|
||||
document.addEventListener('keydown', this.handleDetectShiftKey)
|
||||
document.addEventListener('keyup', this.handleDetectShiftKey)
|
||||
}
|
||||
|
||||
handleDetectShiftKey (event: KeyboardEvent) {
|
||||
if (event.key === 'Shift') {
|
||||
if (event.type === 'keydown') {
|
||||
@ -186,9 +191,11 @@ export default class extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get filterList () {
|
||||
return this.getGallery()
|
||||
}
|
||||
|
||||
get isAllSelected () {
|
||||
const values = Object.values(this.choosedList)
|
||||
if (values.length === 0) {
|
||||
@ -199,9 +206,11 @@ export default class extends Vue {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getPicBeds (event: IpcRendererEvent, picBeds: IPicBedType[]) {
|
||||
this.picBed = picBeds
|
||||
}
|
||||
|
||||
getGallery (): ImgInfo[] {
|
||||
if (this.searchText || this.choosedPicBed.length > 0) {
|
||||
return this.images
|
||||
@ -220,6 +229,7 @@ export default class extends Vue {
|
||||
return this.images
|
||||
}
|
||||
}
|
||||
|
||||
async updateGallery () {
|
||||
this.images = (await this.$$db.get({ orderBy: 'desc' })).data
|
||||
}
|
||||
@ -228,12 +238,13 @@ export default class extends Vue {
|
||||
handleFilterListChange () {
|
||||
this.clearChoosedList()
|
||||
}
|
||||
|
||||
handleChooseImage (val: boolean, index: number) {
|
||||
if (val === true) {
|
||||
this.handleBarActive = true
|
||||
if (this.lastChoosed !== -1 && this.isShiftKeyPress) {
|
||||
let min = Math.min(this.lastChoosed, index)
|
||||
let max = Math.max(this.lastChoosed, index)
|
||||
const min = Math.min(this.lastChoosed, index)
|
||||
const max = Math.max(this.lastChoosed, index)
|
||||
for (let i = min + 1; i < max; i++) {
|
||||
const id = this.filterList[i].id!
|
||||
this.$set(this.choosedList, id, true)
|
||||
@ -242,6 +253,7 @@ export default class extends Vue {
|
||||
this.lastChoosed = index
|
||||
}
|
||||
}
|
||||
|
||||
clearChoosedList () {
|
||||
this.isShiftKeyPress = false
|
||||
Object.keys(this.choosedList).forEach(key => {
|
||||
@ -249,10 +261,12 @@ export default class extends Vue {
|
||||
})
|
||||
this.lastChoosed = -1
|
||||
}
|
||||
|
||||
zoomImage (index: number) {
|
||||
this.idx = index
|
||||
this.changeZIndexForGallery(true)
|
||||
}
|
||||
|
||||
changeZIndexForGallery (isOpen: boolean) {
|
||||
if (isOpen) {
|
||||
// @ts-ignore
|
||||
@ -262,25 +276,25 @@ export default class extends Vue {
|
||||
document.querySelector('.main-content.el-row').style.zIndex = 10
|
||||
}
|
||||
}
|
||||
|
||||
handleClose () {
|
||||
this.idx = null
|
||||
this.changeZIndexForGallery(false)
|
||||
}
|
||||
|
||||
async copy (item: ImgInfo) {
|
||||
const style = await this.getConfig<IPasteStyle>('settings.pasteStyle') || IPasteStyle.MARKDOWN
|
||||
const customLink = await this.getConfig<string>('settings.customLink')
|
||||
const copyLink = pasteStyle(style, item, customLink)
|
||||
const copyLink = await ipcRenderer.invoke(PASTE_TEXT, item)
|
||||
const obj = {
|
||||
title: '复制链接成功',
|
||||
body: copyLink,
|
||||
icon: item.url || item.imgUrl
|
||||
}
|
||||
const myNotification = new Notification(obj.title, obj)
|
||||
clipboard.writeText(copyLink)
|
||||
myNotification.onclick = () => {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
remove (id: string) {
|
||||
this.$confirm('此操作将把该图片移出相册, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
@ -304,11 +318,13 @@ export default class extends Vue {
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
openDialog (item: ImgInfo) {
|
||||
this.imgInfo.id = item.id!
|
||||
this.imgInfo.imgUrl = item.imgUrl as string
|
||||
this.dialogVisible = true
|
||||
}
|
||||
|
||||
async confirmModify () {
|
||||
await this.$$db.updateById(this.imgInfo.id, {
|
||||
imgUrl: this.imgInfo.imgUrl
|
||||
@ -325,26 +341,31 @@ export default class extends Vue {
|
||||
this.dialogVisible = false
|
||||
this.updateGallery()
|
||||
}
|
||||
|
||||
choosePicBed (type: string) {
|
||||
let idx = this.choosedPicBed.indexOf(type)
|
||||
const idx = this.choosedPicBed.indexOf(type)
|
||||
if (idx !== -1) {
|
||||
this.choosedPicBed.splice(idx, 1)
|
||||
} else {
|
||||
this.choosedPicBed.push(type)
|
||||
}
|
||||
}
|
||||
|
||||
cleanSearch () {
|
||||
this.searchText = ''
|
||||
}
|
||||
|
||||
isMultiple (obj: IObj) {
|
||||
return Object.values(obj).some(item => item)
|
||||
}
|
||||
|
||||
toggleSelectAll () {
|
||||
const result = !this.isAllSelected
|
||||
this.filterList.forEach(item => {
|
||||
this.$set(this.choosedList, item.id!, result)
|
||||
})
|
||||
}
|
||||
|
||||
multiRemove () {
|
||||
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
|
||||
const multiRemoveNumber = Object.values(this.choosedList).filter(item => item).length
|
||||
@ -354,7 +375,7 @@ export default class extends Vue {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
let files: IResult<ImgInfo>[] = []
|
||||
const files: IResult<ImgInfo>[] = []
|
||||
const imageIDList = Object.keys(this.choosedList)
|
||||
for (let i = 0; i < imageIDList.length; i++) {
|
||||
const key = imageIDList[i]
|
||||
@ -383,11 +404,10 @@ export default class extends Vue {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async multiCopy () {
|
||||
if (Object.values(this.choosedList).some(item => item)) {
|
||||
const copyString: string[] = []
|
||||
const style = await this.getConfig<IPasteStyle>('settings.pasteStyle') || IPasteStyle.MARKDOWN
|
||||
const customLink = await this.getConfig<string>('settings.customLink')
|
||||
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
|
||||
const imageIDList = Object.keys(this.choosedList)
|
||||
for (let i = 0; i < imageIDList.length; i++) {
|
||||
@ -395,7 +415,8 @@ export default class extends Vue {
|
||||
if (this.choosedList[key]) {
|
||||
const item = await this.$$db.getById<ImgInfo>(key)
|
||||
if (item) {
|
||||
copyString.push(pasteStyle(style, item, customLink))
|
||||
const txt = await ipcRenderer.invoke(PASTE_TEXT, item)
|
||||
copyString.push(txt)
|
||||
this.choosedList[key] = false
|
||||
}
|
||||
}
|
||||
@ -411,9 +432,11 @@ export default class extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toggleHandleBar () {
|
||||
this.handleBarActive = !this.handleBarActive
|
||||
}
|
||||
|
||||
// getPasteStyle () {
|
||||
// this.pasteStyle = this.$db.get('settings.pasteStyle') || 'markdown'
|
||||
// }
|
||||
@ -421,6 +444,7 @@ export default class extends Vue {
|
||||
this.saveConfig('settings.pasteStyle', val)
|
||||
this.pasteStyle = val
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeAllListeners('updateGallery')
|
||||
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)
|
||||
|
@ -20,10 +20,9 @@ import mixin from '@/utils/mixin'
|
||||
import { Component, Vue, Watch } from 'vue-property-decorator'
|
||||
import {
|
||||
ipcRenderer,
|
||||
IpcRendererEvent,
|
||||
remote
|
||||
IpcRendererEvent
|
||||
} from 'electron'
|
||||
import { SHOW_PRIVACY_MESSAGE, OPEN_DEVTOOLS } from '~/universal/events/constants'
|
||||
import { SHOW_MINI_PAGE_MENU } from '~/universal/events/constants'
|
||||
@Component({
|
||||
name: 'mini-page',
|
||||
mixins: [mixin]
|
||||
@ -55,6 +54,7 @@ export default class extends Vue {
|
||||
})
|
||||
this.getPicBeds()
|
||||
}
|
||||
|
||||
mounted () {
|
||||
window.addEventListener('mousedown', this.handleMouseDown, false)
|
||||
window.addEventListener('mousemove', this.handleMouseMove, false)
|
||||
@ -73,27 +73,31 @@ export default class extends Vue {
|
||||
}, 1200)
|
||||
}
|
||||
}
|
||||
|
||||
getPicBeds () {
|
||||
this.picBed = ipcRenderer.sendSync('getPicBeds')
|
||||
this.buildMenu()
|
||||
}
|
||||
|
||||
onDrop (e: DragEvent) {
|
||||
this.dragover = false
|
||||
this.ipcSendFiles(e.dataTransfer!.files)
|
||||
}
|
||||
|
||||
openUploadWindow () {
|
||||
// @ts-ignore
|
||||
document.getElementById('file-uploader').click()
|
||||
}
|
||||
|
||||
onChange (e: any) {
|
||||
this.ipcSendFiles(e.target.files)
|
||||
// @ts-ignore
|
||||
document.getElementById('file-uploader').value = ''
|
||||
}
|
||||
|
||||
ipcSendFiles (files: FileList) {
|
||||
let sendFiles: IFileWithPath[] = []
|
||||
Array.from(files).forEach((item, index) => {
|
||||
let obj = {
|
||||
const sendFiles: IFileWithPath[] = []
|
||||
Array.from(files).forEach((item) => {
|
||||
const obj = {
|
||||
name: item.name,
|
||||
path: item.path
|
||||
}
|
||||
@ -101,6 +105,7 @@ export default class extends Vue {
|
||||
})
|
||||
ipcRenderer.send('uploadChoosedFiles', sendFiles)
|
||||
}
|
||||
|
||||
handleMouseDown (e: MouseEvent) {
|
||||
this.dragging = true
|
||||
this.wX = e.pageX
|
||||
@ -108,20 +113,23 @@ export default class extends Vue {
|
||||
this.screenX = e.screenX
|
||||
this.screenY = e.screenY
|
||||
}
|
||||
|
||||
handleMouseMove (e: MouseEvent) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
if (this.dragging) {
|
||||
const xLoc = e.screenX - this.wX
|
||||
const yLoc = e.screenY - this.wY
|
||||
remote.BrowserWindow.getFocusedWindow()!.setBounds({
|
||||
x: xLoc,
|
||||
y: yLoc,
|
||||
width: 64,
|
||||
height: 64
|
||||
})
|
||||
// const xLoc = e.screenX - this.wX
|
||||
// const yLoc = e.screenY - this.wY
|
||||
// FIXME: drag
|
||||
// remote.BrowserWindow.getFocusedWindow()!.setBounds({
|
||||
// x: xLoc,
|
||||
// y: yLoc,
|
||||
// width: 64,
|
||||
// height: 64
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
||||
handleMouseUp (e: MouseEvent) {
|
||||
this.dragging = false
|
||||
if (this.screenX === e.screenX && this.screenY === e.screenY) {
|
||||
@ -133,77 +141,11 @@ export default class extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
openContextMenu () {
|
||||
this.menu!.popup()
|
||||
}
|
||||
async buildMenu () {
|
||||
const _this = this
|
||||
const current = await this.getConfig('picBed.current')
|
||||
const submenu = this.picBed.filter(item => item.visible).map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
type: 'radio',
|
||||
checked: current === item.type,
|
||||
click () {
|
||||
_this.saveConfig({
|
||||
'picBed.current': item.type,
|
||||
'picBed.uploader': item.type
|
||||
})
|
||||
ipcRenderer.send('syncPicBed')
|
||||
}
|
||||
}
|
||||
})
|
||||
const template = [
|
||||
{
|
||||
label: '打开详细窗口',
|
||||
click () {
|
||||
ipcRenderer.send('openSettingWindow')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '选择默认图床',
|
||||
type: 'submenu',
|
||||
submenu
|
||||
},
|
||||
{
|
||||
label: '剪贴板图片上传',
|
||||
click () {
|
||||
ipcRenderer.send('uploadClipboardFilesFromUploadPage')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '隐藏窗口',
|
||||
click () {
|
||||
remote.BrowserWindow.getFocusedWindow()!.hide()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '隐私协议',
|
||||
click () {
|
||||
ipcRenderer.send(SHOW_PRIVACY_MESSAGE)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '重启应用',
|
||||
click () {
|
||||
remote.app.relaunch()
|
||||
remote.app.exit(0)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '打开调试器',
|
||||
click () {
|
||||
ipcRenderer.send(OPEN_DEVTOOLS)
|
||||
}
|
||||
},
|
||||
{
|
||||
role: 'quit',
|
||||
label: '退出'
|
||||
}
|
||||
]
|
||||
// @ts-ignore
|
||||
this.menu = remote.Menu.buildFromTemplate(template)
|
||||
ipcRenderer.send(SHOW_MINI_PAGE_MENU)
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeAllListeners('uploadProgress')
|
||||
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)
|
||||
|
@ -339,10 +339,9 @@
|
||||
import keyDetect from '@/utils/key-binding'
|
||||
import pkg from 'root/package.json'
|
||||
import { IConfig } from 'picgo/dist/src/types/index'
|
||||
import { PICGO_OPEN_FILE } from '#/events/constants'
|
||||
import { PICGO_OPEN_FILE, OPEN_URL } from '#/events/constants'
|
||||
import {
|
||||
ipcRenderer,
|
||||
remote
|
||||
ipcRenderer
|
||||
} from 'electron'
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
// import db from '#/datastore'
|
||||
@ -373,6 +372,7 @@ export default class extends Vue {
|
||||
autoCopyUrl: true,
|
||||
checkBetaUpdate: true
|
||||
}
|
||||
|
||||
picBed: IPicBedType[] = []
|
||||
logFileVisible = false
|
||||
keyBindingVisible = false
|
||||
@ -383,9 +383,11 @@ export default class extends Vue {
|
||||
customLink = {
|
||||
value: '$url'
|
||||
}
|
||||
|
||||
shortKey: IShortKeyMap = {
|
||||
upload: ''
|
||||
}
|
||||
|
||||
proxy = ''
|
||||
npmRegistry = ''
|
||||
npmProxy = ''
|
||||
@ -394,6 +396,7 @@ export default class extends Vue {
|
||||
{ validator: customLinkRule, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
logLevel = {
|
||||
all: '全部-All',
|
||||
success: '成功-Success',
|
||||
@ -402,11 +405,13 @@ export default class extends Vue {
|
||||
warn: '提醒-Warn',
|
||||
none: '不记录日志-None'
|
||||
}
|
||||
|
||||
server = {
|
||||
port: 36677,
|
||||
host: '127.0.0.1',
|
||||
enable: true
|
||||
}
|
||||
|
||||
version = pkg.version
|
||||
latestVersion = ''
|
||||
os = ''
|
||||
@ -418,12 +423,14 @@ export default class extends Vue {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
created () {
|
||||
this.os = process.platform
|
||||
ipcRenderer.send('getPicBeds')
|
||||
ipcRenderer.on('getPicBeds', this.getPicBeds)
|
||||
this.initData()
|
||||
}
|
||||
|
||||
async initData () {
|
||||
const config = (await this.getConfig<IConfig>())!
|
||||
if (config !== undefined) {
|
||||
@ -469,21 +476,27 @@ export default class extends Vue {
|
||||
if (item.visible) {
|
||||
return item.name
|
||||
}
|
||||
}) as string[]
|
||||
return null
|
||||
}).filter(item => item) as string[]
|
||||
}
|
||||
|
||||
openFile (file: string) {
|
||||
ipcRenderer.send(PICGO_OPEN_FILE, file)
|
||||
}
|
||||
|
||||
openLogSetting () {
|
||||
this.logFileVisible = true
|
||||
}
|
||||
|
||||
keyDetect (type: string, event: KeyboardEvent) {
|
||||
this.shortKey[type] = keyDetect(event).join('+')
|
||||
}
|
||||
|
||||
async cancelCustomLink () {
|
||||
this.customLinkVisible = false
|
||||
this.customLink.value = await this.getConfig<string>('settings.customLink') || '$url'
|
||||
}
|
||||
|
||||
confirmCustomLink () {
|
||||
// @ts-ignore
|
||||
this.$refs.customLink.validate((valid: boolean) => {
|
||||
@ -496,10 +509,12 @@ export default class extends Vue {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async cancelProxy () {
|
||||
this.proxyVisible = false
|
||||
this.proxy = await this.getConfig<string>('picBed.proxy') || ''
|
||||
}
|
||||
|
||||
confirmProxy () {
|
||||
this.proxyVisible = false
|
||||
this.saveConfig({
|
||||
@ -514,12 +529,15 @@ export default class extends Vue {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
updateHelperChange (val: boolean) {
|
||||
this.saveConfig('settings.showUpdateTip', val)
|
||||
}
|
||||
|
||||
checkBetaUpdateChange (val: boolean) {
|
||||
this.saveConfig('settings.checkBetaUpdate', val)
|
||||
}
|
||||
|
||||
handleShowPicBedListChange (val: string[]) {
|
||||
const list = this.picBed.map(item => {
|
||||
if (!val.includes(item.name)) {
|
||||
@ -534,20 +552,24 @@ export default class extends Vue {
|
||||
})
|
||||
ipcRenderer.send('getPicBeds')
|
||||
}
|
||||
|
||||
handleAutoStartChange (val: boolean) {
|
||||
this.saveConfig('settings.autoStart', val)
|
||||
ipcRenderer.send('autoStart', val)
|
||||
}
|
||||
|
||||
handleRename (val: boolean) {
|
||||
this.saveConfig({
|
||||
'settings.rename': val
|
||||
})
|
||||
}
|
||||
|
||||
handleAutoRename (val: boolean) {
|
||||
this.saveConfig({
|
||||
'settings.autoRename': val
|
||||
})
|
||||
}
|
||||
|
||||
compareVersion2Update (current: string, latest: string) {
|
||||
const currentVersion = current.split('.').map(item => parseInt(item))
|
||||
const latestVersion = latest.split('.').map(item => parseInt(item))
|
||||
@ -562,6 +584,7 @@ export default class extends Vue {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
checkUpdate () {
|
||||
this.checkUpdateVisible = true
|
||||
this.$http.get(releaseUrl)
|
||||
@ -576,24 +599,29 @@ export default class extends Vue {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
confirmCheckVersion () {
|
||||
if (this.needUpdate) {
|
||||
remote.shell.openExternal(downloadUrl)
|
||||
ipcRenderer.send(OPEN_URL, downloadUrl)
|
||||
}
|
||||
this.checkUpdateVisible = false
|
||||
}
|
||||
|
||||
cancelCheckVersion () {
|
||||
this.checkUpdateVisible = false
|
||||
}
|
||||
|
||||
handleUploadNotification (val: boolean) {
|
||||
this.saveConfig({
|
||||
'settings.uploadNotification': val
|
||||
})
|
||||
}
|
||||
|
||||
handleMiniWindowOntop (val: boolean) {
|
||||
this.saveConfig('settings.miniWindowOntop', val)
|
||||
this.$message.info('需要重启生效')
|
||||
}
|
||||
|
||||
handleAutoCopyUrl (val: boolean) {
|
||||
this.saveConfig('settings.autoCopy', val)
|
||||
const successNotification = new Notification('设置自动复制链接', {
|
||||
@ -603,6 +631,7 @@ export default class extends Vue {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
confirmLogLevelSetting () {
|
||||
if (this.form.logLevel.length === 0) {
|
||||
return this.$message.error('请选择日志记录等级')
|
||||
@ -618,6 +647,7 @@ export default class extends Vue {
|
||||
}
|
||||
this.logFileVisible = false
|
||||
}
|
||||
|
||||
async cancelLogLevelSetting () {
|
||||
this.logFileVisible = false
|
||||
let logLevel = await this.getConfig<string | string[]>('settings.logLevel')
|
||||
@ -630,6 +660,7 @@ export default class extends Vue {
|
||||
}
|
||||
this.form.logLevel = logLevel
|
||||
}
|
||||
|
||||
confirmServerSetting () {
|
||||
// @ts-ignore
|
||||
this.server.port = parseInt(this.server.port, 10)
|
||||
@ -645,6 +676,7 @@ export default class extends Vue {
|
||||
this.serverVisible = false
|
||||
ipcRenderer.send('updateServer')
|
||||
}
|
||||
|
||||
async cancelServerSetting () {
|
||||
this.serverVisible = false
|
||||
this.server = await this.getConfig('settings.server') || {
|
||||
@ -653,10 +685,11 @@ export default class extends Vue {
|
||||
enable: true
|
||||
}
|
||||
}
|
||||
|
||||
handleLevelDisabled (val: string) {
|
||||
let currentLevel = val
|
||||
const currentLevel = val
|
||||
let flagLevel
|
||||
let result = this.form.logLevel.some(item => {
|
||||
const result = this.form.logLevel.some(item => {
|
||||
if (item === 'all' || item === 'none') {
|
||||
flagLevel = item
|
||||
}
|
||||
@ -673,12 +706,15 @@ export default class extends Vue {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
goConfigPage () {
|
||||
remote.shell.openExternal('https://picgo.github.io/PicGo-Doc/zh/guide/config.html#picgo设置')
|
||||
ipcRenderer.send(OPEN_URL, 'https://picgo.github.io/PicGo-Doc/zh/guide/config.html#picgo设置')
|
||||
}
|
||||
|
||||
goShortCutPage () {
|
||||
this.$router.push('shortKey')
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)
|
||||
}
|
||||
|
@ -109,11 +109,17 @@ import ConfigForm from '@/components/ConfigForm.vue'
|
||||
import { debounce } from 'lodash'
|
||||
import {
|
||||
ipcRenderer,
|
||||
remote,
|
||||
IpcRendererEvent
|
||||
} from 'electron'
|
||||
import { handleStreamlinePluginName } from '~/universal/utils/common'
|
||||
const { Menu } = remote
|
||||
import {
|
||||
OPEN_URL,
|
||||
RELOAD_APP,
|
||||
PICGO_CONFIG_PLUGIN,
|
||||
PICGO_HANDLE_PLUGIN_ING,
|
||||
PICGO_TOGGLE_PLUGIN,
|
||||
SHOW_PLUGIN_PAGE_MENU
|
||||
} from '#/events/constants'
|
||||
|
||||
@Component({
|
||||
name: 'plugin',
|
||||
@ -144,6 +150,7 @@ export default class extends Vue {
|
||||
? `picgo-plugin-${this.searchText}`
|
||||
: this.searchText
|
||||
}
|
||||
|
||||
@Watch('npmSearchText')
|
||||
onNpmSearchTextChange (val: string) {
|
||||
if (val) {
|
||||
@ -154,6 +161,7 @@ export default class extends Vue {
|
||||
this.getPluginList()
|
||||
}
|
||||
}
|
||||
|
||||
@Watch('dialogVisible')
|
||||
onDialogVisible (val: boolean) {
|
||||
if (val) {
|
||||
@ -164,6 +172,7 @@ export default class extends Vue {
|
||||
document.querySelector('.main-content.el-row').style.zIndex = 10
|
||||
}
|
||||
}
|
||||
|
||||
async created () {
|
||||
this.os = process.platform
|
||||
ipcRenderer.on('hideLoading', () => {
|
||||
@ -214,105 +223,45 @@ export default class extends Vue {
|
||||
})
|
||||
this.pluginNameList = this.pluginNameList.filter(item => item !== plugin)
|
||||
})
|
||||
ipcRenderer.on(PICGO_CONFIG_PLUGIN, (evt: IpcRendererEvent, currentType: string, configName: string, config: any) => {
|
||||
this.currentType = currentType
|
||||
this.configName = configName
|
||||
this.dialogVisible = true
|
||||
this.config = config
|
||||
})
|
||||
ipcRenderer.on(PICGO_HANDLE_PLUGIN_ING, (evt: IpcRendererEvent, fullName: string) => {
|
||||
this.pluginList.forEach(item => {
|
||||
if (item.fullName === fullName || (item.name === fullName)) {
|
||||
item.ing = true
|
||||
}
|
||||
})
|
||||
this.loading = true
|
||||
})
|
||||
ipcRenderer.on(PICGO_TOGGLE_PLUGIN, (evt: IpcRendererEvent, fullName: string, enabled: boolean) => {
|
||||
const plugin = this.pluginList.find(item => item.fullName === fullName)
|
||||
if (plugin) {
|
||||
plugin.enabled = enabled
|
||||
this.getPicBeds()
|
||||
this.needReload = true
|
||||
}
|
||||
})
|
||||
this.getPluginList()
|
||||
this.getSearchResult = debounce(this.getSearchResult, 50)
|
||||
this.needReload = await this.getConfig<boolean>('needReload') || false
|
||||
}
|
||||
|
||||
async buildContextMenu (plugin: IPicGoPlugin) {
|
||||
const _this = this
|
||||
let menu = [{
|
||||
label: '启用插件',
|
||||
enabled: !plugin.enabled,
|
||||
click () {
|
||||
_this.saveConfig({
|
||||
[`picgoPlugins.${plugin.fullName}`]: true
|
||||
})
|
||||
plugin.enabled = true
|
||||
_this.getPicBeds()
|
||||
_this.needReload = true
|
||||
}
|
||||
}, {
|
||||
label: '禁用插件',
|
||||
enabled: plugin.enabled,
|
||||
click () {
|
||||
_this.saveConfig({
|
||||
[`picgoPlugins.${plugin.fullName}`]: false
|
||||
})
|
||||
plugin.enabled = false
|
||||
_this.getPicBeds()
|
||||
if (plugin.config.transformer.name) {
|
||||
_this.handleRestoreState('transformer', plugin.config.transformer.name)
|
||||
}
|
||||
if (plugin.config.uploader.name) {
|
||||
_this.handleRestoreState('uploader', plugin.config.uploader.name)
|
||||
}
|
||||
_this.needReload = true
|
||||
}
|
||||
}, {
|
||||
label: '卸载插件',
|
||||
click () {
|
||||
_this.uninstallPlugin(plugin.fullName)
|
||||
}
|
||||
}, {
|
||||
label: '更新插件',
|
||||
click () {
|
||||
_this.updatePlugin(plugin.fullName)
|
||||
}
|
||||
}]
|
||||
for (let i in plugin.config) {
|
||||
if (plugin.config[i].config.length > 0) {
|
||||
const obj = {
|
||||
label: `配置${i} - ${plugin.config[i].fullName || plugin.config[i].name}`,
|
||||
click () {
|
||||
_this.currentType = i
|
||||
_this.configName = plugin.config[i].fullName || plugin.config[i].name
|
||||
_this.dialogVisible = true
|
||||
_this.config = plugin.config[i].config
|
||||
},
|
||||
enabled: plugin.enabled
|
||||
}
|
||||
menu.push(obj)
|
||||
}
|
||||
ipcRenderer.send(SHOW_PLUGIN_PAGE_MENU, plugin)
|
||||
}
|
||||
|
||||
// handle transformer
|
||||
if (plugin.config.transformer.name) {
|
||||
let currentTransformer = await this.getConfig<string>('picBed.transformer') || 'path'
|
||||
let pluginTransformer = plugin.config.transformer.name
|
||||
const obj = {
|
||||
label: `${currentTransformer === pluginTransformer ? '禁用' : '启用'}transformer - ${plugin.config.transformer.name}`,
|
||||
click () {
|
||||
_this.toggleTransformer(plugin.config.transformer.name)
|
||||
}
|
||||
}
|
||||
menu.push(obj)
|
||||
}
|
||||
|
||||
// plugin custom menus
|
||||
if (plugin.guiMenu) {
|
||||
menu.push({
|
||||
// @ts-ignore
|
||||
type: 'separator'
|
||||
})
|
||||
for (let i of plugin.guiMenu) {
|
||||
menu.push({
|
||||
label: i.label,
|
||||
click () {
|
||||
ipcRenderer.send('pluginActions', plugin.fullName, i.label)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.menu = Menu.buildFromTemplate(menu)
|
||||
this.menu.popup()
|
||||
}
|
||||
getPluginList () {
|
||||
ipcRenderer.send('getPluginList')
|
||||
}
|
||||
|
||||
getPicBeds () {
|
||||
ipcRenderer.send('getPicBeds')
|
||||
}
|
||||
|
||||
installPlugin (item: IPicGoPlugin) {
|
||||
if (!item.gui) {
|
||||
this.$confirm('该插件未对可视化界面进行优化, 是否继续安装?', '提示', {
|
||||
@ -330,6 +279,7 @@ export default class extends Vue {
|
||||
ipcRenderer.send('installPlugin', item.fullName)
|
||||
}
|
||||
}
|
||||
|
||||
uninstallPlugin (val: string) {
|
||||
this.pluginList.forEach(item => {
|
||||
if (item.name === val) {
|
||||
@ -339,6 +289,7 @@ export default class extends Vue {
|
||||
this.loading = true
|
||||
ipcRenderer.send('uninstallPlugin', val)
|
||||
}
|
||||
|
||||
updatePlugin (val: string) {
|
||||
this.pluginList.forEach(item => {
|
||||
if (item.fullName === val) {
|
||||
@ -348,10 +299,11 @@ export default class extends Vue {
|
||||
this.loading = true
|
||||
ipcRenderer.send('updatePlugin', val)
|
||||
}
|
||||
|
||||
reloadApp () {
|
||||
remote.app.relaunch()
|
||||
remote.app.exit(0)
|
||||
ipcRenderer.send(RELOAD_APP)
|
||||
}
|
||||
|
||||
async handleReload () {
|
||||
this.saveConfig({
|
||||
needReload: true
|
||||
@ -364,21 +316,11 @@ export default class extends Vue {
|
||||
this.reloadApp()
|
||||
}
|
||||
}
|
||||
|
||||
cleanSearch () {
|
||||
this.searchText = ''
|
||||
}
|
||||
async toggleTransformer (transformer: string) {
|
||||
let currentTransformer = await this.getConfig<string>('picBed.transformer') || 'path'
|
||||
if (currentTransformer === transformer) {
|
||||
this.saveConfig({
|
||||
'picBed.transformer': 'path'
|
||||
})
|
||||
} else {
|
||||
this.saveConfig({
|
||||
'picBed.transformer': transformer
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async handleConfirmConfig () {
|
||||
// @ts-ignore
|
||||
const result = await this.$refs.configForm.validate()
|
||||
@ -410,6 +352,7 @@ export default class extends Vue {
|
||||
this.getPluginList()
|
||||
}
|
||||
}
|
||||
|
||||
getSearchResult (val: string) {
|
||||
// this.$http.get(`https://api.npms.io/v2/search?q=${val}`)
|
||||
this.$http.get(`https://registry.npmjs.com/-/v1/search?text=${val}`)
|
||||
@ -428,6 +371,7 @@ export default class extends Vue {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
handleSearchResult (item: INPMSearchResultObject) {
|
||||
const name = handleStreamlinePluginName(item.package.name)
|
||||
let gui = false
|
||||
@ -450,6 +394,7 @@ export default class extends Vue {
|
||||
ing: false // installing or uninstalling
|
||||
}
|
||||
}
|
||||
|
||||
// restore Uploader & Transformer
|
||||
async handleRestoreState (item: string, name: string) {
|
||||
if (item === 'uploader') {
|
||||
@ -470,18 +415,26 @@ export default class extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
openHomepage (url: string) {
|
||||
if (url) {
|
||||
remote.shell.openExternal(url)
|
||||
ipcRenderer.send(OPEN_URL, url)
|
||||
}
|
||||
}
|
||||
|
||||
goAwesomeList () {
|
||||
remote.shell.openExternal('https://github.com/PicGo/Awesome-PicGo')
|
||||
ipcRenderer.send(OPEN_URL, 'https://github.com/PicGo/Awesome-PicGo')
|
||||
}
|
||||
|
||||
saveConfig (data: IObj) {
|
||||
ipcRenderer.send('picgoSaveData', data)
|
||||
}
|
||||
|
||||
handleImportLocalPlugin () {
|
||||
ipcRenderer.send('importLocalPlugin')
|
||||
this.loading = true
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeAllListeners('pluginList')
|
||||
ipcRenderer.removeAllListeners('installPlugin')
|
||||
|
@ -41,12 +41,15 @@ export default class extends Vue {
|
||||
this.id = id
|
||||
})
|
||||
}
|
||||
|
||||
confirmName () {
|
||||
ipcRenderer.send(`rename${this.id}`, this.fileName)
|
||||
}
|
||||
|
||||
cancel () {
|
||||
ipcRenderer.send(`rename${this.id}`, null)
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeAllListeners('rename')
|
||||
}
|
||||
|
@ -118,35 +118,43 @@ export default class extends Vue {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Watch('keyBindingVisible')
|
||||
onKeyBindingVisibleChange (val: boolean) {
|
||||
ipcRenderer.send(TOGGLE_SHORTKEY_MODIFIED_MODE, val)
|
||||
}
|
||||
|
||||
calcOrigin (item: string) {
|
||||
const [origin] = item.split(':')
|
||||
return origin
|
||||
}
|
||||
|
||||
calcOriginShowName (item: string) {
|
||||
return item.replace('picgo-plugin-', '')
|
||||
}
|
||||
|
||||
toggleEnable (item: IShortKeyConfig) {
|
||||
const status = !item.enable
|
||||
item.enable = status
|
||||
ipcRenderer.send('bindOrUnbindShortKey', item, item.from)
|
||||
}
|
||||
|
||||
keyDetect (event: KeyboardEvent) {
|
||||
this.shortKey = keyDetect(event).join('+')
|
||||
}
|
||||
|
||||
async openKeyBindingDialog (config: IShortKeyConfig, index: number) {
|
||||
this.command = `${config.from}:${config.name}`
|
||||
this.shortKey = await this.getConfig(`settings.shortKey.${this.command}.key`) || ''
|
||||
this.currentIndex = index
|
||||
this.keyBindingVisible = true
|
||||
}
|
||||
|
||||
async cancelKeyBinding () {
|
||||
this.keyBindingVisible = false
|
||||
this.shortKey = await this.getConfig<string>(`settings.shortKey.${this.command}.key`) || ''
|
||||
}
|
||||
|
||||
async confirmKeyBinding () {
|
||||
const oldKey = await this.getConfig<string>(`settings.shortKey.${this.command}.key`)
|
||||
const config = Object.assign({}, this.list[this.currentIndex])
|
||||
@ -159,6 +167,7 @@ export default class extends Vue {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.send(TOGGLE_SHORTKEY_MODIFIED_MODE, false)
|
||||
}
|
||||
|
@ -28,10 +28,9 @@
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import mixin from '@/utils/mixin'
|
||||
import pasteTemplate from '#/utils/pasteTemplate'
|
||||
import { ipcRenderer, clipboard } from 'electron'
|
||||
import { IPasteStyle } from '#/types/enum'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { IResult } from '@picgo/store/dist/types'
|
||||
import { PASTE_TEXT } from '#/events/constants'
|
||||
|
||||
@Component({
|
||||
name: 'tray-page',
|
||||
@ -44,28 +43,31 @@ export default class extends Vue {
|
||||
body: '',
|
||||
icon: ''
|
||||
}
|
||||
|
||||
clipboardFiles: ImgInfo[] = []
|
||||
uploadFlag = false
|
||||
get reverseList () {
|
||||
return this.files.slice().reverse()
|
||||
}
|
||||
|
||||
async getData () {
|
||||
this.files = (await this.$$db.get<ImgInfo>({ orderBy: 'desc', limit: 5 })).data
|
||||
}
|
||||
|
||||
async copyTheLink (item: ImgInfo) {
|
||||
this.notification.body = item.imgUrl!
|
||||
this.notification.icon = item.imgUrl!
|
||||
const myNotification = new Notification(this.notification.title, this.notification)
|
||||
const pasteStyle = await this.getConfig<IPasteStyle>('settings.pasteStyle') || IPasteStyle.MARKDOWN
|
||||
const customLink = await this.getConfig<string>('settings.customLink')
|
||||
clipboard.writeText(pasteTemplate(pasteStyle, item, customLink))
|
||||
ipcRenderer.invoke(PASTE_TEXT, item)
|
||||
myNotification.onclick = () => {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
calcHeight (width: number, height: number): number {
|
||||
return height * 160 / width
|
||||
}
|
||||
|
||||
disableDragFile () {
|
||||
window.addEventListener('dragover', (e) => {
|
||||
e = e || event
|
||||
@ -76,6 +78,7 @@ export default class extends Vue {
|
||||
e.preventDefault()
|
||||
}, false)
|
||||
}
|
||||
|
||||
uploadClipboardFiles () {
|
||||
if (this.uploadFlag) {
|
||||
return
|
||||
@ -83,6 +86,7 @@ export default class extends Vue {
|
||||
this.uploadFlag = true
|
||||
ipcRenderer.send('uploadClipboardFiles')
|
||||
}
|
||||
|
||||
mounted () {
|
||||
this.disableDragFile()
|
||||
this.getData()
|
||||
@ -96,15 +100,16 @@ export default class extends Vue {
|
||||
ipcRenderer.on('clipboardFiles', (event: Event, files: ImgInfo[]) => {
|
||||
this.clipboardFiles = files
|
||||
})
|
||||
ipcRenderer.on('uploadFiles', async (event: Event) => {
|
||||
ipcRenderer.on('uploadFiles', async () => {
|
||||
this.files = (await this.$$db.get<ImgInfo>({ orderBy: 'desc', limit: 5 })).data
|
||||
console.log(this.files)
|
||||
this.uploadFlag = false
|
||||
})
|
||||
ipcRenderer.on('updateFiles', (event: Event) => {
|
||||
ipcRenderer.on('updateFiles', () => {
|
||||
this.getData()
|
||||
})
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeAllListeners('dragFiles')
|
||||
ipcRenderer.removeAllListeners('clipboardFiles')
|
||||
|
@ -60,17 +60,16 @@
|
||||
import { Component, Vue, Watch } from 'vue-property-decorator'
|
||||
import {
|
||||
ipcRenderer,
|
||||
IpcRendererEvent,
|
||||
remote
|
||||
IpcRendererEvent
|
||||
} from 'electron'
|
||||
import {
|
||||
SHOW_INPUT_BOX,
|
||||
SHOW_INPUT_BOX_RESPONSE
|
||||
SHOW_INPUT_BOX_RESPONSE,
|
||||
SHOW_UPLOAD_PAGE_MENU
|
||||
} from '~/universal/events/constants'
|
||||
import {
|
||||
isUrl
|
||||
} from '~/universal/utils/common'
|
||||
const { Menu } = remote
|
||||
@Component({
|
||||
name: 'upload'
|
||||
})
|
||||
@ -82,7 +81,6 @@ export default class extends Vue {
|
||||
pasteStyle = ''
|
||||
picBed: IPicBedType[] = []
|
||||
picBedName = ''
|
||||
menu: Electron.Menu | null= null
|
||||
mounted () {
|
||||
ipcRenderer.on('uploadProgress', (event: IpcRendererEvent, progress: number) => {
|
||||
if (progress !== -1) {
|
||||
@ -102,6 +100,7 @@ export default class extends Vue {
|
||||
ipcRenderer.on('getPicBeds', this.getPicBeds)
|
||||
this.$bus.$on(SHOW_INPUT_BOX_RESPONSE, this.handleInputBoxValue)
|
||||
}
|
||||
|
||||
@Watch('progress')
|
||||
onProgressChange (val: number) {
|
||||
if (val === 100) {
|
||||
@ -114,12 +113,14 @@ export default class extends Vue {
|
||||
}, 1200)
|
||||
}
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
this.$bus.$off(SHOW_INPUT_BOX_RESPONSE)
|
||||
ipcRenderer.removeAllListeners('uploadProgress')
|
||||
ipcRenderer.removeAllListeners('syncPicBed')
|
||||
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)
|
||||
}
|
||||
|
||||
onDrop (e: DragEvent) {
|
||||
this.dragover = false
|
||||
const items = e.dataTransfer!.items
|
||||
@ -136,6 +137,7 @@ export default class extends Vue {
|
||||
this.ipcSendFiles(e.dataTransfer!.files)
|
||||
}
|
||||
}
|
||||
|
||||
handleURLDrag (items: DataTransferItemList, dataTransfer: DataTransfer) {
|
||||
// text/html
|
||||
// Use this data to get a more precise URL
|
||||
@ -151,17 +153,20 @@ export default class extends Vue {
|
||||
this.$message.error('请拖入合法的图片文件或者图片URL地址')
|
||||
}
|
||||
}
|
||||
|
||||
openUplodWindow () {
|
||||
document.getElementById('file-uploader')!.click()
|
||||
}
|
||||
|
||||
onChange (e: any) {
|
||||
this.ipcSendFiles(e.target.files);
|
||||
(document.getElementById('file-uploader') as HTMLInputElement).value = ''
|
||||
}
|
||||
|
||||
ipcSendFiles (files: FileList) {
|
||||
let sendFiles: IFileWithPath[] = []
|
||||
Array.from(files).forEach((item, index) => {
|
||||
let obj = {
|
||||
const sendFiles: IFileWithPath[] = []
|
||||
Array.from(files).forEach((item) => {
|
||||
const obj = {
|
||||
name: item.name,
|
||||
path: item.path
|
||||
}
|
||||
@ -169,17 +174,21 @@ export default class extends Vue {
|
||||
})
|
||||
ipcRenderer.send('uploadChoosedFiles', sendFiles)
|
||||
}
|
||||
|
||||
async getPasteStyle () {
|
||||
this.pasteStyle = await this.getConfig('settings.pasteStyle') || 'markdown'
|
||||
}
|
||||
|
||||
handlePasteStyleChange (val: string) {
|
||||
this.saveConfig({
|
||||
'settings.pasteStyle': val
|
||||
})
|
||||
}
|
||||
|
||||
uploadClipboardFiles () {
|
||||
ipcRenderer.send('uploadClipboardFilesFromUploadPage')
|
||||
}
|
||||
|
||||
async uploadURLFiles () {
|
||||
const str = await navigator.clipboard.readText()
|
||||
this.$bus.$emit(SHOW_INPUT_BOX, {
|
||||
@ -188,6 +197,7 @@ export default class extends Vue {
|
||||
placeholder: 'http://或者https://开头'
|
||||
})
|
||||
}
|
||||
|
||||
handleInputBoxValue (val: string) {
|
||||
if (val === '') return false
|
||||
if (isUrl(val)) {
|
||||
@ -198,6 +208,7 @@ export default class extends Vue {
|
||||
this.$message.error('请输入合法的URL')
|
||||
}
|
||||
}
|
||||
|
||||
async getDefaultPicBed () {
|
||||
const currentPicBed = await this.getConfig<string>('picBed.current')
|
||||
this.picBed.forEach(item => {
|
||||
@ -206,34 +217,14 @@ export default class extends Vue {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getPicBeds (event: Event, picBeds: IPicBedType[]) {
|
||||
this.picBed = picBeds
|
||||
this.getDefaultPicBed()
|
||||
}
|
||||
|
||||
async handleChangePicBed () {
|
||||
await this.buildMenu()
|
||||
// this.menu.popup(remote.getCurrentWindow())
|
||||
this.menu!.popup()
|
||||
}
|
||||
async buildMenu () {
|
||||
const _this = this
|
||||
const currentPicBed = await this.getConfig<string>('picBed.current')
|
||||
const submenu = this.picBed.filter(item => item.visible).map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
type: 'radio',
|
||||
checked: currentPicBed === item.type,
|
||||
click () {
|
||||
_this.saveConfig({
|
||||
'picBed.current': item.type,
|
||||
'picBed.uploader': item.type
|
||||
})
|
||||
ipcRenderer.send('syncPicBed')
|
||||
}
|
||||
}
|
||||
})
|
||||
// @ts-ignore
|
||||
this.menu = Menu.buildFromTemplate(submenu)
|
||||
ipcRenderer.send(SHOW_UPLOAD_PAGE_MENU)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -86,12 +86,14 @@ export default class extends Vue {
|
||||
customUrl: '',
|
||||
options: ''
|
||||
}
|
||||
|
||||
async created () {
|
||||
const config = await this.getConfig<IAliYunConfig>('picBed.aliyun')
|
||||
if (config) {
|
||||
this.form = Object.assign({}, config)
|
||||
}
|
||||
}
|
||||
|
||||
confirm () {
|
||||
// @ts-ignore
|
||||
this.$refs.aliyun.validate((valid) => {
|
||||
|
@ -71,12 +71,14 @@ export default class extends Vue {
|
||||
customUrl: '',
|
||||
branch: ''
|
||||
}
|
||||
|
||||
async created () {
|
||||
const config = await this.getConfig<IGitHubConfig>('picBed.github')
|
||||
if (config) {
|
||||
this.form = Object.assign({}, config)
|
||||
}
|
||||
}
|
||||
|
||||
confirm () {
|
||||
// @ts-ignore
|
||||
this.$refs.github.validate((valid) => {
|
||||
|
@ -48,12 +48,14 @@ export default class extends Vue {
|
||||
clientId: '',
|
||||
proxy: ''
|
||||
}
|
||||
|
||||
async created () {
|
||||
const config = await this.getConfig<IImgurConfig>('picBed.imgur')
|
||||
if (config) {
|
||||
this.form = Object.assign({}, config)
|
||||
}
|
||||
}
|
||||
|
||||
confirm () {
|
||||
// @ts-ignore
|
||||
this.$refs.imgur.validate((valid) => {
|
||||
|
@ -52,6 +52,7 @@ export default class extends Vue {
|
||||
ipcRenderer.send('getPicBedConfig', this.$route.params.type)
|
||||
ipcRenderer.on('getPicBedConfig', this.getPicBeds)
|
||||
}
|
||||
|
||||
async handleConfirm () {
|
||||
// @ts-ignore
|
||||
const result = await this.$refs.configForm.validate()
|
||||
@ -67,6 +68,7 @@ export default class extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setDefaultPicBed (type: string) {
|
||||
this.saveConfig({
|
||||
'picBed.current': type,
|
||||
@ -81,10 +83,12 @@ export default class extends Vue {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
getPicBeds (event: IpcRendererEvent, config: any[], name: string) {
|
||||
this.config = config
|
||||
this.picBedName = name
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
ipcRenderer.removeListener('getPicBedConfig', this.getPicBeds)
|
||||
}
|
||||
|
@ -88,12 +88,14 @@ export default class extends Vue {
|
||||
options: '',
|
||||
path: ''
|
||||
}
|
||||
|
||||
async created () {
|
||||
const config = await this.getConfig<IQiniuConfig>('picBed.qiniu')
|
||||
if (config) {
|
||||
this.form = Object.assign({}, config)
|
||||
}
|
||||
}
|
||||
|
||||
confirm () {
|
||||
// @ts-ignore
|
||||
this.$refs.qiniu.validate((valid) => {
|
||||
|
@ -41,12 +41,14 @@ export default class extends Vue {
|
||||
form: ISMMSConfig = {
|
||||
token: ''
|
||||
}
|
||||
|
||||
async created () {
|
||||
const config = await this.getConfig<string | boolean>('picBed.smms.token')
|
||||
if (typeof config !== 'boolean') {
|
||||
this.form.token = config || ''
|
||||
}
|
||||
}
|
||||
|
||||
confirm () {
|
||||
// @ts-ignore
|
||||
this.$refs.smms.validate((valid) => {
|
||||
|
@ -86,9 +86,10 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import mixin from '@/utils/ConfirmButtonMixin'
|
||||
import { remote } from 'electron'
|
||||
import { OPEN_URL } from '#/events/constants'
|
||||
@Component({
|
||||
name: 'tcyun',
|
||||
mixins: [mixin]
|
||||
@ -104,12 +105,14 @@ export default class extends Vue {
|
||||
customUrl: '',
|
||||
version: 'v4'
|
||||
}
|
||||
|
||||
async created () {
|
||||
const config = await this.getConfig<ITcYunConfig>('picBed.tcyun')
|
||||
if (config) {
|
||||
this.form = Object.assign({}, config)
|
||||
}
|
||||
}
|
||||
|
||||
confirm () {
|
||||
// @ts-ignore
|
||||
this.$refs.tcyun.validate((valid) => {
|
||||
@ -128,8 +131,9 @@ export default class extends Vue {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
openWiki () {
|
||||
remote.shell.openExternal('https://github.com/Molunerfinn/PicGo/wiki/%E8%AF%A6%E7%BB%86%E7%AA%97%E5%8F%A3%E7%9A%84%E4%BD%BF%E7%94%A8#腾讯云cos')
|
||||
ipcRenderer.send(OPEN_URL, 'https://picgo.github.io/PicGo-Doc/zh/guide/config.html#%E8%85%BE%E8%AE%AF%E4%BA%91cos')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -79,12 +79,14 @@ export default class extends Vue {
|
||||
options: '',
|
||||
path: ''
|
||||
}
|
||||
|
||||
async created () {
|
||||
const config = await this.getConfig<IUpYunConfig>('picBed.upyun')
|
||||
if (config) {
|
||||
this.form = Object.assign({}, config)
|
||||
}
|
||||
}
|
||||
|
||||
confirm () {
|
||||
// @ts-ignore
|
||||
this.$refs.tcyun.validate((valid) => {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { IConfig } from 'picgo/dist/src/types'
|
||||
@Component
|
||||
export default class extends Vue {
|
||||
@ -10,6 +9,7 @@ export default class extends Vue {
|
||||
this.defaultPicBed = config?.picBed?.uploader || config?.picBed?.current || 'smms'
|
||||
}
|
||||
}
|
||||
|
||||
setDefaultPicBed (type: string) {
|
||||
this.saveConfig({
|
||||
'picBed.current': type,
|
||||
|
@ -15,26 +15,32 @@ export class GalleryDB implements IGalleryDB {
|
||||
const res = await this.msgHandler<IGetResult<T>>(PICGO_GET_DB, filter)
|
||||
return res
|
||||
}
|
||||
|
||||
async insert<T> (value: T): Promise<IResult<T>> {
|
||||
const res = await this.msgHandler<IResult<T>>(PICGO_INSERT_DB, value)
|
||||
return res
|
||||
}
|
||||
|
||||
async insertMany<T> (value: T[]): Promise<IResult<T>[]> {
|
||||
const res = await this.msgHandler<IResult<T>[]>(PICGO_INSERT_MANY_DB, value)
|
||||
return res
|
||||
}
|
||||
|
||||
async updateById (id: string, value: IObject): Promise<boolean> {
|
||||
const res = await this.msgHandler<boolean>(PICGO_UPDATE_BY_ID_DB, id, value)
|
||||
return res
|
||||
}
|
||||
|
||||
async getById<T> (id: string): Promise<IResult<T> | undefined> {
|
||||
const res = await this.msgHandler<IResult<T> | undefined>(PICGO_GET_BY_ID_DB, id)
|
||||
return res
|
||||
}
|
||||
|
||||
async removeById (id: string): Promise<void> {
|
||||
const res = await this.msgHandler<void>(PICGO_REMOVE_BY_ID_DB, id)
|
||||
return res
|
||||
}
|
||||
|
||||
private msgHandler<T> (method: string, ...args: any[]): Promise<T> {
|
||||
return new Promise((resolve) => {
|
||||
const callbackId = uuid()
|
||||
|
@ -14,16 +14,16 @@ const isSpecialKey = (keyCode: number) => {
|
||||
|
||||
const keyDetect = (event: KeyboardEvent) => {
|
||||
const meta = process.platform === 'darwin' ? 'Cmd' : 'Super'
|
||||
let specialKey = {
|
||||
const specialKey = {
|
||||
Ctrl: event.ctrlKey,
|
||||
Shift: event.shiftKey,
|
||||
Alt: event.altKey,
|
||||
[meta]: event.metaKey
|
||||
}
|
||||
|
||||
let pressKey = []
|
||||
const pressKey = []
|
||||
|
||||
for (let i in specialKey) {
|
||||
for (const i in specialKey) {
|
||||
if (specialKey[i]) {
|
||||
pressKey.push(i)
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ export default class extends Vue {
|
||||
}
|
||||
ipcRenderer.send(PICGO_SAVE_CONFIG, config)
|
||||
}
|
||||
|
||||
getConfig<T> (key?: string): Promise<T | undefined> {
|
||||
return new Promise((resolve) => {
|
||||
const callbackId = uuid()
|
||||
|
@ -4,11 +4,13 @@ export default class extends Vue {
|
||||
mounted () {
|
||||
this.disableDragEvent()
|
||||
}
|
||||
|
||||
disableDragEvent () {
|
||||
window.addEventListener('dragenter', this.disableDrag, false)
|
||||
window.addEventListener('dragover', this.disableDrag)
|
||||
window.addEventListener('drop', this.disableDrag)
|
||||
}
|
||||
|
||||
disableDrag (e: DragEvent) {
|
||||
const dropzone = document.getElementById('upload-area')
|
||||
if (dropzone === null || !dropzone.contains(<Node>e.target)) {
|
||||
@ -17,6 +19,7 @@ export default class extends Vue {
|
||||
e.dataTransfer!.dropEffect = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
beforeDestroy () {
|
||||
window.removeEventListener('dragenter', this.disableDrag, false)
|
||||
window.removeEventListener('dragover', this.disableDrag)
|
||||
|
@ -14,3 +14,16 @@ export const PICGO_GET_BY_ID_DB = 'PICGO_GET_BY_ID_DB'
|
||||
export const PICGO_REMOVE_BY_ID_DB = 'PICGO_REMOVE_BY_ID_DB'
|
||||
export const PICGO_OPEN_FILE = 'PICGO_OPEN_FILE'
|
||||
export const OPEN_DEVTOOLS = 'OPEN_DEVTOOLS'
|
||||
export const SHOW_MINI_PAGE_MENU = 'SHOW_MINI_PAGE_MENU'
|
||||
export const SHOW_MAIN_PAGE_MENU = 'SHOW_MAIN_PAGE_MENU'
|
||||
export const SHOW_UPLOAD_PAGE_MENU = 'SHOW_UPLOAD_PAGE_MENU'
|
||||
export const SHOW_PLUGIN_PAGE_MENU = 'SHOW_PLUGIN_PAGE_MENU'
|
||||
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_TOGGLE_PLUGIN = 'PICGO_TOGGLE_PLUGIN'
|
||||
export const PASTE_TEXT = 'PASTE_TEXT'
|
||||
|
10
src/universal/types/electron.d.ts
vendored
10
src/universal/types/electron.d.ts
vendored
@ -23,11 +23,7 @@ declare interface IWindowManager {
|
||||
|
||||
// https://stackoverflow.com/questions/35074713/extending-typescript-global-object-in-node-js/44387594#44387594
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
interface Global {
|
||||
PICGO_GUI_VERSION: string
|
||||
PICGO_CORE_VERSION: string
|
||||
notificationList?: IAppNotification[]
|
||||
}
|
||||
}
|
||||
var PICGO_GUI_VERSION: string
|
||||
var PICGO_CORE_VERSION: string
|
||||
var notificationList: IAppNotification[]
|
||||
}
|
||||
|
3
src/universal/types/types.d.ts
vendored
3
src/universal/types/types.d.ts
vendored
@ -15,7 +15,7 @@ declare interface ErrnoException extends Error {
|
||||
stack?: string;
|
||||
}
|
||||
|
||||
declare var __static: string
|
||||
declare let __static: string
|
||||
|
||||
declare type ILogType = 'success' | 'info' | 'warn' | 'error'
|
||||
|
||||
@ -94,6 +94,7 @@ interface IBrowserWindowOptions {
|
||||
webPreferences: {
|
||||
nodeIntegration: boolean,
|
||||
nodeIntegrationInWorker: boolean,
|
||||
contextIsolation: boolean,
|
||||
backgroundThrottling: boolean
|
||||
webSecurity?: boolean
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2020",
|
||||
"target": "es2019", // https://github.com/TypeStrong/ts-loader/issues/1061
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
|
@ -23,6 +23,7 @@ const config = {
|
||||
},
|
||||
pluginOptions: {
|
||||
electronBuilder: {
|
||||
nodeIntegration: true, // will remove in the future
|
||||
customFileProtocol: 'picgo://./',
|
||||
externals: ['picgo'],
|
||||
chainWebpackMainProcess: config => {
|
||||
|
Loading…
Reference in New Issue
Block a user