Added: picgo plugin handle states

This commit is contained in:
Molunerfinn 2018-12-18 18:58:31 +08:00
parent 72f2669cce
commit be6cce9501
14 changed files with 175 additions and 131 deletions

View File

@ -1,6 +1,6 @@
'use strict'
import uploader from './utils/uploader.js'
import Uploader from './utils/uploader.js'
import { app, BrowserWindow, Tray, Menu, Notification, clipboard, ipcMain, globalShortcut, dialog } from 'electron'
import db from '../datastore'
import pasteTemplate from './utils/pasteTemplate'
@ -146,7 +146,7 @@ function createTray () {
tray.on('drop-files', async (event, files) => {
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
const imgs = await uploader(files, 'imgFromPath', window.webContents)
const imgs = await new Uploader(files, 'imgFromPath', window.webContents).upload()
if (imgs !== false) {
for (let i in imgs) {
clipboard.writeText(pasteTemplate(pasteStyle, imgs[i].imgUrl))
@ -323,7 +323,7 @@ const uploadClipboardFiles = async () => {
} else {
win = settingWindow || window
}
let img = await uploader(undefined, 'imgFromClipboard', win.webContents)
let img = await new Uploader(undefined, 'imgFromClipboard', win.webContents).upload()
if (img !== false) {
if (img.length > 0) {
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
@ -371,7 +371,7 @@ const updateDefaultPicBed = () => {
picgoCoreIPC(app, ipcMain)
ipcMain.on('uploadClipboardFiles', async (evt, file) => {
const img = await uploader(file, 'imgFromClipboard', window.webContents)
const img = await new Uploader(file, 'imgFromClipboard', window.webContents).upload()
if (img !== false) {
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
clipboard.writeText(pasteTemplate(pasteStyle, img[0].imgUrl))
@ -399,7 +399,7 @@ ipcMain.on('uploadClipboardFilesFromUploadPage', () => {
ipcMain.on('uploadChoosedFiles', async (evt, files) => {
const input = files.map(item => item.path)
const imgs = await uploader(input, 'imgFromUploader', evt.sender)
const imgs = await new Uploader(input, 'imgFromUploader', evt.sender).upload()
if (imgs !== false) {
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
let pasteText = ''

View File

@ -37,6 +37,7 @@ const handleGetPluginList = (ipcMain, STORE_PATH, CONFIG_PATH) => {
ipcMain.on('getPluginList', event => {
const picgo = new PicGo(CONFIG_PATH)
const pluginList = picgo.pluginLoader.getList()
// console.log(pluginList.length)
const list = []
for (let i in pluginList) {
const plugin = picgo.pluginLoader.getPlugin(pluginList[i])
@ -65,7 +66,8 @@ const handleGetPluginList = (ipcMain, STORE_PATH, CONFIG_PATH) => {
}
},
enabled: picgo.getConfig(`plugins.${pluginList[i]}`),
homepage: pluginPKG.homepage ? pluginPKG.homepage : ''
homepage: pluginPKG.homepage ? pluginPKG.homepage : '',
ing: false
}
list.push(obj)
}
@ -91,7 +93,7 @@ const handlePluginUninstall = (ipcMain, STORE_PATH, CONFIG_PATH) => {
const picgo = new PicGo(CONFIG_PATH)
const pluginHandler = new PluginHandler(picgo)
picgo.on('uninstallSuccess', notice => {
event.sender.send('installSuccess', notice.body[0].replace(/picgo-plugin-/, ''))
event.sender.send('uninstallSuccess', notice.body[0].replace(/picgo-plugin-/, ''))
})
pluginHandler.uninstall([`picgo-plugin-${msg}`])
picgo.cmd.program.removeAllListeners()

View File

@ -74,69 +74,78 @@ const waitForRename = (window, id) => {
})
}
const uploader = (img, type, webContents) => {
const win = BrowserWindow.fromWebContents(webContents)
const picgo = new PicGo(CONFIG_PATH)
picgo.config.debug = true
let input = img
class Uploader {
constructor (img, type, webContents) {
this.img = img
this.type = type
this.webContents = webContents
}
picgo.helper.beforeUploadPlugins.register('renameFn', {
handle: async ctx => {
const rename = picgo.getConfig('settings.rename')
const autoRename = picgo.getConfig('settings.autoRename')
await Promise.all(ctx.output.map(async (item, index) => {
let name
let fileName
if (autoRename) {
fileName = dayjs().add(index, 'second').format('YYYYMMDDHHmmss') + item.extname
} else {
fileName = item.fileName
}
if (rename) {
const window = createRenameWindow(win)
await waitForShow(window.webContents)
window.webContents.send('rename', fileName, window.webContents.id)
name = await waitForRename(window, window.webContents.id)
}
item.fileName = name || fileName
}))
}
})
upload () {
const win = BrowserWindow.fromWebContents(this.webContents)
const picgo = new PicGo(CONFIG_PATH)
console.log(picgo.pluginLoader.getList())
picgo.config.debug = true
let input = this.img
picgo.on('beforeTransform', ctx => {
if (ctx.getConfig('settings.uploadNotification')) {
const notification = new Notification({
title: '上传进度',
body: '正在上传'
})
notification.show()
}
})
picgo.upload(input)
picgo.on('notification', message => {
const notification = new Notification(message)
notification.show()
})
picgo.on('uploadProgress', progress => {
webContents.send('uploadProgress', progress)
})
return new Promise((resolve) => {
picgo.on('finished', ctx => {
if (ctx.output.every(item => item.imgUrl)) {
resolve(ctx.output)
} else {
resolve(false)
picgo.helper.beforeUploadPlugins.register('renameFn', {
handle: async ctx => {
const rename = picgo.getConfig('settings.rename')
const autoRename = picgo.getConfig('settings.autoRename')
await Promise.all(ctx.output.map(async (item, index) => {
let name
let fileName
if (autoRename) {
fileName = dayjs().add(index, 'second').format('YYYYMMDDHHmmss') + item.extname
} else {
fileName = item.fileName
}
if (rename) {
const window = createRenameWindow(win)
await waitForShow(window.webContents)
window.webContents.send('rename', fileName, window.webContents.id)
name = await waitForRename(window, window.webContents.id)
}
item.fileName = name || fileName
}))
}
})
picgo.on('failed', ctx => {
console.log(ctx)
resolve(false)
picgo.on('beforeTransform', ctx => {
if (ctx.getConfig('settings.uploadNotification')) {
const notification = new Notification({
title: '上传进度',
body: '正在上传'
})
notification.show()
}
})
})
picgo.upload(input)
picgo.on('notification', message => {
const notification = new Notification(message)
notification.show()
})
picgo.on('uploadProgress', progress => {
this.webContents.send('uploadProgress', progress)
})
return new Promise((resolve) => {
picgo.on('finished', ctx => {
if (ctx.output.every(item => item.imgUrl)) {
resolve(ctx.output)
} else {
resolve(false)
}
})
picgo.on('failed', ctx => {
console.log(ctx)
resolve(false)
})
})
}
}
export default uploader
export default Uploader

View File

@ -18,7 +18,10 @@
<img class="plugin-item__logo" :src="item.logo"
onerror="this.src='static/logo.png'"
>
<div class="plugin-item__content">
<div
class="plugin-item__content"
:class="{ disabled: !item.enabled }"
>
<div class="plugin-item__name">
{{ item.name }} <small>{{ ' ' + item.version }}</small>
</div>
@ -32,25 +35,33 @@
<span class="plugin-item__config" >
<template v-if="searchText">
<template v-if="!item.hasInstall">
<span class="config-button install" v-if="!item.installing" @click="installPlugin(item)">
<span class="config-button install" v-if="!item.ing" @click="installPlugin(item)">
安装
</span>
<span v-else="item.installing" class="config-button installing">
<span v-else-if="item.ing" class="config-button ing">
安装中
</span>
<span class="config-button reload" v-if="item.reload" @click="reloadApp">
重启
</span>
</template>
<span v-else class="config-button ing">
已安装
</span>
</template>
<template v-else>
<span class="config-button" v-if="item.reload" @click="reloadApp">
重启
<span v-if="item.ing" class="config-button ing">
卸载中
</span>
<i
class="el-icon-setting"
@click="buildContextMenu(item)"
></i>
<template v-else>
<i
v-if="item.enabled"
class="el-icon-setting"
@click="buildContextMenu(item)"
></i>
<i
v-else="!item.enabled"
class="el-icon-remove-outline"
@click="buildContextMenu(item)"
></i>
</template>
</template>
</span>
</div>
@ -81,7 +92,6 @@
<script>
import ConfigForm from '@/components/ConfigForm'
import { debounce } from 'lodash'
import LS from '@/utils/LS'
export default {
name: 'plugin',
components: {
@ -113,6 +123,7 @@ export default {
npmSearchText (val) {
if (val) {
this.loading = true
this.pluginList = []
this.getSearchResult(val)
} else {
this.getPluginList()
@ -120,17 +131,8 @@ export default {
}
},
created () {
console.log(this.pluginState)
this.$electron.ipcRenderer.on('pluginList', (evt, list) => {
const plugins = LS.get('plugins')
this.pluginList = list.map(item => {
if (plugins && plugins[item.name] && plugins[item.name].reload) {
item.reload = true
} else {
item.reload = false
}
return item
})
this.pluginList = list
this.pluginNameList = list.map(item => item.name)
this.loading = false
})
@ -138,24 +140,28 @@ export default {
this.loading = false
this.pluginList.forEach(item => {
if (item.name === plugin) {
item.installing = false
item.reload = true
this.handlePluginState(plugin, { reload: true })
item.ing = false
item.hasInstall = true
}
})
})
this.$electron.ipcRenderer.on('uninstallSuccess', (evt, plugin) => {
this.loading = false
this.pluginList.forEach(item => {
if (item.name === plugin) {
item.reload = true
item.hasInstall = false
this.handlePluginState(plugin, { reload: true })
this.pluginList = this.pluginList.filter(item => {
if (item.name === plugin) { // restore Uploader & Transformer after uninstalling
if (item.config.transformer.name) {
this.handleRestoreState('transformer')
}
if (item.config.uploader.name) {
this.handleRestoreState('uploader')
}
}
return item.name !== plugin
})
this.pluginNameList = this.pluginNameList.filter(item => item !== plugin)
})
this.getPluginList()
this.getSearchResult = debounce(this.getSearchResult, 250)
this.getSearchResult = debounce(this.getSearchResult, 50)
},
methods: {
buildContextMenu (plugin) {
@ -166,8 +172,6 @@ export default {
click () {
_this.$db.read().set(`plugins.picgo-plugin-${plugin.name}`, true).write()
plugin.enabled = true
plugin.reload = true
this.handlePluginState(plugin.name, { reload: true })
}
}, {
label: '禁用插件',
@ -175,13 +179,10 @@ export default {
click () {
_this.$db.read().set(`plugins.picgo-plugin-${plugin.name}`, false).write()
plugin.enabled = false
plugin.reload = true
this.handlePluginState(plugin.name, { reload: true })
}
}, {
label: '卸载插件',
click () {
_this.loading = true
_this.uninstallPlugin(plugin.name)
}
}]
@ -206,14 +207,18 @@ export default {
this.$electron.ipcRenderer.send('getPluginList')
},
installPlugin (item) {
item.installing = true
item.ing = true
this.$electron.ipcRenderer.send('installPlugin', item.name)
},
uninstallPlugin (val) {
this.pluginList.forEach(item => {
if (item.name === val) {
item.ing = true
}
})
this.$electron.ipcRenderer.send('uninstallPlugin', val)
},
reloadApp () {
LS.set('plugins', '')
this.$electron.remote.app.relaunch()
this.$electron.remote.app.exit(0)
},
@ -269,14 +274,17 @@ export default {
homepage: item.package.links ? item.package.links.homepage : '',
hasInstall: this.pluginNameList.some(plugin => plugin === item.package.name.replace(/picgo-plugin-/, '')),
version: item.package.version,
installing: false,
reload: false
ing: false // installing or uninstalling
}
},
handlePluginState (name, state) {
const plugins = LS.get('plugins')
plugins[name] = state
LS.set('plugins', plugins)
// restore Uploader & Transformer
handleRestoreState (item) {
if (item === 'uploader') {
this.$db.set('picBed.current', 'smms')
}
if (item === 'transformer') {
this.$db.set('picBed.transformer', 'path')
}
}
},
beforeDestroy () {
@ -290,6 +298,8 @@ export default {
#plugin-view
position relative
padding 0 20px 0
.el-loading-mask
background-color rgba(0, 0, 0, 0.8)
.plugin-list
height: 339px;
box-sizing: border-box;
@ -334,11 +344,13 @@ export default {
float left
width calc(100% - 72px)
height 64px
color #aaa
color #ddd
margin-left 8px
display flex
flex-direction column
justify-content space-between
&.disabled
color #aaa
&__name
font-size 16px
height 22px
@ -378,7 +390,7 @@ export default {
transition all .2s ease-in-out
&.reload
right 0px
&.installing
&.ing
right 0px
&.install
right 0px

View File

@ -65,7 +65,9 @@
</div>
</template>
<script>
import mixin from '@/utils/ConfirmButtonMixin'
export default {
mixins: [mixin],
name: 'aliyun',
data () {
return {

View File

@ -57,8 +57,10 @@
</div>
</template>
<script>
import mixin from '@/utils/ConfirmButtonMixin'
export default {
name: 'upyun',
name: 'github',
mixins: [mixin],
data () {
return {
form: {

View File

@ -37,8 +37,10 @@
</div>
</template>
<script>
import mixin from '@/utils/ConfirmButtonMixin'
export default {
name: 'imgur',
mixins: [mixin],
data () {
return {
form: {

View File

@ -75,7 +75,9 @@
</div>
</template>
<script>
import mixin from '@/utils/ConfirmButtonMixin'
export default {
mixins: [mixin],
name: 'qiniu',
data () {
return {

View File

@ -16,7 +16,9 @@
</div>
</template>
<script>
import mixin from '@/utils/ConfirmButtonMixin'
export default {
mixins: [mixin],
name: 'upyun',
data () {
return {}

View File

@ -86,7 +86,9 @@
</div>
</template>
<script>
import mixin from '@/utils/ConfirmButtonMixin'
export default {
mixins: [mixin],
name: 'tcyun',
data () {
return {

View File

@ -65,8 +65,10 @@
</div>
</template>
<script>
import mixin from '@/utils/ConfirmButtonMixin'
export default {
name: 'upyun',
mixins: [mixin],
data () {
return {
form: {

View File

@ -62,8 +62,10 @@
</div>
</template>
<script>
import mixin from '@/utils/ConfirmButtonMixin'
export default {
name: 'weibo',
mixins: [mixin],
data () {
return {
form: {

View File

@ -0,0 +1,22 @@
import db from '~/datastore'
export default {
name: '',
data () {
return {
defaultPicBed: db.read().get('picBed.current').value()
}
},
methods: {
setDefaultPicBed (type) {
db.read().set('picBed.current', type).write()
this.defaultPicBed = type
this.$electron.ipcRenderer.send('updateDefaultPicBed', type)
const successNotification = new window.Notification('设置默认图床', {
body: '设置成功'
})
successNotification.onclick = () => {
return true
}
}
}
}

View File

@ -1,13 +1,7 @@
import db from '~/datastore'
export default {
mounted () {
this.disableDragEvent()
},
data () {
return {
defaultPicBed: db.read().get('picBed.current').value()
}
},
methods: {
disableDragEvent () {
window.addEventListener('dragenter', this.disableDrag, false)
@ -21,17 +15,6 @@ export default {
e.dataTransfer.effectAllowed = 'none'
e.dataTransfer.dropEffect = 'none'
}
},
setDefaultPicBed (type) {
db.read().set('picBed.current', type).write()
this.defaultPicBed = type
this.$electron.ipcRenderer.send('updateDefaultPicBed', type)
const successNotification = new window.Notification('设置默认图床', {
body: '设置成功'
})
successNotification.onclick = () => {
return true
}
}
},
beforeDestroy () {