PicList/src/main/index.js

554 lines
14 KiB
JavaScript
Raw Normal View History

2017-11-27 19:21:12 -05:00
'use strict'
2018-12-18 05:58:31 -05:00
import Uploader from './utils/uploader.js'
import { app, BrowserWindow, Tray, Menu, Notification, clipboard, ipcMain, globalShortcut, dialog } from 'electron'
2017-11-28 10:56:15 -05:00
import db from '../datastore'
import pasteTemplate from './utils/pasteTemplate'
2017-12-23 03:38:19 -05:00
import updateChecker from './utils/updateChecker'
2018-12-23 10:15:00 -05:00
import { getPicBeds } from './utils/getPicBeds'
import pkg from '../../package.json'
import picgoCoreIPC from './utils/picgoCoreIPC'
2017-11-27 19:21:12 -05:00
/**
* Set `__static` path to static files in production
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
*/
if (process.env.NODE_ENV !== 'development') {
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}
2018-01-12 04:24:07 -05:00
if (process.env.DEBUG_ENV === 'debug') {
global.__static = require('path').join(__dirname, '../../static').replace(/\\/g, '\\\\')
}
2017-11-27 19:21:12 -05:00
let window
let settingWindow
2018-07-05 12:43:53 -04:00
let miniWindow
2017-11-27 19:21:12 -05:00
let tray
2017-12-15 04:37:38 -05:00
let menu
2018-01-30 02:20:19 -05:00
let contextMenu
2017-11-27 19:21:12 -05:00
const winURL = process.env.NODE_ENV === 'development'
? `http://localhost:9080`
: `file://${__dirname}/index.html`
const settingWinURL = process.env.NODE_ENV === 'development'
? `http://localhost:9080/#setting/upload`
: `file://${__dirname}/index.html#setting/upload`
2018-07-05 12:43:53 -04:00
const miniWinURL = process.env.NODE_ENV === 'development'
? `http://localhost:9080/#mini-page`
: `file://${__dirname}/index.html#mini-page`
2017-11-27 19:21:12 -05:00
function createContextMenu () {
2018-12-23 10:15:00 -05:00
const picBeds = getPicBeds(app)
const submenu = picBeds.map(item => {
2018-06-05 08:29:16 -04:00
return {
label: item.name,
type: 'radio',
checked: db.read().get('picBed.current').value() === item.type,
click () {
db.read().set('picBed.current', item.type).write()
2018-07-10 10:37:29 -04:00
if (settingWindow) {
settingWindow.webContents.send('syncPicBed')
}
2018-06-05 08:29:16 -04:00
}
}
})
2018-01-30 02:20:19 -05:00
contextMenu = Menu.buildFromTemplate([
{
label: '关于',
click () {
dialog.showMessageBox({
title: 'PicGo',
message: 'PicGo',
detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`
})
}
},
2017-11-27 19:21:12 -05:00
{
2017-11-28 10:56:15 -05:00
label: '打开详细窗口',
2017-11-27 19:21:12 -05:00
click () {
if (settingWindow === null) {
createSettingWindow()
2017-12-11 08:52:14 -05:00
settingWindow.show()
2017-11-27 19:21:12 -05:00
} else {
settingWindow.show()
settingWindow.focus()
}
if (miniWindow) {
miniWindow.hide()
}
2017-11-27 19:21:12 -05:00
}
2017-11-28 10:56:15 -05:00
},
{
label: '选择默认图床',
type: 'submenu',
2018-06-05 08:29:16 -04:00
submenu
2017-12-11 08:52:14 -05:00
},
2018-01-10 04:12:24 -05:00
{
label: '打开更新助手',
type: 'checkbox',
checked: db.get('settings.showUpdateTip').value(),
2018-01-10 04:12:24 -05:00
click () {
const value = db.read().get('settings.showUpdateTip').value()
db.read().set('settings.showUpdateTip', !value).write()
2018-01-10 04:12:24 -05:00
}
},
2017-12-11 08:52:14 -05:00
{
role: 'quit',
label: '退出'
2017-11-27 19:21:12 -05:00
}
])
}
function createTray () {
const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png`
tray = new Tray(menubarPic)
2017-11-27 19:21:12 -05:00
tray.on('right-click', () => {
if (window) {
window.hide()
}
createContextMenu()
2017-11-27 19:21:12 -05:00
tray.popUpContextMenu(contextMenu)
})
tray.on('click', (event, bounds) => {
2018-01-10 03:51:09 -05:00
if (process.platform === 'darwin') {
let img = clipboard.readImage()
let obj = []
if (!img.isEmpty()) {
// 从剪贴板来的图片默认转为png
const imgUrl = 'data:image/png;base64,' + Buffer.from(img.toPNG(), 'binary').toString('base64')
obj.push({
width: img.getSize().width,
height: img.getSize().height,
imgUrl
})
}
toggleWindow(bounds)
2018-01-10 03:51:09 -05:00
setTimeout(() => {
window.webContents.send('clipboardFiles', obj)
}, 0)
} else {
if (window) {
window.hide()
}
2018-01-10 03:51:09 -05:00
if (settingWindow === null) {
createSettingWindow()
settingWindow.show()
} else {
settingWindow.show()
settingWindow.focus()
}
if (miniWindow) {
miniWindow.hide()
}
2017-11-27 19:21:12 -05:00
}
})
tray.on('drag-enter', () => {
tray.setImage(`${__static}/upload.png`)
})
tray.on('drag-end', () => {
2017-12-11 08:52:14 -05:00
tray.setImage(`${__static}/menubar.png`)
2017-11-27 19:21:12 -05:00
})
tray.on('drop-files', async (event, files) => {
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
2019-01-11 04:22:33 -05:00
const imgs = await new Uploader(files, window.webContents).upload()
2017-12-22 09:30:16 -05:00
if (imgs !== false) {
for (let i in imgs) {
2019-01-11 04:22:33 -05:00
const url = imgs[i].url || imgs[i].imgUrl
clipboard.writeText(pasteTemplate(pasteStyle, url))
2017-12-22 09:30:16 -05:00
const notification = new Notification({
title: '上传成功',
body: imgs[i].imgUrl,
icon: files[i]
})
setTimeout(() => {
notification.show()
}, i * 100)
2019-01-11 04:22:33 -05:00
db.read().get('uploaded').insert(imgs[i]).write()
2017-12-22 09:30:16 -05:00
}
window.webContents.send('dragFiles', imgs)
2017-11-27 19:21:12 -05:00
}
})
2017-12-08 02:52:41 -05:00
// toggleWindow()
2017-11-27 19:21:12 -05:00
}
const createWindow = () => {
if (process.platform !== 'darwin' && process.platform !== 'win32') {
return
}
2017-11-27 19:21:12 -05:00
window = new BrowserWindow({
height: 350,
width: 196, // 196
show: false,
frame: false,
fullscreenable: false,
resizable: false,
transparent: true,
vibrancy: 'ultra-dark',
webPreferences: {
backgroundThrottling: false
}
})
window.loadURL(winURL)
window.on('closed', () => {
window = null
})
window.on('blur', () => {
window.hide()
})
}
2018-07-05 12:43:53 -04:00
const createMiniWidow = () => {
2018-07-06 11:54:36 -04:00
if (miniWindow) {
return false
}
let obj = {
2018-07-05 12:43:53 -04:00
height: 64,
2018-07-06 11:54:36 -04:00
width: 64,
show: true,
2018-07-05 12:43:53 -04:00
frame: false,
fullscreenable: false,
resizable: false,
transparent: true,
2018-07-06 12:01:06 -04:00
icon: `${__static}/logo.png`,
2018-07-05 12:43:53 -04:00
webPreferences: {
backgroundThrottling: false
}
}
if (process.platform === 'linux') {
obj.transparent = false
}
2018-09-18 07:08:26 -04:00
if (process.platform === 'darwin') {
obj.show = false
}
2018-09-07 05:32:11 -04:00
if (db.read().get('miniWindowOntop').value()) {
obj.alwaysOnTop = true
}
miniWindow = new BrowserWindow(obj)
2018-07-05 12:43:53 -04:00
miniWindow.loadURL(miniWinURL)
miniWindow.on('closed', () => {
miniWindow = null
})
}
2017-11-27 19:21:12 -05:00
const createSettingWindow = () => {
2018-01-10 03:51:09 -05:00
const options = {
2017-11-27 19:21:12 -05:00
height: 450,
width: 800,
2017-12-08 02:52:41 -05:00
show: false,
2017-11-27 19:21:12 -05:00
frame: true,
center: true,
fullscreenable: false,
resizable: false,
2018-01-10 03:51:09 -05:00
title: 'PicGo',
2017-11-27 19:21:12 -05:00
vibrancy: 'ultra-dark',
transparent: true,
titleBarStyle: 'hidden',
webPreferences: {
backgroundThrottling: false,
webSecurity: false
2017-11-27 19:21:12 -05:00
}
2018-01-10 03:51:09 -05:00
}
if (process.platform !== 'darwin') {
options.show = false
2018-01-10 03:51:09 -05:00
options.frame = false
options.backgroundColor = '#3f3c37'
options.transparent = false
2018-07-05 12:43:53 -04:00
options.icon = `${__static}/logo.png`
2018-01-10 03:51:09 -05:00
}
settingWindow = new BrowserWindow(options)
2017-11-27 19:21:12 -05:00
settingWindow.loadURL(settingWinURL)
settingWindow.on('closed', () => {
settingWindow = null
2018-07-10 22:04:42 -04:00
if (process.platform === 'linux') {
app.quit()
}
2017-11-27 19:21:12 -05:00
})
createMenu()
2018-07-05 12:43:53 -04:00
createMiniWidow()
2017-11-27 19:21:12 -05:00
}
2017-12-15 04:37:38 -05:00
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()
}
2017-12-15 04:37:38 -05:00
}
]
}]
menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
}
2017-12-15 04:37:38 -05:00
}
const toggleWindow = (bounds) => {
2017-11-27 19:21:12 -05:00
if (window.isVisible()) {
window.hide()
} else {
showWindow(bounds)
2017-11-27 19:21:12 -05:00
}
}
const showWindow = (bounds) => {
window.setPosition(bounds.x - 98 + 11, bounds.y, false)
2017-12-07 01:33:14 -05:00
window.webContents.send('updateFiles')
2017-11-27 19:21:12 -05:00
window.show()
window.focus()
}
const uploadClipboardFiles = async () => {
let win
if (miniWindow.isVisible()) {
win = miniWindow
} else {
win = settingWindow || window
}
2018-12-18 05:58:31 -05:00
let img = await new Uploader(undefined, 'imgFromClipboard', win.webContents).upload()
if (img !== false) {
2018-01-30 02:20:19 -05:00
if (img.length > 0) {
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
2019-01-11 04:22:33 -05:00
const url = img[0].url || img[0].imgUrl
clipboard.writeText(pasteTemplate(pasteStyle, url))
2018-01-30 02:20:19 -05:00
const notification = new Notification({
title: '上传成功',
body: img[0].imgUrl,
icon: img[0].imgUrl
})
notification.show()
2019-01-11 04:22:33 -05:00
db.read().get('uploaded').insert(img[0]).write()
2018-01-30 02:20:19 -05:00
window.webContents.send('clipboardFiles', [])
window.webContents.send('uploadFiles', img)
if (settingWindow) {
settingWindow.webContents.send('updateGallery')
}
2018-01-30 02:20:19 -05:00
} else {
const notification = new Notification({
title: '上传不成功',
body: '你剪贴板最新的一条记录不是图片哦'
})
notification.show()
}
}
}
picgoCoreIPC(app, ipcMain)
2018-12-27 22:10:28 -05:00
// from macOS tray
2017-11-27 19:21:12 -05:00
ipcMain.on('uploadClipboardFiles', async (evt, file) => {
2019-01-11 04:22:33 -05:00
const img = await new Uploader(file, window.webContents).upload()
2017-12-22 09:30:16 -05:00
if (img !== false) {
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
2019-01-11 04:22:33 -05:00
const url = img[0].url || img[0].imgUrl
clipboard.writeText(pasteTemplate(pasteStyle, url))
2017-12-22 09:30:16 -05:00
const notification = new Notification({
title: '上传成功',
body: img[0].imgUrl,
// icon: file[0]
icon: img[0].imgUrl
2017-12-22 09:30:16 -05:00
})
notification.show()
2019-01-11 04:22:33 -05:00
db.read().get('uploaded').insert(img[0]).write()
2017-12-22 09:30:16 -05:00
window.webContents.send('clipboardFiles', [])
2018-08-08 02:39:40 -04:00
window.webContents.send('uploadFiles')
if (settingWindow) {
settingWindow.webContents.send('updateGallery')
}
2017-12-22 09:30:16 -05:00
}
2017-11-28 10:56:15 -05:00
})
2018-01-30 02:20:19 -05:00
ipcMain.on('uploadClipboardFilesFromUploadPage', () => {
uploadClipboardFiles()
})
2017-11-28 10:56:15 -05:00
ipcMain.on('uploadChoosedFiles', async (evt, files) => {
const input = files.map(item => item.path)
2019-01-11 04:22:33 -05:00
const imgs = await new Uploader(input, evt.sender).upload()
2017-12-22 09:30:16 -05:00
if (imgs !== false) {
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
2017-12-22 09:30:16 -05:00
let pasteText = ''
for (let i in imgs) {
2019-01-11 04:22:33 -05:00
const url = imgs[i].url || imgs[i].imgUrl
pasteText += pasteTemplate(pasteStyle, url) + '\r\n'
2017-12-22 09:30:16 -05:00
const notification = new Notification({
title: '上传成功',
body: imgs[i].imgUrl,
icon: files[i].path
})
setTimeout(() => {
notification.show()
}, i * 100)
2019-01-11 04:22:33 -05:00
db.read().get('uploaded').insert(imgs[i]).write()
2017-12-22 09:30:16 -05:00
}
clipboard.writeText(pasteText)
window.webContents.send('uploadFiles', imgs)
if (settingWindow) {
settingWindow.webContents.send('updateGallery')
}
2017-11-28 10:56:15 -05:00
}
2017-11-27 19:21:12 -05:00
})
2018-01-30 02:20:19 -05:00
ipcMain.on('updateShortKey', (evt, oldKey) => {
globalShortcut.unregisterAll()
for (let key in oldKey) {
globalShortcut.register(db.read().get('settings.shortKey').value()[key], () => {
2018-01-30 02:20:19 -05:00
return shortKeyHash[key]()
})
}
const notification = new Notification({
title: '操作成功',
body: '你的快捷键已经修改成功'
})
notification.show()
})
ipcMain.on('updateCustomLink', (evt, oldLink) => {
const notification = new Notification({
title: '操作成功',
body: '你的自定义链接格式已经修改成功'
})
notification.show()
})
2018-05-02 07:34:24 -04:00
ipcMain.on('autoStart', (evt, val) => {
app.setLoginItemSettings({
openAtLogin: val
})
})
2018-07-06 11:54:36 -04:00
ipcMain.on('openSettingWindow', (evt) => {
if (!settingWindow) {
createSettingWindow()
} else {
settingWindow.show()
}
miniWindow.hide()
})
ipcMain.on('openMiniWindow', (evt) => {
if (!miniWindow) {
createMiniWidow()
}
miniWindow.show()
miniWindow.focus()
2018-07-06 11:54:36 -04:00
settingWindow.hide()
})
2018-07-10 10:37:29 -04:00
// from mini window
ipcMain.on('syncPicBed', (evt) => {
if (settingWindow) {
settingWindow.webContents.send('syncPicBed')
}
})
2018-12-23 10:15:00 -05:00
ipcMain.on('getPicBeds', (evt) => {
const picBeds = getPicBeds(app)
evt.sender.send('getPicBeds', picBeds)
evt.returnValue = picBeds
2018-12-23 10:15:00 -05:00
})
2018-01-30 02:20:19 -05:00
const shortKeyHash = {
upload: uploadClipboardFiles
}
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
if (settingWindow) {
if (settingWindow.isMinimized()) {
settingWindow.restore()
}
settingWindow.focus()
}
}
2018-01-10 03:51:09 -05:00
if (process.platform === 'win32') {
app.setAppUserModelId(pkg.build.appId)
}
if (process.env.XDG_CURRENT_DESKTOP && process.env.XDG_CURRENT_DESKTOP.includes('Unity')) {
process.env.XDG_CURRENT_DESKTOP = 'Unity'
}
2017-11-27 19:21:12 -05:00
app.on('ready', () => {
createWindow()
createSettingWindow()
if (process.platform === 'darwin' || process.platform === 'win32') {
createTray()
}
2018-12-24 03:05:30 -05:00
db.read().set('needReload', false).write()
2017-12-23 03:38:19 -05:00
updateChecker()
globalShortcut.register(db.read().get('settings.shortKey.upload').value(), () => {
uploadClipboardFiles()
})
2017-11-27 19:21:12 -05:00
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (window === null) {
2017-11-27 19:21:12 -05:00
createWindow()
}
if (settingWindow === null) {
createSettingWindow()
}
2017-11-27 19:21:12 -05:00
})
app.on('will-quit', () => {
globalShortcut.unregisterAll()
})
2018-05-02 05:17:55 -04:00
app.setLoginItemSettings({
openAtLogin: db.read().get('settings.autoStart').value() || false
2018-05-02 05:17:55 -04:00
})
2017-11-27 19:21:12 -05:00
/**
* Auto Updater
*
* Uncomment the following code below and install `electron-updater` to
* support auto updating. Code Signing with a valid certificate is required.
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
*/
// import { autoUpdater } from 'electron-updater'
// autoUpdater.on('update-downloaded', () => {
// autoUpdater.quitAndInstall()
// })
// app.on('ready', () => {
// if (process.env.NODE_ENV === 'production') {
// autoUpdater.checkForUpdates()
// }
// })