mirror of
https://github.com/Molunerfinn/PicGo.git
synced 2024-04-21 10:31:33 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
962c9f2f37 | ||
|
|
4ebd76ff11 | ||
|
|
c3fe613696 | ||
|
|
ee46ab1fb7 | ||
|
|
3caeccc492 | ||
|
|
c4f0a30c51 | ||
|
|
762dc9b2cc | ||
|
|
73870a5326 | ||
|
|
5f2b7c7802 | ||
|
|
0d6fdc4727 | ||
|
|
ded7998fbc | ||
|
|
3913cef1e6 |
@@ -1,3 +1,56 @@
|
|||||||
|
## :tada: 2.2.2 (2020-01-20)
|
||||||
|
|
||||||
|
|
||||||
|
### :bug: Bug Fixes
|
||||||
|
|
||||||
|
* picgo-server upload clipboard file's result bug ([4ebd76f](https://github.com/Molunerfinn/PicGo/commit/4ebd76f))
|
||||||
|
* releaseUrl may can't get latest version ([ee46ab1](https://github.com/Molunerfinn/PicGo/commit/ee46ab1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## :tada: 2.2.1 (2020-01-09)
|
||||||
|
|
||||||
|
|
||||||
|
### :sparkles: Features
|
||||||
|
|
||||||
|
* add alias for plugin config name ([5a06483](https://github.com/Molunerfinn/PicGo/commit/5a06483))
|
||||||
|
* add aliyun oss options ([a33f1ad](https://github.com/Molunerfinn/PicGo/commit/a33f1ad)), closes [#347](https://github.com/Molunerfinn/PicGo/issues/347)
|
||||||
|
* **server:** add http server for uploading images by a http request ([c56d4ef](https://github.com/Molunerfinn/PicGo/commit/c56d4ef))
|
||||||
|
* add server config settings ([6b57cf7](https://github.com/Molunerfinn/PicGo/commit/6b57cf7))
|
||||||
|
* only shows visible pic-beds ([9d4d605](https://github.com/Molunerfinn/PicGo/commit/9d4d605)), closes [#310](https://github.com/Molunerfinn/PicGo/issues/310)
|
||||||
|
|
||||||
|
|
||||||
|
### :bug: Bug Fixes
|
||||||
|
|
||||||
|
* decrease title-bar z-index when config-form dialog shows ([f2750e1](https://github.com/Molunerfinn/PicGo/commit/f2750e1))
|
||||||
|
* **website:** website pictures error ([a5b6526](https://github.com/Molunerfinn/PicGo/commit/a5b6526))
|
||||||
|
* add new tray icon for macOS dark-mode ([c5adf3b](https://github.com/Molunerfinn/PicGo/commit/c5adf3b)), closes [#267](https://github.com/Molunerfinn/PicGo/issues/267)
|
||||||
|
* beforeOpen handler in windows ([cd30a6c](https://github.com/Molunerfinn/PicGo/commit/cd30a6c))
|
||||||
|
* busApi event register first && emit later ([e1a0cbb](https://github.com/Molunerfinn/PicGo/commit/e1a0cbb))
|
||||||
|
* enum type error ([4e3fa28](https://github.com/Molunerfinn/PicGo/commit/4e3fa28))
|
||||||
|
* handle empty request-body ([81e6acb](https://github.com/Molunerfinn/PicGo/commit/81e6acb))
|
||||||
|
* launch error in new structrue ([bc8e641](https://github.com/Molunerfinn/PicGo/commit/bc8e641))
|
||||||
|
* miniWindow minimize bug ([5f2b7c7](https://github.com/Molunerfinn/PicGo/commit/5f2b7c7))
|
||||||
|
* plugin config-form && default plugin logo ([514fc40](https://github.com/Molunerfinn/PicGo/commit/514fc40))
|
||||||
|
* release script ([b4f10c6](https://github.com/Molunerfinn/PicGo/commit/b4f10c6))
|
||||||
|
* removeById handler error ([c4f0a30](https://github.com/Molunerfinn/PicGo/commit/c4f0a30)), closes [#382](https://github.com/Molunerfinn/PicGo/issues/382)
|
||||||
|
* rename page not work ([29a55ed](https://github.com/Molunerfinn/PicGo/commit/29a55ed))
|
||||||
|
* save debug mode && PICGO_ENV into config file ([c6ead5b](https://github.com/Molunerfinn/PicGo/commit/c6ead5b))
|
||||||
|
* server may never start ([73870a5](https://github.com/Molunerfinn/PicGo/commit/73870a5))
|
||||||
|
* settingPage && miniPage style in windows ([3fd9572](https://github.com/Molunerfinn/PicGo/commit/3fd9572))
|
||||||
|
|
||||||
|
|
||||||
|
### :pencil: Documentation
|
||||||
|
|
||||||
|
* add note for windows electron mirror ([46a49ed](https://github.com/Molunerfinn/PicGo/commit/46a49ed))
|
||||||
|
* remove weibo picbed ([e81b8f4](https://github.com/Molunerfinn/PicGo/commit/e81b8f4))
|
||||||
|
* update installation by scoop ([91b397d](https://github.com/Molunerfinn/PicGo/commit/91b397d)), closes [#295](https://github.com/Molunerfinn/PicGo/issues/295)
|
||||||
|
* update readme ([1b3522e](https://github.com/Molunerfinn/PicGo/commit/1b3522e))
|
||||||
|
* update README ([f491209](https://github.com/Molunerfinn/PicGo/commit/f491209))
|
||||||
|
* update site ([fe9e19a](https://github.com/Molunerfinn/PicGo/commit/fe9e19a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# :tada: 2.2.0 (2020-01-01)
|
# :tada: 2.2.0 (2020-01-01)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "picgo",
|
"name": "picgo",
|
||||||
"version": "2.2.0",
|
"version": "2.2.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve",
|
||||||
|
|||||||
+25
-593
@@ -1,18 +1,6 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
app,
|
app,
|
||||||
BrowserWindow,
|
|
||||||
Tray,
|
|
||||||
Menu,
|
|
||||||
Notification,
|
|
||||||
clipboard,
|
|
||||||
ipcMain,
|
|
||||||
globalShortcut,
|
globalShortcut,
|
||||||
dialog,
|
|
||||||
systemPreferences,
|
|
||||||
WebContents,
|
|
||||||
IpcMainEvent,
|
|
||||||
protocol
|
protocol
|
||||||
} from 'electron'
|
} from 'electron'
|
||||||
import {
|
import {
|
||||||
@@ -20,550 +8,38 @@ import {
|
|||||||
installVueDevtools
|
installVueDevtools
|
||||||
} from 'vue-cli-plugin-electron-builder/lib'
|
} from 'vue-cli-plugin-electron-builder/lib'
|
||||||
import db from '#/datastore'
|
import db from '#/datastore'
|
||||||
import picgo from '~/main/utils/picgo'
|
import { IWindowList } from '~/main/apis/window/constants'
|
||||||
import uploader from '~/main/utils/uploader'
|
import windowManager from '~/main/apis/window/windowManager'
|
||||||
|
import {
|
||||||
|
uploadChoosedFiles,
|
||||||
|
uploadClipboardFiles
|
||||||
|
} from '~/main/apis/uploader/api'
|
||||||
import beforeOpen from '~/main/utils/beforeOpen'
|
import beforeOpen from '~/main/utils/beforeOpen'
|
||||||
import pasteTemplate from '#/utils/pasteTemplate'
|
|
||||||
import updateChecker from '~/main/utils/updateChecker'
|
import updateChecker from '~/main/utils/updateChecker'
|
||||||
import { getPicBeds } from '~/main/utils/getPicBeds'
|
import ipcList from '~/main/apis/eventCenter/ipcList'
|
||||||
import pkg from 'root/package.json'
|
import busEventList from '~/main/apis/eventCenter/busEventList'
|
||||||
import picgoCoreIPC from '~/main/utils/picgoCoreIPC'
|
|
||||||
import fixPath from 'fix-path'
|
import fixPath from 'fix-path'
|
||||||
import { getUploadFiles } from '~/main/utils/handleArgv'
|
import { getUploadFiles } from '~/main/utils/handleArgv'
|
||||||
import bus from '~/main/utils/eventBus'
|
import bus from '~/main/utils/eventBus'
|
||||||
import {
|
import {
|
||||||
updateShortKeyFromVersion212
|
updateShortKeyFromVersion212
|
||||||
} from '~/main/migrate/shortKeyUpdateHelper'
|
} from '~/main/migrate'
|
||||||
import shortKeyHandler from '~/main/utils/shortKeyHandler'
|
import shortKeyHandler from '~/main/apis/shortKey/shortKeyHandler'
|
||||||
import logger from '~/main/utils/logger'
|
|
||||||
import {
|
|
||||||
UPLOAD_WITH_FILES,
|
|
||||||
UPLOAD_WITH_FILES_RESPONSE,
|
|
||||||
UPLOAD_WITH_CLIPBOARD_FILES,
|
|
||||||
UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE,
|
|
||||||
GET_WINDOW_ID,
|
|
||||||
GET_WINDOW_ID_REPONSE,
|
|
||||||
GET_SETTING_WINDOW_ID,
|
|
||||||
GET_SETTING_WINDOW_ID_RESPONSE
|
|
||||||
} from '~/main/utils/busApi/constants'
|
|
||||||
import server from '~/main/server/index'
|
import server from '~/main/server/index'
|
||||||
|
import {
|
||||||
|
createTray
|
||||||
|
} from '~/main/apis/app'
|
||||||
|
|
||||||
const isDevelopment = process.env.NODE_ENV !== 'production'
|
const isDevelopment = process.env.NODE_ENV !== 'production'
|
||||||
protocol.registerSchemesAsPrivileged([{ scheme: 'picgo', privileges: { secure: true, standard: true } }])
|
protocol.registerSchemesAsPrivileged([{ scheme: 'picgo', privileges: { secure: true, standard: true } }])
|
||||||
|
|
||||||
beforeOpen()
|
beforeOpen()
|
||||||
|
|
||||||
let window: BrowserWindow | null
|
|
||||||
let settingWindow: BrowserWindow | null
|
|
||||||
let miniWindow: BrowserWindow | null
|
|
||||||
let tray: Tray | null
|
|
||||||
let menu: Menu | null
|
|
||||||
let contextMenu: Menu | null
|
|
||||||
const winURL = isDevelopment
|
|
||||||
? (process.env.WEBPACK_DEV_SERVER_URL as string)
|
|
||||||
: `picgo://./index.html`
|
|
||||||
const settingWinURL = isDevelopment
|
|
||||||
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#setting/upload`
|
|
||||||
: `picgo://./index.html#setting/upload`
|
|
||||||
const miniWinURL = isDevelopment
|
|
||||||
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#mini-page`
|
|
||||||
: `picgo://./index.html#mini-page`
|
|
||||||
|
|
||||||
// fix the $PATH in macOS
|
// fix the $PATH in macOS
|
||||||
fixPath()
|
fixPath()
|
||||||
|
|
||||||
function createContextMenu () {
|
ipcList.listen()
|
||||||
const picBeds = getPicBeds()
|
busEventList.listen()
|
||||||
const submenu = picBeds.filter(item => item.visible).map(item => {
|
|
||||||
return {
|
|
||||||
label: item.name,
|
|
||||||
type: 'radio',
|
|
||||||
checked: db.get('picBed.current') === item.type,
|
|
||||||
click () {
|
|
||||||
picgo.saveConfig({
|
|
||||||
'picBed.current': item.type
|
|
||||||
})
|
|
||||||
if (settingWindow) {
|
|
||||||
settingWindow.webContents.send('syncPicBed')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
contextMenu = Menu.buildFromTemplate([
|
|
||||||
{
|
|
||||||
label: '关于',
|
|
||||||
click () {
|
|
||||||
dialog.showMessageBox({
|
|
||||||
title: 'PicGo',
|
|
||||||
message: 'PicGo',
|
|
||||||
detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '打开详细窗口',
|
|
||||||
click () {
|
|
||||||
if (settingWindow === null) {
|
|
||||||
createSettingWindow()
|
|
||||||
settingWindow!.show()
|
|
||||||
} else {
|
|
||||||
settingWindow.show()
|
|
||||||
settingWindow.focus()
|
|
||||||
}
|
|
||||||
if (miniWindow) {
|
|
||||||
miniWindow.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '选择默认图床',
|
|
||||||
type: 'submenu',
|
|
||||||
// @ts-ignore
|
|
||||||
submenu
|
|
||||||
},
|
|
||||||
// @ts-ignore
|
|
||||||
{
|
|
||||||
label: '打开更新助手',
|
|
||||||
type: 'checkbox',
|
|
||||||
checked: db.get('settings.showUpdateTip'),
|
|
||||||
click () {
|
|
||||||
const value = db.get('settings.showUpdateTip')
|
|
||||||
db.set('settings.showUpdateTip', !value)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '重启应用',
|
|
||||||
click () {
|
|
||||||
app.relaunch()
|
|
||||||
app.exit(0)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// @ts-ignore
|
|
||||||
{
|
|
||||||
role: 'quit',
|
|
||||||
label: '退出'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
function createTray () {
|
|
||||||
const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png`
|
|
||||||
tray = new Tray(menubarPic)
|
|
||||||
tray.on('right-click', () => {
|
|
||||||
if (window) {
|
|
||||||
window.hide()
|
|
||||||
}
|
|
||||||
createContextMenu()
|
|
||||||
tray!.popUpContextMenu(contextMenu!)
|
|
||||||
})
|
|
||||||
tray.on('click', (event, bounds) => {
|
|
||||||
if (process.platform === 'darwin') {
|
|
||||||
toggleWindow(bounds)
|
|
||||||
setTimeout(() => {
|
|
||||||
let img = clipboard.readImage()
|
|
||||||
let obj: ImgInfo[] = []
|
|
||||||
if (!img.isEmpty()) {
|
|
||||||
// 从剪贴板来的图片默认转为png
|
|
||||||
// @ts-ignore
|
|
||||||
const imgUrl = 'data:image/png;base64,' + Buffer.from(img.toPNG(), 'binary').toString('base64')
|
|
||||||
obj.push({
|
|
||||||
width: img.getSize().width,
|
|
||||||
height: img.getSize().height,
|
|
||||||
imgUrl
|
|
||||||
})
|
|
||||||
}
|
|
||||||
window!.webContents.send('clipboardFiles', obj)
|
|
||||||
}, 0)
|
|
||||||
} else {
|
|
||||||
if (window) {
|
|
||||||
window.hide()
|
|
||||||
}
|
|
||||||
if (settingWindow === null) {
|
|
||||||
createSettingWindow()
|
|
||||||
settingWindow!.show()
|
|
||||||
} else {
|
|
||||||
settingWindow.show()
|
|
||||||
settingWindow.focus()
|
|
||||||
}
|
|
||||||
if (miniWindow) {
|
|
||||||
miniWindow.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tray.on('drag-enter', () => {
|
|
||||||
if (systemPreferences.isDarkMode()) {
|
|
||||||
tray!.setImage(`${__static}/upload-dark.png`)
|
|
||||||
} else {
|
|
||||||
tray!.setImage(`${__static}/upload.png`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tray.on('drag-end', () => {
|
|
||||||
tray!.setImage(`${__static}/menubar.png`)
|
|
||||||
})
|
|
||||||
|
|
||||||
tray.on('drop-files', async (event: Event, files: string[]) => {
|
|
||||||
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
|
||||||
const imgs = await uploader.setWebContents(window!.webContents).upload(files)
|
|
||||||
if (imgs !== false) {
|
|
||||||
for (let i = 0; i < imgs.length; i++) {
|
|
||||||
clipboard.writeText(pasteTemplate(pasteStyle, imgs[i]))
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '上传成功',
|
|
||||||
body: imgs[i].imgUrl!,
|
|
||||||
icon: files[i]
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
notification.show()
|
|
||||||
}, i * 100)
|
|
||||||
db.insert('uploaded', imgs[i])
|
|
||||||
}
|
|
||||||
window!.webContents.send('dragFiles', imgs)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// toggleWindow()
|
|
||||||
}
|
|
||||||
|
|
||||||
const createWindow = () => {
|
|
||||||
if (process.platform !== 'darwin' && process.platform !== 'win32') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
window = new BrowserWindow({
|
|
||||||
height: 350,
|
|
||||||
width: 196, // 196
|
|
||||||
show: false,
|
|
||||||
frame: false,
|
|
||||||
fullscreenable: false,
|
|
||||||
resizable: false,
|
|
||||||
transparent: true,
|
|
||||||
vibrancy: 'ultra-dark',
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: true,
|
|
||||||
nodeIntegrationInWorker: true,
|
|
||||||
backgroundThrottling: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
window.loadURL(winURL)
|
|
||||||
|
|
||||||
window.on('closed', () => {
|
|
||||||
window = null
|
|
||||||
})
|
|
||||||
|
|
||||||
window.on('blur', () => {
|
|
||||||
window!.hide()
|
|
||||||
})
|
|
||||||
return window
|
|
||||||
}
|
|
||||||
|
|
||||||
const createMiniWindow = () => {
|
|
||||||
if (miniWindow || process.platform === 'darwin') {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
let obj: IBrowserWindowOptions = {
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
show: process.platform === 'linux',
|
|
||||||
frame: false,
|
|
||||||
fullscreenable: false,
|
|
||||||
skipTaskbar: true,
|
|
||||||
resizable: false,
|
|
||||||
transparent: process.platform !== 'linux',
|
|
||||||
icon: `${__static}/logo.png`,
|
|
||||||
webPreferences: {
|
|
||||||
backgroundThrottling: false,
|
|
||||||
nodeIntegration: true,
|
|
||||||
nodeIntegrationInWorker: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (db.get('settings.miniWindowOntop')) {
|
|
||||||
obj.alwaysOnTop = true
|
|
||||||
}
|
|
||||||
|
|
||||||
miniWindow = new BrowserWindow(obj)
|
|
||||||
|
|
||||||
miniWindow.loadURL(miniWinURL)
|
|
||||||
|
|
||||||
miniWindow.on('closed', () => {
|
|
||||||
miniWindow = null
|
|
||||||
})
|
|
||||||
return miniWindow
|
|
||||||
}
|
|
||||||
|
|
||||||
const createSettingWindow = () => {
|
|
||||||
const options: IBrowserWindowOptions = {
|
|
||||||
height: 450,
|
|
||||||
width: 800,
|
|
||||||
show: false,
|
|
||||||
frame: true,
|
|
||||||
center: true,
|
|
||||||
fullscreenable: false,
|
|
||||||
resizable: false,
|
|
||||||
title: 'PicGo',
|
|
||||||
vibrancy: 'ultra-dark',
|
|
||||||
transparent: true,
|
|
||||||
titleBarStyle: 'hidden',
|
|
||||||
webPreferences: {
|
|
||||||
backgroundThrottling: false,
|
|
||||||
nodeIntegration: true,
|
|
||||||
nodeIntegrationInWorker: true,
|
|
||||||
webSecurity: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (process.platform !== 'darwin') {
|
|
||||||
options.show = false
|
|
||||||
options.frame = false
|
|
||||||
options.backgroundColor = '#3f3c37'
|
|
||||||
options.transparent = false
|
|
||||||
options.icon = `${__static}/logo.png`
|
|
||||||
}
|
|
||||||
settingWindow = new BrowserWindow(options)
|
|
||||||
|
|
||||||
settingWindow!.loadURL(settingWinURL)
|
|
||||||
|
|
||||||
settingWindow!.on('closed', () => {
|
|
||||||
bus.emit('toggleShortKeyModifiedMode', false)
|
|
||||||
settingWindow = null
|
|
||||||
if (process.platform === 'linux') {
|
|
||||||
process.nextTick(() => {
|
|
||||||
app.quit()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
createMenu()
|
|
||||||
createMiniWindow()
|
|
||||||
return settingWindow
|
|
||||||
}
|
|
||||||
|
|
||||||
const createMenu = () => {
|
|
||||||
if (process.env.NODE_ENV !== 'development') {
|
|
||||||
const template = [{
|
|
||||||
label: 'Edit',
|
|
||||||
submenu: [
|
|
||||||
{ label: 'Undo', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
|
|
||||||
{ label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
|
|
||||||
{ type: 'separator' },
|
|
||||||
{ label: 'Cut', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
|
|
||||||
{ label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
|
|
||||||
{ label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
|
|
||||||
{ label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' },
|
|
||||||
{
|
|
||||||
label: 'Quit',
|
|
||||||
accelerator: 'CmdOrCtrl+Q',
|
|
||||||
click () {
|
|
||||||
app.quit()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
// @ts-ignore
|
|
||||||
menu = Menu.buildFromTemplate(template)
|
|
||||||
Menu.setApplicationMenu(menu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const toggleWindow = (bounds: IBounds) => {
|
|
||||||
if (window!.isVisible()) {
|
|
||||||
window!.hide()
|
|
||||||
} else {
|
|
||||||
showWindow(bounds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const showWindow = (bounds: IBounds) => {
|
|
||||||
window!.setPosition(bounds.x - 98 + 11, bounds.y, false)
|
|
||||||
window!.webContents.send('updateFiles')
|
|
||||||
window!.show()
|
|
||||||
window!.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
const uploadClipboardFiles = async (): Promise<string> => {
|
|
||||||
const win = getAvailableWindow()
|
|
||||||
let img = await uploader.setWebContents(win!.webContents).upload()
|
|
||||||
if (img !== false) {
|
|
||||||
if (img.length > 0) {
|
|
||||||
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
|
||||||
clipboard.writeText(pasteTemplate(pasteStyle, img[0]))
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '上传成功',
|
|
||||||
body: img[0].imgUrl!,
|
|
||||||
icon: img[0].imgUrl
|
|
||||||
})
|
|
||||||
notification.show()
|
|
||||||
db.insert('uploaded', img[0])
|
|
||||||
window!.webContents.send('clipboardFiles', [])
|
|
||||||
window!.webContents.send('uploadFiles', img)
|
|
||||||
if (settingWindow) {
|
|
||||||
settingWindow.webContents.send('updateGallery')
|
|
||||||
}
|
|
||||||
return img[0].imgUrl as string
|
|
||||||
} else {
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '上传不成功',
|
|
||||||
body: '你剪贴板最新的一条记录不是图片哦'
|
|
||||||
})
|
|
||||||
notification.show()
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const uploadChoosedFiles = async (webContents: WebContents, files: IFileWithPath[]): Promise<string[]> => {
|
|
||||||
const input = files.map(item => item.path)
|
|
||||||
const imgs = await uploader.setWebContents(webContents).upload(input)
|
|
||||||
const result = []
|
|
||||||
if (imgs !== false) {
|
|
||||||
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
|
||||||
let pasteText = ''
|
|
||||||
for (let i = 0; i < imgs.length; i++) {
|
|
||||||
pasteText += pasteTemplate(pasteStyle, imgs[i]) + '\r\n'
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '上传成功',
|
|
||||||
body: imgs[i].imgUrl!,
|
|
||||||
icon: files[i].path
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
notification.show()
|
|
||||||
}, i * 100)
|
|
||||||
db.insert('uploaded', imgs[i])
|
|
||||||
result.push(imgs[i].imgUrl!)
|
|
||||||
}
|
|
||||||
clipboard.writeText(pasteText)
|
|
||||||
window!.webContents.send('uploadFiles', imgs)
|
|
||||||
if (settingWindow) {
|
|
||||||
settingWindow.webContents.send('updateGallery')
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
} else {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
picgoCoreIPC()
|
|
||||||
|
|
||||||
// from macOS tray
|
|
||||||
ipcMain.on('uploadClipboardFiles', async () => {
|
|
||||||
const img = await uploader.setWebContents(window!.webContents).upload()
|
|
||||||
if (img !== false) {
|
|
||||||
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
|
||||||
clipboard.writeText(pasteTemplate(pasteStyle, img[0]))
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '上传成功',
|
|
||||||
body: img[0].imgUrl!,
|
|
||||||
// icon: file[0]
|
|
||||||
icon: img[0].imgUrl
|
|
||||||
})
|
|
||||||
notification.show()
|
|
||||||
db.insert('uploaded', img[0])
|
|
||||||
window!.webContents.send('clipboardFiles', [])
|
|
||||||
if (settingWindow) {
|
|
||||||
settingWindow.webContents.send('updateGallery')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window!.webContents.send('uploadFiles')
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('uploadClipboardFilesFromUploadPage', () => {
|
|
||||||
uploadClipboardFiles()
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('uploadChoosedFiles', async (evt: IpcMainEvent, files: IFileWithPath[]) => {
|
|
||||||
return uploadChoosedFiles(evt.sender, files)
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('updateShortKey', (evt: IpcMainEvent, item: IShortKeyConfig, oldKey: string, from: string) => {
|
|
||||||
const result = shortKeyHandler.updateShortKey(item, oldKey, from)
|
|
||||||
evt.sender.send('updateShortKeyResponse', result)
|
|
||||||
if (result) {
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '操作成功',
|
|
||||||
body: '你的快捷键已经修改成功'
|
|
||||||
})
|
|
||||||
notification.show()
|
|
||||||
} else {
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '操作失败',
|
|
||||||
body: '快捷键冲突,请重新设置'
|
|
||||||
})
|
|
||||||
notification.show()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('bindOrUnbindShortKey', (evt: IpcMainEvent, item: IShortKeyConfig, from: string) => {
|
|
||||||
const result = shortKeyHandler.bindOrUnbindShortKey(item, from)
|
|
||||||
if (result) {
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '操作成功',
|
|
||||||
body: '你的快捷键已经修改成功'
|
|
||||||
})
|
|
||||||
notification.show()
|
|
||||||
} else {
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '操作失败',
|
|
||||||
body: '快捷键冲突,请重新设置'
|
|
||||||
})
|
|
||||||
notification.show()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('updateCustomLink', () => {
|
|
||||||
const notification = new Notification({
|
|
||||||
title: '操作成功',
|
|
||||||
body: '你的自定义链接格式已经修改成功'
|
|
||||||
})
|
|
||||||
notification.show()
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('autoStart', (evt: IpcMainEvent, val: boolean) => {
|
|
||||||
app.setLoginItemSettings({
|
|
||||||
openAtLogin: val
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('openSettingWindow', () => {
|
|
||||||
if (!settingWindow) {
|
|
||||||
createSettingWindow()
|
|
||||||
} else {
|
|
||||||
settingWindow.show()
|
|
||||||
}
|
|
||||||
if (miniWindow) {
|
|
||||||
miniWindow.hide()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('openMiniWindow', () => {
|
|
||||||
if (!miniWindow) {
|
|
||||||
createMiniWindow()
|
|
||||||
}
|
|
||||||
miniWindow!.show()
|
|
||||||
miniWindow!.focus()
|
|
||||||
settingWindow!.hide()
|
|
||||||
})
|
|
||||||
|
|
||||||
// from mini window
|
|
||||||
ipcMain.on('syncPicBed', () => {
|
|
||||||
if (settingWindow) {
|
|
||||||
settingWindow.webContents.send('syncPicBed')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('getPicBeds', (evt: IpcMainEvent) => {
|
|
||||||
const picBeds = getPicBeds()
|
|
||||||
evt.sender.send('getPicBeds', picBeds)
|
|
||||||
evt.returnValue = picBeds
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('toggleShortKeyModifiedMode', (evt: IpcMainEvent, val: boolean) => {
|
|
||||||
bus.emit('toggleShortKeyModifiedMode', val)
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('updateServer', () => {
|
|
||||||
server.restart()
|
|
||||||
})
|
|
||||||
|
|
||||||
const gotTheLock = app.requestSingleInstanceLock()
|
const gotTheLock = app.requestSingleInstanceLock()
|
||||||
|
|
||||||
@@ -576,11 +52,12 @@ if (!gotTheLock) {
|
|||||||
if (files === null) {
|
if (files === null) {
|
||||||
uploadClipboardFiles()
|
uploadClipboardFiles()
|
||||||
} else {
|
} else {
|
||||||
const win = getAvailableWindow()
|
const win = windowManager.getAvailableWindow()
|
||||||
uploadChoosedFiles(win.webContents, files)
|
uploadChoosedFiles(win.webContents, files)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (settingWindow) {
|
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||||
|
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||||
if (settingWindow.isMinimized()) {
|
if (settingWindow.isMinimized()) {
|
||||||
settingWindow.restore()
|
settingWindow.restore()
|
||||||
}
|
}
|
||||||
@@ -608,14 +85,13 @@ app.on('ready', async () => {
|
|||||||
console.error('Vue Devtools failed to install:', e.toString())
|
console.error('Vue Devtools failed to install:', e.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createWindow()
|
windowManager.create(IWindowList.TRAY_WINDOW)
|
||||||
createSettingWindow()
|
windowManager.create(IWindowList.SETTING_WINDOW)
|
||||||
if (process.platform === 'darwin' || process.platform === 'win32') {
|
if (process.platform === 'darwin' || process.platform === 'win32') {
|
||||||
createTray()
|
createTray()
|
||||||
}
|
}
|
||||||
db.set('needReload', false)
|
db.set('needReload', false)
|
||||||
updateChecker()
|
updateChecker()
|
||||||
initEventCenter()
|
|
||||||
// 不需要阻塞
|
// 不需要阻塞
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
updateShortKeyFromVersion212(db, db.get('settings.shortKey'))
|
updateShortKeyFromVersion212(db, db.get('settings.shortKey'))
|
||||||
@@ -628,7 +104,7 @@ app.on('ready', async () => {
|
|||||||
if (files === null) {
|
if (files === null) {
|
||||||
uploadClipboardFiles()
|
uploadClipboardFiles()
|
||||||
} else {
|
} else {
|
||||||
const win = getAvailableWindow()
|
const win = windowManager.getAvailableWindow()
|
||||||
uploadChoosedFiles(win.webContents, files)
|
uploadChoosedFiles(win.webContents, files)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -643,11 +119,11 @@ app.on('window-all-closed', () => {
|
|||||||
|
|
||||||
app.on('activate', () => {
|
app.on('activate', () => {
|
||||||
createProtocol('picgo')
|
createProtocol('picgo')
|
||||||
if (window === null) {
|
if (!windowManager.has(IWindowList.TRAY_WINDOW)) {
|
||||||
createWindow()
|
windowManager.create(IWindowList.TRAY_WINDOW)
|
||||||
}
|
}
|
||||||
if (settingWindow === null) {
|
if (!windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||||
createSettingWindow()
|
windowManager.create(IWindowList.SETTING_WINDOW)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -661,50 +137,6 @@ app.setLoginItemSettings({
|
|||||||
openAtLogin: db.get('settings.autoStart') || false
|
openAtLogin: db.get('settings.autoStart') || false
|
||||||
})
|
})
|
||||||
|
|
||||||
function initEventCenter () {
|
|
||||||
const eventList: any = {
|
|
||||||
'picgo:upload': uploadClipboardFiles,
|
|
||||||
[UPLOAD_WITH_CLIPBOARD_FILES]: busCallUploadClipboardFiles,
|
|
||||||
[UPLOAD_WITH_FILES]: busCallUploadFiles,
|
|
||||||
[GET_WINDOW_ID]: busCallGetWindowId,
|
|
||||||
[GET_SETTING_WINDOW_ID]: busCallGetSettingWindowId
|
|
||||||
}
|
|
||||||
for (let i in eventList) {
|
|
||||||
bus.on(i, eventList[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAvailableWindow () {
|
|
||||||
let win
|
|
||||||
if (miniWindow && miniWindow.isVisible()) {
|
|
||||||
win = miniWindow
|
|
||||||
} else {
|
|
||||||
win = settingWindow || window || createSettingWindow()
|
|
||||||
}
|
|
||||||
return win
|
|
||||||
}
|
|
||||||
|
|
||||||
async function busCallUploadClipboardFiles () {
|
|
||||||
const imgUrl = await uploadClipboardFiles()
|
|
||||||
bus.emit(UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE, imgUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function busCallUploadFiles (pathList: IFileWithPath[]) {
|
|
||||||
const win = getAvailableWindow()
|
|
||||||
const urls = await uploadChoosedFiles(win.webContents, pathList)
|
|
||||||
bus.emit(UPLOAD_WITH_FILES_RESPONSE, urls)
|
|
||||||
}
|
|
||||||
|
|
||||||
function busCallGetWindowId () {
|
|
||||||
const win = getAvailableWindow()
|
|
||||||
bus.emit(GET_WINDOW_ID_REPONSE, win.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
function busCallGetSettingWindowId () {
|
|
||||||
if (!settingWindow) createSettingWindow()
|
|
||||||
bus.emit(GET_SETTING_WINDOW_ID_RESPONSE, settingWindow!.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exit cleanly on request from parent process in development mode.
|
// Exit cleanly on request from parent process in development mode.
|
||||||
if (isDevelopment) {
|
if (isDevelopment) {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
|
|||||||
@@ -0,0 +1,206 @@
|
|||||||
|
import {
|
||||||
|
app,
|
||||||
|
Menu,
|
||||||
|
Tray,
|
||||||
|
dialog,
|
||||||
|
clipboard,
|
||||||
|
systemPreferences,
|
||||||
|
Notification
|
||||||
|
} from 'electron'
|
||||||
|
import uploader from '~/main/apis/uploader'
|
||||||
|
import getPicBeds from '~/main/utils/getPicBeds'
|
||||||
|
import db from '#/datastore'
|
||||||
|
import windowManager from '~/main/apis/window/windowManager'
|
||||||
|
import { IWindowList } from '~/main/apis/window/constants'
|
||||||
|
import picgo from '~/main/apis/picgo'
|
||||||
|
import pasteTemplate from '#/utils/pasteTemplate'
|
||||||
|
import pkg from 'root/package.json'
|
||||||
|
let contextMenu: Menu | null
|
||||||
|
let menu: Menu | null
|
||||||
|
let tray: Tray | null
|
||||||
|
export function createContextMenu () {
|
||||||
|
const picBeds = getPicBeds()
|
||||||
|
const submenu = picBeds.filter(item => item.visible).map(item => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
type: 'radio',
|
||||||
|
checked: db.get('picBed.current') === item.type,
|
||||||
|
click () {
|
||||||
|
picgo.saveConfig({
|
||||||
|
'picBed.current': item.type
|
||||||
|
})
|
||||||
|
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
contextMenu = Menu.buildFromTemplate([
|
||||||
|
{
|
||||||
|
label: '关于',
|
||||||
|
click () {
|
||||||
|
dialog.showMessageBox({
|
||||||
|
title: 'PicGo',
|
||||||
|
message: 'PicGo',
|
||||||
|
detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '打开详细窗口',
|
||||||
|
click () {
|
||||||
|
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
|
||||||
|
settingWindow!.show()
|
||||||
|
settingWindow!.focus()
|
||||||
|
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '选择默认图床',
|
||||||
|
type: 'submenu',
|
||||||
|
// @ts-ignore
|
||||||
|
submenu
|
||||||
|
},
|
||||||
|
// @ts-ignore
|
||||||
|
{
|
||||||
|
label: '打开更新助手',
|
||||||
|
type: 'checkbox',
|
||||||
|
checked: db.get('settings.showUpdateTip'),
|
||||||
|
click () {
|
||||||
|
const value = db.get('settings.showUpdateTip')
|
||||||
|
db.set('settings.showUpdateTip', !value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '重启应用',
|
||||||
|
click () {
|
||||||
|
app.relaunch()
|
||||||
|
app.exit(0)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// @ts-ignore
|
||||||
|
{
|
||||||
|
role: 'quit',
|
||||||
|
label: '退出'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createTray () {
|
||||||
|
const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png`
|
||||||
|
tray = new Tray(menubarPic)
|
||||||
|
tray.on('right-click', () => {
|
||||||
|
if (windowManager.has(IWindowList.TRAY_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
|
||||||
|
}
|
||||||
|
createContextMenu()
|
||||||
|
tray!.popUpContextMenu(contextMenu!)
|
||||||
|
})
|
||||||
|
tray.on('click', (event, bounds) => {
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
toggleWindow(bounds)
|
||||||
|
setTimeout(() => {
|
||||||
|
let img = clipboard.readImage()
|
||||||
|
let obj: ImgInfo[] = []
|
||||||
|
if (!img.isEmpty()) {
|
||||||
|
// 从剪贴板来的图片默认转为png
|
||||||
|
// @ts-ignore
|
||||||
|
const imgUrl = 'data:image/png;base64,' + Buffer.from(img.toPNG(), 'binary').toString('base64')
|
||||||
|
obj.push({
|
||||||
|
width: img.getSize().width,
|
||||||
|
height: img.getSize().height,
|
||||||
|
imgUrl
|
||||||
|
})
|
||||||
|
}
|
||||||
|
windowManager.get(IWindowList.TRAY_WINDOW)!.webContents.send('clipboardFiles', obj)
|
||||||
|
}, 0)
|
||||||
|
} else {
|
||||||
|
if (windowManager.has(IWindowList.TRAY_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
|
||||||
|
}
|
||||||
|
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
|
||||||
|
settingWindow!.show()
|
||||||
|
settingWindow!.focus()
|
||||||
|
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
tray.on('drag-enter', () => {
|
||||||
|
if (systemPreferences.isDarkMode()) {
|
||||||
|
tray!.setImage(`${__static}/upload-dark.png`)
|
||||||
|
} else {
|
||||||
|
tray!.setImage(`${__static}/upload.png`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
tray.on('drag-end', () => {
|
||||||
|
tray!.setImage(`${__static}/menubar.png`)
|
||||||
|
})
|
||||||
|
|
||||||
|
tray.on('drop-files', async (event: Event, files: string[]) => {
|
||||||
|
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
||||||
|
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
|
||||||
|
const imgs = await uploader
|
||||||
|
.setWebContents(trayWindow.webContents)
|
||||||
|
.upload(files)
|
||||||
|
if (imgs !== false) {
|
||||||
|
for (let i = 0; i < imgs.length; i++) {
|
||||||
|
clipboard.writeText(pasteTemplate(pasteStyle, imgs[i]))
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '上传成功',
|
||||||
|
body: imgs[i].imgUrl!,
|
||||||
|
icon: files[i]
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.show()
|
||||||
|
}, i * 100)
|
||||||
|
db.insert('uploaded', imgs[i])
|
||||||
|
}
|
||||||
|
trayWindow.webContents.send('dragFiles', imgs)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// toggleWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createMenu () {
|
||||||
|
if (process.env.NODE_ENV !== 'development') {
|
||||||
|
const template = [{
|
||||||
|
label: 'Edit',
|
||||||
|
submenu: [
|
||||||
|
{ label: 'Undo', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
|
||||||
|
{ label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
|
||||||
|
{ type: 'separator' },
|
||||||
|
{ label: 'Cut', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
|
||||||
|
{ label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
|
||||||
|
{ label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
|
||||||
|
{ label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' },
|
||||||
|
{
|
||||||
|
label: 'Quit',
|
||||||
|
accelerator: 'CmdOrCtrl+Q',
|
||||||
|
click () {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
// @ts-ignore
|
||||||
|
menu = Menu.buildFromTemplate(template)
|
||||||
|
Menu.setApplicationMenu(menu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleWindow = (bounds: IBounds) => {
|
||||||
|
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
|
||||||
|
if (trayWindow.isVisible()) {
|
||||||
|
trayWindow.hide()
|
||||||
|
} else {
|
||||||
|
trayWindow.setPosition(bounds.x - 98 + 11, bounds.y, false)
|
||||||
|
trayWindow.webContents.send('updateFiles')
|
||||||
|
trayWindow.show()
|
||||||
|
trayWindow.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,3 +6,4 @@ export const UPLOAD_WITH_FILES = 'UPLOAD_WITH_FILES'
|
|||||||
export const UPLOAD_WITH_FILES_RESPONSE = 'UPLOAD_WITH_FILES_RESPONSE'
|
export const UPLOAD_WITH_FILES_RESPONSE = 'UPLOAD_WITH_FILES_RESPONSE'
|
||||||
export const UPLOAD_WITH_CLIPBOARD_FILES = 'UPLOAD_WITH_CLIPBOARD_FILES'
|
export const UPLOAD_WITH_CLIPBOARD_FILES = 'UPLOAD_WITH_CLIPBOARD_FILES'
|
||||||
export const UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE = 'UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE'
|
export const UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE = 'UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE'
|
||||||
|
export const CREATE_APP_MENU = 'CREATE_APP_MENU'
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import bus from '../eventBus'
|
import bus from '../../utils/eventBus'
|
||||||
import {
|
import {
|
||||||
UPLOAD_WITH_FILES,
|
UPLOAD_WITH_FILES,
|
||||||
UPLOAD_WITH_FILES_RESPONSE,
|
UPLOAD_WITH_FILES_RESPONSE,
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import bus from '~/main/utils/eventBus'
|
||||||
|
import {
|
||||||
|
uploadClipboardFiles,
|
||||||
|
uploadChoosedFiles
|
||||||
|
} from '~/main/apis/uploader/api'
|
||||||
|
import {
|
||||||
|
createMenu
|
||||||
|
} from '~/main/apis/app'
|
||||||
|
import { IWindowList } from '~/main/apis/window/constants'
|
||||||
|
import windowManager from '~/main/apis/window/windowManager'
|
||||||
|
import {
|
||||||
|
UPLOAD_WITH_FILES,
|
||||||
|
UPLOAD_WITH_FILES_RESPONSE,
|
||||||
|
UPLOAD_WITH_CLIPBOARD_FILES,
|
||||||
|
UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE,
|
||||||
|
GET_WINDOW_ID,
|
||||||
|
GET_WINDOW_ID_REPONSE,
|
||||||
|
GET_SETTING_WINDOW_ID,
|
||||||
|
GET_SETTING_WINDOW_ID_RESPONSE,
|
||||||
|
CREATE_APP_MENU
|
||||||
|
} from '~/main/apis/bus/constants'
|
||||||
|
function initEventCenter () {
|
||||||
|
const eventList: any = {
|
||||||
|
'picgo:upload': uploadClipboardFiles,
|
||||||
|
[UPLOAD_WITH_CLIPBOARD_FILES]: busCallUploadClipboardFiles,
|
||||||
|
[UPLOAD_WITH_FILES]: busCallUploadFiles,
|
||||||
|
[GET_WINDOW_ID]: busCallGetWindowId,
|
||||||
|
[GET_SETTING_WINDOW_ID]: busCallGetSettingWindowId,
|
||||||
|
[CREATE_APP_MENU]: createMenu
|
||||||
|
}
|
||||||
|
for (let i in eventList) {
|
||||||
|
bus.on(i, eventList[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function busCallUploadClipboardFiles () {
|
||||||
|
const imgUrl = await uploadClipboardFiles()
|
||||||
|
bus.emit(UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE, imgUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function busCallUploadFiles (pathList: IFileWithPath[]) {
|
||||||
|
const win = windowManager.getAvailableWindow()
|
||||||
|
const urls = await uploadChoosedFiles(win.webContents, pathList)
|
||||||
|
bus.emit(UPLOAD_WITH_FILES_RESPONSE, urls)
|
||||||
|
}
|
||||||
|
|
||||||
|
function busCallGetWindowId () {
|
||||||
|
const win = windowManager.getAvailableWindow()
|
||||||
|
bus.emit(GET_WINDOW_ID_REPONSE, win.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
function busCallGetSettingWindowId () {
|
||||||
|
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||||
|
bus.emit(GET_SETTING_WINDOW_ID_RESPONSE, settingWindow.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
listen () {
|
||||||
|
initEventCenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
import {
|
||||||
|
app,
|
||||||
|
ipcMain,
|
||||||
|
clipboard,
|
||||||
|
Notification,
|
||||||
|
IpcMainEvent
|
||||||
|
} from 'electron'
|
||||||
|
import windowManager from '~/main/apis/window/windowManager'
|
||||||
|
import { IWindowList } from '~/main/apis/window/constants'
|
||||||
|
import uploader from '~/main/apis/uploader'
|
||||||
|
import pasteTemplate from '#/utils/pasteTemplate'
|
||||||
|
import db from '#/datastore'
|
||||||
|
import server from '~/main/server'
|
||||||
|
import getPicBeds from '~/main/utils/getPicBeds'
|
||||||
|
import shortKeyHandler from '~/main/apis/shortKey/shortKeyHandler'
|
||||||
|
import bus from '~/main/utils/eventBus'
|
||||||
|
import {
|
||||||
|
uploadClipboardFiles,
|
||||||
|
uploadChoosedFiles
|
||||||
|
} from '~/main/apis/uploader/api'
|
||||||
|
import picgoCoreIPC from './picgoCoreIPC'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
listen () {
|
||||||
|
picgoCoreIPC.listen()
|
||||||
|
// from macOS tray
|
||||||
|
ipcMain.on('uploadClipboardFiles', async () => {
|
||||||
|
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
|
||||||
|
const img = await uploader.setWebContents(trayWindow.webContents).upload()
|
||||||
|
if (img !== false) {
|
||||||
|
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
||||||
|
clipboard.writeText(pasteTemplate(pasteStyle, img[0]))
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '上传成功',
|
||||||
|
body: img[0].imgUrl!,
|
||||||
|
// icon: file[0]
|
||||||
|
icon: img[0].imgUrl
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
db.insert('uploaded', img[0])
|
||||||
|
trayWindow.webContents.send('clipboardFiles', [])
|
||||||
|
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trayWindow.webContents.send('uploadFiles')
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('uploadClipboardFilesFromUploadPage', () => {
|
||||||
|
uploadClipboardFiles()
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('uploadChoosedFiles', async (evt: IpcMainEvent, files: IFileWithPath[]) => {
|
||||||
|
return uploadChoosedFiles(evt.sender, files)
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('updateShortKey', (evt: IpcMainEvent, item: IShortKeyConfig, oldKey: string, from: string) => {
|
||||||
|
const result = shortKeyHandler.updateShortKey(item, oldKey, from)
|
||||||
|
evt.sender.send('updateShortKeyResponse', result)
|
||||||
|
if (result) {
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '操作成功',
|
||||||
|
body: '你的快捷键已经修改成功'
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
} else {
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '操作失败',
|
||||||
|
body: '快捷键冲突,请重新设置'
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('bindOrUnbindShortKey', (evt: IpcMainEvent, item: IShortKeyConfig, from: string) => {
|
||||||
|
const result = shortKeyHandler.bindOrUnbindShortKey(item, from)
|
||||||
|
if (result) {
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '操作成功',
|
||||||
|
body: '你的快捷键已经修改成功'
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
} else {
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '操作失败',
|
||||||
|
body: '快捷键冲突,请重新设置'
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('updateCustomLink', () => {
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '操作成功',
|
||||||
|
body: '你的自定义链接格式已经修改成功'
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('autoStart', (evt: IpcMainEvent, val: boolean) => {
|
||||||
|
app.setLoginItemSettings({
|
||||||
|
openAtLogin: val
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('openSettingWindow', () => {
|
||||||
|
windowManager.get(IWindowList.SETTING_WINDOW)!.show()
|
||||||
|
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('openMiniWindow', () => {
|
||||||
|
const miniWindow = windowManager.get(IWindowList.MINI_WINDOW)!
|
||||||
|
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||||
|
miniWindow.show()
|
||||||
|
miniWindow.focus()
|
||||||
|
settingWindow.hide()
|
||||||
|
})
|
||||||
|
|
||||||
|
// from mini window
|
||||||
|
ipcMain.on('syncPicBed', () => {
|
||||||
|
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('getPicBeds', (evt: IpcMainEvent) => {
|
||||||
|
const picBeds = getPicBeds()
|
||||||
|
evt.sender.send('getPicBeds', picBeds)
|
||||||
|
evt.returnValue = picBeds
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('toggleShortKeyModifiedMode', (evt: IpcMainEvent, val: boolean) => {
|
||||||
|
bus.emit('toggleShortKeyModifiedMode', val)
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('updateServer', () => {
|
||||||
|
server.restart()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
dispose () {}
|
||||||
|
}
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import GuiApi from './guiApi'
|
import GuiApi from '../gui'
|
||||||
import {
|
import {
|
||||||
dialog,
|
dialog,
|
||||||
shell,
|
shell,
|
||||||
IpcMain,
|
|
||||||
IpcMainEvent,
|
IpcMainEvent,
|
||||||
App,
|
|
||||||
ipcMain,
|
ipcMain,
|
||||||
app
|
app
|
||||||
} from 'electron'
|
} from 'electron'
|
||||||
import PicGoCore from '~/universal/types/picgo'
|
import PicGoCore from '~/universal/types/picgo'
|
||||||
import { IPicGoHelperType } from '#/types/enum'
|
import { IPicGoHelperType } from '#/types/enum'
|
||||||
import shortKeyHandler from './shortKeyHandler'
|
import shortKeyHandler from '../shortKey/shortKeyHandler'
|
||||||
import picgo from '~/main/utils/picgo'
|
import picgo from '~/main/apis/picgo'
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
|
const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
|
||||||
@@ -213,13 +211,15 @@ const handlePicGoSaveData = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => {
|
export default {
|
||||||
handleGetPluginList()
|
listen () {
|
||||||
handlePluginInstall()
|
handleGetPluginList()
|
||||||
handlePluginUninstall()
|
handlePluginInstall()
|
||||||
handlePluginUpdate()
|
handlePluginUninstall()
|
||||||
handleGetPicBedConfig()
|
handlePluginUpdate()
|
||||||
handlePluginActions()
|
handleGetPicBedConfig()
|
||||||
handleRemoveFiles()
|
handlePluginActions()
|
||||||
handlePicGoSaveData()
|
handleRemoveFiles()
|
||||||
|
handlePicGoSaveData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,17 +3,15 @@ import {
|
|||||||
BrowserWindow,
|
BrowserWindow,
|
||||||
clipboard,
|
clipboard,
|
||||||
Notification,
|
Notification,
|
||||||
WebContents,
|
ipcMain
|
||||||
ipcMain,
|
|
||||||
webContents
|
|
||||||
} from 'electron'
|
} from 'electron'
|
||||||
import db from '#/datastore'
|
import db from '#/datastore'
|
||||||
import uploader from './uploader'
|
import uploader from '../uploader'
|
||||||
import pasteTemplate from '#/utils/pasteTemplate'
|
import pasteTemplate from '#/utils/pasteTemplate'
|
||||||
import {
|
import {
|
||||||
getWindowId,
|
getWindowId,
|
||||||
getSettingWindowId
|
getSettingWindowId
|
||||||
} from '~/main/utils/busApi'
|
} from '~/main/apis/bus'
|
||||||
|
|
||||||
class GuiApi implements IGuiApi {
|
class GuiApi implements IGuiApi {
|
||||||
private windowId: number = -1
|
private windowId: number = -1
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import bus from './eventBus'
|
import bus from '../../utils/eventBus'
|
||||||
import PicGoCore from '~/universal/types/picgo'
|
import PicGoCore from '~/universal/types/picgo'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import {
|
import {
|
||||||
@@ -6,11 +6,11 @@ import {
|
|||||||
globalShortcut,
|
globalShortcut,
|
||||||
BrowserWindow
|
BrowserWindow
|
||||||
} from 'electron'
|
} from 'electron'
|
||||||
import logger from './logger'
|
import logger from '../../utils/logger'
|
||||||
import GuiApi from './guiApi'
|
import GuiApi from '../gui'
|
||||||
import db from '#/datastore'
|
import db from '#/datastore'
|
||||||
import shortKeyService from './shortkeyService'
|
import shortKeyService from './shortKeyService'
|
||||||
import picgo from './picgo'
|
import picgo from '../picgo'
|
||||||
|
|
||||||
class ShortKeyHandler {
|
class ShortKeyHandler {
|
||||||
private isInModifiedMode: boolean = false
|
private isInModifiedMode: boolean = false
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import logger from './logger'
|
import logger from '../../utils/logger'
|
||||||
class ShortKeyService {
|
class ShortKeyService {
|
||||||
private commandList: Map<string, IShortKeyHandler> = new Map()
|
private commandList: Map<string, IShortKeyHandler> = new Map()
|
||||||
registerCommand (command: string, handler: IShortKeyHandler) {
|
registerCommand (command: string, handler: IShortKeyHandler) {
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import {
|
||||||
|
clipboard,
|
||||||
|
Notification,
|
||||||
|
WebContents
|
||||||
|
} from 'electron'
|
||||||
|
import windowManager from '~/main/apis/window/windowManager'
|
||||||
|
import { IWindowList } from '~/main/apis/window/constants'
|
||||||
|
import uploader from './'
|
||||||
|
import pasteTemplate from '#/utils/pasteTemplate'
|
||||||
|
import db from '#/datastore'
|
||||||
|
export const uploadClipboardFiles = async (): Promise<string> => {
|
||||||
|
const win = windowManager.getAvailableWindow()
|
||||||
|
let img = await uploader.setWebContents(win!.webContents).upload()
|
||||||
|
if (img !== false) {
|
||||||
|
if (img.length > 0) {
|
||||||
|
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
|
||||||
|
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
||||||
|
clipboard.writeText(pasteTemplate(pasteStyle, img[0]))
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '上传成功',
|
||||||
|
body: img[0].imgUrl!,
|
||||||
|
icon: img[0].imgUrl
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
db.insert('uploaded', img[0])
|
||||||
|
trayWindow.webContents.send('clipboardFiles', [])
|
||||||
|
trayWindow.webContents.send('uploadFiles', img)
|
||||||
|
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery')
|
||||||
|
}
|
||||||
|
return img[0].imgUrl as string
|
||||||
|
} else {
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '上传不成功',
|
||||||
|
body: '你剪贴板最新的一条记录不是图片哦'
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const uploadChoosedFiles = async (webContents: WebContents, files: IFileWithPath[]): Promise<string[]> => {
|
||||||
|
const input = files.map(item => item.path)
|
||||||
|
const imgs = await uploader.setWebContents(webContents).upload(input)
|
||||||
|
const result = []
|
||||||
|
if (imgs !== false) {
|
||||||
|
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
||||||
|
let pasteText = ''
|
||||||
|
for (let i = 0; i < imgs.length; i++) {
|
||||||
|
pasteText += pasteTemplate(pasteStyle, imgs[i]) + '\r\n'
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '上传成功',
|
||||||
|
body: imgs[i].imgUrl!,
|
||||||
|
icon: files[i].path
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.show()
|
||||||
|
}, i * 100)
|
||||||
|
db.insert('uploaded', imgs[i])
|
||||||
|
result.push(imgs[i].imgUrl!)
|
||||||
|
}
|
||||||
|
clipboard.writeText(pasteText)
|
||||||
|
windowManager.get(IWindowList.TRAY_WINDOW)!.webContents.send('uploadFiles', imgs)
|
||||||
|
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery')
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,53 +6,10 @@ import {
|
|||||||
WebContents
|
WebContents
|
||||||
} from 'electron'
|
} from 'electron'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import picgo from '~/main/utils/picgo'
|
import picgo from '~/main/apis/picgo'
|
||||||
import db from '#/datastore'
|
import db from '#/datastore'
|
||||||
|
import windowManager from '~/main/apis/window/windowManager'
|
||||||
const renameURL = process.env.NODE_ENV === 'development'
|
import { IWindowList } from '~/main/apis/window/constants'
|
||||||
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#rename-page`
|
|
||||||
: `picgo://./index.html#rename-page`
|
|
||||||
|
|
||||||
const createRenameWindow = (currentWindow: BrowserWindow) => {
|
|
||||||
let options: IBrowserWindowOptions = {
|
|
||||||
height: 175,
|
|
||||||
width: 300,
|
|
||||||
show: true,
|
|
||||||
fullscreenable: false,
|
|
||||||
resizable: false,
|
|
||||||
vibrancy: 'ultra-dark',
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: true,
|
|
||||||
nodeIntegrationInWorker: true,
|
|
||||||
backgroundThrottling: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.platform !== 'darwin') {
|
|
||||||
options.show = true
|
|
||||||
options.backgroundColor = '#3f3c37'
|
|
||||||
options.autoHideMenuBar = true
|
|
||||||
options.transparent = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const window = new BrowserWindow(options)
|
|
||||||
window.loadURL(renameURL)
|
|
||||||
// check if this window is visible
|
|
||||||
if (currentWindow && currentWindow.isVisible()) {
|
|
||||||
// bounds: { x: 821, y: 75, width: 800, height: 450 }
|
|
||||||
const bounds = currentWindow.getBounds()
|
|
||||||
const positionX = bounds.x + bounds.width / 2 - 150
|
|
||||||
let positionY
|
|
||||||
// if is the settingWindow
|
|
||||||
if (bounds.height > 400) {
|
|
||||||
positionY = bounds.y + bounds.height / 2 - 88
|
|
||||||
} else { // if is the miniWindow
|
|
||||||
positionY = bounds.y + bounds.height / 2
|
|
||||||
}
|
|
||||||
window.setPosition(positionX, positionY, false)
|
|
||||||
}
|
|
||||||
return window
|
|
||||||
}
|
|
||||||
|
|
||||||
const waitForShow = (webcontent: WebContents) => {
|
const waitForShow = (webcontent: WebContents) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -64,6 +21,7 @@ const waitForShow = (webcontent: WebContents) => {
|
|||||||
|
|
||||||
const waitForRename = (window: BrowserWindow, id: number): Promise<string|null> => {
|
const waitForRename = (window: BrowserWindow, id: number): Promise<string|null> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
const windowId = window.id
|
||||||
ipcMain.once(`rename${id}`, (evt: Event, newName: string) => {
|
ipcMain.once(`rename${id}`, (evt: Event, newName: string) => {
|
||||||
resolve(newName)
|
resolve(newName)
|
||||||
window.close()
|
window.close()
|
||||||
@@ -71,13 +29,13 @@ const waitForRename = (window: BrowserWindow, id: number): Promise<string|null>
|
|||||||
window.on('close', () => {
|
window.on('close', () => {
|
||||||
resolve(null)
|
resolve(null)
|
||||||
ipcMain.removeAllListeners(`rename${id}`)
|
ipcMain.removeAllListeners(`rename${id}`)
|
||||||
|
windowManager.deleteById(windowId)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
class Uploader {
|
class Uploader {
|
||||||
private webContents: WebContents | null = null
|
private webContents: WebContents | null = null
|
||||||
private currentWindow: BrowserWindow | null = null
|
|
||||||
constructor () {
|
constructor () {
|
||||||
this.init()
|
this.init()
|
||||||
}
|
}
|
||||||
@@ -89,7 +47,7 @@ class Uploader {
|
|||||||
})
|
})
|
||||||
|
|
||||||
picgo.on('uploadProgress', progress => {
|
picgo.on('uploadProgress', progress => {
|
||||||
this.webContents!.send('uploadProgress', progress)
|
this.webContents?.send('uploadProgress', progress)
|
||||||
})
|
})
|
||||||
picgo.on('beforeTransform', ctx => {
|
picgo.on('beforeTransform', ctx => {
|
||||||
if (db.get('settings.uploadNotification')) {
|
if (db.get('settings.uploadNotification')) {
|
||||||
@@ -113,7 +71,7 @@ class Uploader {
|
|||||||
fileName = item.fileName
|
fileName = item.fileName
|
||||||
}
|
}
|
||||||
if (rename) {
|
if (rename) {
|
||||||
const window = createRenameWindow(this.currentWindow!)
|
const window = windowManager.create(IWindowList.RENAME_WINDOW)!
|
||||||
await waitForShow(window.webContents)
|
await waitForShow(window.webContents)
|
||||||
window.webContents.send('rename', fileName, window.webContents.id)
|
window.webContents.send('rename', fileName, window.webContents.id)
|
||||||
name = await waitForRename(window, window.webContents.id)
|
name = await waitForRename(window, window.webContents.id)
|
||||||
@@ -130,8 +88,6 @@ class Uploader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
upload (img?: IUploadOption): Promise<ImgInfo[]|false> {
|
upload (img?: IUploadOption): Promise<ImgInfo[]|false> {
|
||||||
this.currentWindow = BrowserWindow.fromWebContents(this.webContents!)
|
|
||||||
|
|
||||||
picgo.upload(img)
|
picgo.upload(img)
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
export enum IWindowList {
|
||||||
|
SETTING_WINDOW = 'SETTING_WINDOW',
|
||||||
|
TRAY_WINDOW = 'TRAY_WINDOW',
|
||||||
|
MINI_WINDOW = 'MINI_WINDOW',
|
||||||
|
RENAME_WINDOW = 'RENAME_WINDOW'
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDevelopment = process.env.NODE_ENV !== 'production'
|
||||||
|
|
||||||
|
export const TRAY_WINDOW_URL = isDevelopment
|
||||||
|
? (process.env.WEBPACK_DEV_SERVER_URL as string)
|
||||||
|
: `picgo://./index.html`
|
||||||
|
|
||||||
|
export const SETTING_WINDOW_URL = isDevelopment
|
||||||
|
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#setting/upload`
|
||||||
|
: `picgo://./index.html#setting/upload`
|
||||||
|
|
||||||
|
export const MINI_WINDOW_URL = isDevelopment
|
||||||
|
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#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`
|
||||||
|
|
||||||
|
export const DELETE_WINDOW_EVENT = 'DELETE_WINDOW_EVENT'
|
||||||
|
export const CREATE_WINDOW_EVENT = 'CREATE_WINDOW_EVENT'
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
import {
|
||||||
|
IWindowList,
|
||||||
|
DELETE_WINDOW_EVENT,
|
||||||
|
CREATE_WINDOW_EVENT,
|
||||||
|
SETTING_WINDOW_URL,
|
||||||
|
TRAY_WINDOW_URL,
|
||||||
|
MINI_WINDOW_URL,
|
||||||
|
RENAME_WINDOW_URL
|
||||||
|
} from './constants'
|
||||||
|
import { IWindowListItem } from '#/types/electron'
|
||||||
|
import bus from '~/main/utils/eventBus'
|
||||||
|
import db from '#/datastore'
|
||||||
|
import { getWindowId } from '~/main/apis/bus'
|
||||||
|
import { BrowserWindow, app } from 'electron'
|
||||||
|
import { CREATE_APP_MENU } from '~/main/apis/bus/constants'
|
||||||
|
|
||||||
|
const windowList = new Map<IWindowList, IWindowListItem>()
|
||||||
|
|
||||||
|
windowList.set(IWindowList.TRAY_WINDOW, {
|
||||||
|
isValid: process.platform !== 'linux',
|
||||||
|
multiple: false,
|
||||||
|
options () {
|
||||||
|
return {
|
||||||
|
height: 350,
|
||||||
|
width: 196, // 196
|
||||||
|
show: false,
|
||||||
|
frame: false,
|
||||||
|
fullscreenable: false,
|
||||||
|
resizable: false,
|
||||||
|
transparent: true,
|
||||||
|
vibrancy: 'ultra-dark',
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
nodeIntegrationInWorker: true,
|
||||||
|
backgroundThrottling: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
callback (window) {
|
||||||
|
const id = window!.id
|
||||||
|
window!.loadURL(TRAY_WINDOW_URL)
|
||||||
|
window!.on('closed', () => {
|
||||||
|
bus.emit(DELETE_WINDOW_EVENT, id)
|
||||||
|
})
|
||||||
|
|
||||||
|
window!.on('blur', () => {
|
||||||
|
window!.hide()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
windowList.set(IWindowList.SETTING_WINDOW, {
|
||||||
|
isValid: true,
|
||||||
|
multiple: false,
|
||||||
|
options () {
|
||||||
|
const options: IBrowserWindowOptions = {
|
||||||
|
height: 450,
|
||||||
|
width: 800,
|
||||||
|
show: false,
|
||||||
|
frame: true,
|
||||||
|
center: true,
|
||||||
|
fullscreenable: false,
|
||||||
|
resizable: false,
|
||||||
|
title: 'PicGo',
|
||||||
|
vibrancy: 'ultra-dark',
|
||||||
|
transparent: true,
|
||||||
|
titleBarStyle: 'hidden',
|
||||||
|
webPreferences: {
|
||||||
|
backgroundThrottling: false,
|
||||||
|
nodeIntegration: true,
|
||||||
|
nodeIntegrationInWorker: true,
|
||||||
|
webSecurity: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
options.show = false
|
||||||
|
options.frame = false
|
||||||
|
options.backgroundColor = '#3f3c37'
|
||||||
|
options.transparent = false
|
||||||
|
options.icon = `${__static}/logo.png`
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
},
|
||||||
|
callback (window) {
|
||||||
|
const id = window!.id
|
||||||
|
window!.loadURL(SETTING_WINDOW_URL)
|
||||||
|
window!.on('closed', () => {
|
||||||
|
bus.emit('toggleShortKeyModifiedMode', false)
|
||||||
|
bus.emit(DELETE_WINDOW_EVENT, id)
|
||||||
|
if (process.platform === 'linux') {
|
||||||
|
process.nextTick(() => {
|
||||||
|
app.quit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
bus.emit(CREATE_APP_MENU)
|
||||||
|
bus.emit(CREATE_WINDOW_EVENT, IWindowList.MINI_WINDOW)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
windowList.set(IWindowList.MINI_WINDOW, {
|
||||||
|
isValid: process.platform !== 'darwin',
|
||||||
|
multiple: false,
|
||||||
|
options () {
|
||||||
|
let obj: IBrowserWindowOptions = {
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
show: process.platform === 'linux',
|
||||||
|
frame: false,
|
||||||
|
fullscreenable: false,
|
||||||
|
skipTaskbar: true,
|
||||||
|
resizable: false,
|
||||||
|
transparent: process.platform !== 'linux',
|
||||||
|
icon: `${__static}/logo.png`,
|
||||||
|
webPreferences: {
|
||||||
|
backgroundThrottling: false,
|
||||||
|
nodeIntegration: true,
|
||||||
|
nodeIntegrationInWorker: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db.get('settings.miniWindowOntop')) {
|
||||||
|
obj.alwaysOnTop = true
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
},
|
||||||
|
callback (window) {
|
||||||
|
const id = window!.id
|
||||||
|
window!.loadURL(MINI_WINDOW_URL)
|
||||||
|
window!.on('closed', () => {
|
||||||
|
bus.emit(DELETE_WINDOW_EVENT, id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
windowList.set(IWindowList.RENAME_WINDOW, {
|
||||||
|
isValid: true,
|
||||||
|
multiple: true,
|
||||||
|
options () {
|
||||||
|
let options: IBrowserWindowOptions = {
|
||||||
|
height: 175,
|
||||||
|
width: 300,
|
||||||
|
show: true,
|
||||||
|
fullscreenable: false,
|
||||||
|
resizable: false,
|
||||||
|
vibrancy: 'ultra-dark',
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
nodeIntegrationInWorker: true,
|
||||||
|
backgroundThrottling: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
options.show = true
|
||||||
|
options.backgroundColor = '#3f3c37'
|
||||||
|
options.autoHideMenuBar = true
|
||||||
|
options.transparent = false
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
},
|
||||||
|
async callback (window) {
|
||||||
|
window!.loadURL(RENAME_WINDOW_URL)
|
||||||
|
const currentWindowId = await getWindowId()
|
||||||
|
const currentWindow = BrowserWindow.fromId(currentWindowId)
|
||||||
|
if (currentWindow && currentWindow.isVisible()) {
|
||||||
|
// bounds: { x: 821, y: 75, width: 800, height: 450 }
|
||||||
|
const bounds = currentWindow.getBounds()
|
||||||
|
const positionX = bounds.x + bounds.width / 2 - 150
|
||||||
|
let positionY
|
||||||
|
// if is the settingWindow
|
||||||
|
if (bounds.height > 400) {
|
||||||
|
positionY = bounds.y + bounds.height / 2 - 88
|
||||||
|
} else { // if is the miniWindow
|
||||||
|
positionY = bounds.y + bounds.height / 2
|
||||||
|
}
|
||||||
|
window!.setPosition(positionX, positionY, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default windowList
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import {
|
||||||
|
BrowserWindow
|
||||||
|
} from 'electron'
|
||||||
|
import { IWindowManager, IWindowListItem } from '#/types/electron'
|
||||||
|
import windowList from './windowList'
|
||||||
|
import {
|
||||||
|
IWindowList,
|
||||||
|
DELETE_WINDOW_EVENT,
|
||||||
|
CREATE_WINDOW_EVENT
|
||||||
|
} from './constants'
|
||||||
|
import bus from '~/main/utils/eventBus'
|
||||||
|
|
||||||
|
class WindowManager implements IWindowManager {
|
||||||
|
private windowMap: Map<IWindowList | string, BrowserWindow> = new Map()
|
||||||
|
private windowIdMap: Map<number, IWindowList | string> = new Map()
|
||||||
|
constructor () {
|
||||||
|
bus.on(DELETE_WINDOW_EVENT, this.deleteById)
|
||||||
|
bus.on(CREATE_WINDOW_EVENT, this.create)
|
||||||
|
}
|
||||||
|
create = (name: IWindowList) => {
|
||||||
|
const windowConfig: IWindowListItem = windowList.get(name)!
|
||||||
|
if (windowConfig.isValid) {
|
||||||
|
if (!windowConfig.multiple) {
|
||||||
|
if (this.windowMap.has(name)) return this.windowMap.get(name)!
|
||||||
|
}
|
||||||
|
const window = new BrowserWindow(windowConfig.options())
|
||||||
|
if (windowConfig.multiple) {
|
||||||
|
this.windowMap.set(`${name}_${window.id}`, window)
|
||||||
|
this.windowIdMap.set(window.id, `${name}_${window.id}`)
|
||||||
|
} else {
|
||||||
|
this.windowMap.set(name, window)
|
||||||
|
this.windowIdMap.set(window.id, name)
|
||||||
|
}
|
||||||
|
windowConfig.callback(window)
|
||||||
|
return window
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get (name: IWindowList) {
|
||||||
|
if (this.windowMap.has(name)) {
|
||||||
|
return this.windowMap.get(name)!
|
||||||
|
} else {
|
||||||
|
const window = this.create(name)
|
||||||
|
return window
|
||||||
|
}
|
||||||
|
}
|
||||||
|
has (name: IWindowList) {
|
||||||
|
return this.windowMap.has(name)
|
||||||
|
}
|
||||||
|
delete = (name: IWindowList) => {
|
||||||
|
const window = this.windowMap.get(name)
|
||||||
|
if (window) {
|
||||||
|
this.windowIdMap.delete(window.id)
|
||||||
|
this.windowMap.delete(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deleteById = (id: number) => {
|
||||||
|
const name = this.windowIdMap.get(id)
|
||||||
|
if (name) {
|
||||||
|
this.windowMap.delete(name)
|
||||||
|
this.windowIdMap.delete(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getAvailableWindow () {
|
||||||
|
const miniWindow = this.windowMap.get(IWindowList.MINI_WINDOW)
|
||||||
|
if (miniWindow && miniWindow.isVisible()) {
|
||||||
|
return miniWindow
|
||||||
|
} else {
|
||||||
|
const settingWindow = this.windowMap.get(IWindowList.SETTING_WINDOW)
|
||||||
|
const trayWindow = this.windowMap.get(IWindowList.TRAY_WINDOW)
|
||||||
|
return settingWindow || trayWindow || this.create(IWindowList.SETTING_WINDOW)!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new WindowManager()
|
||||||
@@ -3,20 +3,37 @@ import routers from './routerManager'
|
|||||||
import {
|
import {
|
||||||
handleResponse
|
handleResponse
|
||||||
} from './utils'
|
} from './utils'
|
||||||
import picgo from '~/main/utils/picgo'
|
import picgo from '~/main/apis/picgo'
|
||||||
import logger from '~/main/utils/logger'
|
import logger from '~/main/utils/logger'
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
private httpServer: http.Server
|
private httpServer: http.Server
|
||||||
private config: IServerConfig
|
private config: IServerConfig
|
||||||
constructor () {
|
constructor () {
|
||||||
this.config = picgo.getConfig('settings.server') || {
|
let config = picgo.getConfig('settings.server')
|
||||||
port: 36677,
|
const result = this.checkIfConfigIsValid(config)
|
||||||
host: '127.0.0.1',
|
if (result) {
|
||||||
enable: true
|
this.config = config
|
||||||
|
} else {
|
||||||
|
config = {
|
||||||
|
port: 36677,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
enable: true
|
||||||
|
}
|
||||||
|
this.config = config
|
||||||
|
picgo.saveConfig({
|
||||||
|
'settings.server': config
|
||||||
|
})
|
||||||
}
|
}
|
||||||
this.httpServer = http.createServer(this.handleRequest)
|
this.httpServer = http.createServer(this.handleRequest)
|
||||||
}
|
}
|
||||||
|
private checkIfConfigIsValid (config: IObj | undefined) {
|
||||||
|
if (config && config.port && config.host && (config.enable !== undefined)) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
private handleRequest = (request: http.IncomingMessage, response: http.ServerResponse) => {
|
private handleRequest = (request: http.IncomingMessage, response: http.ServerResponse) => {
|
||||||
if (request.method === 'POST') {
|
if (request.method === 'POST') {
|
||||||
if (!routers.getHandler(request.url!)) {
|
if (!routers.getHandler(request.url!)) {
|
||||||
@@ -65,7 +82,7 @@ class Server {
|
|||||||
logger.warn(`[PicGo Server] ${port} is busy, trying with port ${port + 1}`)
|
logger.warn(`[PicGo Server] ${port} is busy, trying with port ${port + 1}`)
|
||||||
this.config.port += 1
|
this.config.port += 1
|
||||||
picgo.saveConfig({
|
picgo.saveConfig({
|
||||||
'settings.server.port': this.config.port
|
'settings.server': this.config
|
||||||
})
|
})
|
||||||
this.listen(this.config.port)
|
this.listen(this.config.port)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import router from './router'
|
|||||||
import {
|
import {
|
||||||
uploadWithClipboardFiles,
|
uploadWithClipboardFiles,
|
||||||
uploadWithFiles
|
uploadWithFiles
|
||||||
} from '~/main/utils/busApi/index'
|
} from '~/main/apis/bus/index'
|
||||||
import {
|
import {
|
||||||
handleResponse
|
handleResponse
|
||||||
} from './utils'
|
} from './utils'
|
||||||
@@ -24,7 +24,7 @@ router.get('/upload', async ({
|
|||||||
response,
|
response,
|
||||||
body: {
|
body: {
|
||||||
success: true,
|
success: true,
|
||||||
result: [res.result]
|
result: res.result
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import picgo from './picgo'
|
import picgo from '../apis/picgo'
|
||||||
|
|
||||||
const getPicBeds = () => {
|
const getPicBeds = () => {
|
||||||
const picBedTypes = picgo.helper.uploader.getIdList()
|
const picBedTypes = picgo.helper.uploader.getIdList()
|
||||||
@@ -14,6 +14,4 @@ const getPicBeds = () => {
|
|||||||
return picBeds
|
return picBeds
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export default getPicBeds
|
||||||
getPicBeds
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import db from '#/datastore'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import pkg from 'root/package.json'
|
import pkg from 'root/package.json'
|
||||||
const version = pkg.version
|
const version = pkg.version
|
||||||
let release = 'https://cdn.jsdelivr.net/gh/Molunerfinn/PicGo/package.json'
|
const releaseUrl = 'https://api.github.com/repos/Molunerfinn/PicGo/releases/latest'
|
||||||
|
const releaseUrlBackup = 'https://cdn.jsdelivr.net/gh/Molunerfinn/PicGo@latest/package.json'
|
||||||
const downloadUrl = 'https://github.com/Molunerfinn/PicGo/releases/latest'
|
const downloadUrl = 'https://github.com/Molunerfinn/PicGo/releases/latest'
|
||||||
|
|
||||||
const checkVersion = async () => {
|
const checkVersion = async () => {
|
||||||
@@ -15,12 +16,15 @@ const checkVersion = async () => {
|
|||||||
if (showTip) {
|
if (showTip) {
|
||||||
let res: any
|
let res: any
|
||||||
try {
|
try {
|
||||||
res = await axios.get(release)
|
res = await axios.get(releaseUrl).catch(async () => {
|
||||||
|
const result = await axios.get(releaseUrlBackup)
|
||||||
|
return result
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
const latest = res.data.version
|
const latest = res.data.version || res.data.name
|
||||||
const result = compareVersion2Update(version, latest)
|
const result = compareVersion2Update(version, latest)
|
||||||
if (result) {
|
if (result) {
|
||||||
dialog.showMessageBox({
|
dialog.showMessageBox({
|
||||||
|
|||||||
@@ -237,9 +237,8 @@ export default class extends Vue {
|
|||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
const file = this.$db.get('uploaded').getById(id)
|
const file = this.$db.getById('uploaded', id)
|
||||||
// @ts-ignore
|
this.$db.removeById('uploaded', id)
|
||||||
this.$db.read().get('uploaded').removeById(id).write()
|
|
||||||
ipcRenderer.send('removeFiles', [file])
|
ipcRenderer.send('removeFiles', [file])
|
||||||
const obj = {
|
const obj = {
|
||||||
title: '操作结果',
|
title: '操作结果',
|
||||||
@@ -250,7 +249,8 @@ export default class extends Vue {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
this.getGallery()
|
this.getGallery()
|
||||||
}).catch(() => {
|
}).catch((e) => {
|
||||||
|
console.log(e)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -302,11 +302,9 @@ export default class extends Vue {
|
|||||||
let files: ImgInfo[] = []
|
let files: ImgInfo[] = []
|
||||||
Object.keys(this.choosedList).forEach(key => {
|
Object.keys(this.choosedList).forEach(key => {
|
||||||
if (this.choosedList[key]) {
|
if (this.choosedList[key]) {
|
||||||
// @ts-ignore
|
const file = this.$db.getById('uploaded', key)
|
||||||
const file = this.$db.read().get('uploaded').getById(key).value()
|
|
||||||
files.push(file)
|
files.push(file)
|
||||||
// @ts-ignore
|
this.$db.removeById('uploaded', key)
|
||||||
this.$db.read().get('uploaded').removeById(key).write()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.choosedList = {}
|
this.choosedList = {}
|
||||||
@@ -332,8 +330,7 @@ export default class extends Vue {
|
|||||||
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
|
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
|
||||||
Object.keys(this.choosedList).forEach(key => {
|
Object.keys(this.choosedList).forEach(key => {
|
||||||
if (this.choosedList[key]) {
|
if (this.choosedList[key]) {
|
||||||
// @ts-ignore
|
const item = this.$db.getById('uploaded', key)
|
||||||
const item = this.$db.read().get('uploaded').getById(key).value()
|
|
||||||
copyString += pasteStyle(style, item) + '\n'
|
copyString += pasteStyle(style, item) + '\n'
|
||||||
this.choosedList[key] = false
|
this.choosedList[key] = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,8 +170,10 @@ export default class extends Vue {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '最小化窗口',
|
label: '隐藏窗口',
|
||||||
role: 'minimize'
|
click () {
|
||||||
|
remote.BrowserWindow.getFocusedWindow()!.hide()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '重启应用',
|
label: '重启应用',
|
||||||
|
|||||||
@@ -305,7 +305,8 @@ import {
|
|||||||
} from 'electron'
|
} from 'electron'
|
||||||
import { Component, Vue } from 'vue-property-decorator'
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
import db from '#/datastore'
|
import db from '#/datastore'
|
||||||
const release = 'https://api.github.com/repos/Molunerfinn/PicGo/releases/latest'
|
const releaseUrl = 'https://api.github.com/repos/Molunerfinn/PicGo/releases/latest'
|
||||||
|
const releaseUrlBackup = 'https://cdn.jsdelivr.net/gh/Molunerfinn/PicGo@latest/package.json'
|
||||||
const downloadUrl = 'https://github.com/Molunerfinn/PicGo/releases/latest'
|
const downloadUrl = 'https://github.com/Molunerfinn/PicGo/releases/latest'
|
||||||
const customLinkRule = (rule: string, value: string, callback: (arg0?: Error) => void) => {
|
const customLinkRule = (rule: string, value: string, callback: (arg0?: Error) => void) => {
|
||||||
if (!/\$url/.test(value)) {
|
if (!/\$url/.test(value)) {
|
||||||
@@ -484,11 +485,16 @@ export default class extends Vue {
|
|||||||
}
|
}
|
||||||
checkUpdate () {
|
checkUpdate () {
|
||||||
this.checkUpdateVisible = true
|
this.checkUpdateVisible = true
|
||||||
this.$http.get(release)
|
this.$http.get(releaseUrl)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
this.latestVersion = res.data.name
|
this.latestVersion = res.data.name
|
||||||
}).catch(err => {
|
}).catch(async () => {
|
||||||
console.log(err)
|
this.$http.get(releaseUrlBackup)
|
||||||
|
.then(res => {
|
||||||
|
this.latestVersion = res.data.version
|
||||||
|
}).catch(() => {
|
||||||
|
this.latestVersion = '网络错误暂时无法获取'
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
confirmCheckVersion () {
|
confirmCheckVersion () {
|
||||||
|
|||||||
@@ -61,6 +61,14 @@ class DB {
|
|||||||
unset (key: string, value: any): boolean {
|
unset (key: string, value: any): boolean {
|
||||||
return this.read().get(key).unset(value).value()
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new DB()
|
export default new DB()
|
||||||
|
|||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
import {
|
||||||
|
BrowserWindow
|
||||||
|
} from 'electron'
|
||||||
|
import {
|
||||||
|
IWindowList
|
||||||
|
} from '~/main/apis/window/constants'
|
||||||
|
|
||||||
|
declare interface IWindowListItem {
|
||||||
|
isValid: boolean
|
||||||
|
multiple: boolean
|
||||||
|
options: () => IBrowserWindowOptions,
|
||||||
|
callback: (window: BrowserWindow | null) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare interface IWindowManager {
|
||||||
|
create: (name: IWindowList) => BrowserWindow | null
|
||||||
|
get: (name: IWindowList) => BrowserWindow | null
|
||||||
|
delete: (name: IWindowList) => void
|
||||||
|
getAvailableWindow: () => BrowserWindow
|
||||||
|
}
|
||||||
Vendored
+5
-6
@@ -7,7 +7,7 @@ interface IObjT<T> {
|
|||||||
[propName: string]: T
|
[propName: string]: T
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ErrnoException extends Error {
|
declare interface ErrnoException extends Error {
|
||||||
errno?: number | string;
|
errno?: number | string;
|
||||||
code?: string;
|
code?: string;
|
||||||
path?: string;
|
path?: string;
|
||||||
@@ -15,6 +15,10 @@ interface ErrnoException extends Error {
|
|||||||
stack?: string;
|
stack?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare var __static: string
|
||||||
|
|
||||||
|
declare type ILogType = 'success' | 'info' | 'warn' | 'error'
|
||||||
|
|
||||||
// Server
|
// Server
|
||||||
type routeHandler = (ctx: IServerCTX) => Promise<void>
|
type routeHandler = (ctx: IServerCTX) => Promise<void>
|
||||||
|
|
||||||
@@ -114,11 +118,6 @@ interface IBounds {
|
|||||||
y: number
|
y: number
|
||||||
}
|
}
|
||||||
|
|
||||||
declare type ILogType = 'success' | 'info' | 'warn' | 'error'
|
|
||||||
|
|
||||||
// global value
|
|
||||||
declare var __static: string
|
|
||||||
|
|
||||||
// PicGo Types
|
// PicGo Types
|
||||||
type ICtx = import('picgo')
|
type ICtx = import('picgo')
|
||||||
interface IPicGoPlugin {
|
interface IPicGoPlugin {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "esnext",
|
"target": "es2020",
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
linux: {
|
linux: {
|
||||||
icon: 'build/icons/'
|
icon: 'build/icons/'
|
||||||
|
},
|
||||||
|
snap: {
|
||||||
|
publish: ['github']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user