mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-05-12 02:20:46 +08:00
Added: guiApi for plugins
This commit is contained in:
@@ -151,10 +151,11 @@ function createTray () {
|
||||
|
||||
tray.on('drop-files', async (event, files) => {
|
||||
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
|
||||
const imgs = await new Uploader(files, 'imgFromPath', window.webContents).upload()
|
||||
const imgs = await new Uploader(files, window.webContents).upload()
|
||||
if (imgs !== false) {
|
||||
for (let i in imgs) {
|
||||
clipboard.writeText(pasteTemplate(pasteStyle, imgs[i].imgUrl))
|
||||
const url = imgs[i].url || imgs[i].imgUrl
|
||||
clipboard.writeText(pasteTemplate(pasteStyle, url))
|
||||
const notification = new Notification({
|
||||
title: '上传成功',
|
||||
body: imgs[i].imgUrl,
|
||||
@@ -163,10 +164,8 @@ function createTray () {
|
||||
setTimeout(() => {
|
||||
notification.show()
|
||||
}, i * 100)
|
||||
db.read().get('uploaded').insert(imgs[i]).write()
|
||||
}
|
||||
imgs.forEach(item => {
|
||||
db.read().get('uploaded').insert(item).write()
|
||||
})
|
||||
window.webContents.send('dragFiles', imgs)
|
||||
}
|
||||
})
|
||||
@@ -332,16 +331,15 @@ const uploadClipboardFiles = async () => {
|
||||
if (img !== false) {
|
||||
if (img.length > 0) {
|
||||
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
|
||||
clipboard.writeText(pasteTemplate(pasteStyle, img[0].imgUrl))
|
||||
const url = img[0].url || img[0].imgUrl
|
||||
clipboard.writeText(pasteTemplate(pasteStyle, url))
|
||||
const notification = new Notification({
|
||||
title: '上传成功',
|
||||
body: img[0].imgUrl,
|
||||
icon: img[0].imgUrl
|
||||
})
|
||||
notification.show()
|
||||
img.forEach(item => {
|
||||
db.read().get('uploaded').insert(item).write()
|
||||
})
|
||||
db.read().get('uploaded').insert(img[0]).write()
|
||||
window.webContents.send('clipboardFiles', [])
|
||||
window.webContents.send('uploadFiles', img)
|
||||
if (settingWindow) {
|
||||
@@ -361,10 +359,11 @@ picgoCoreIPC(app, ipcMain)
|
||||
|
||||
// from macOS tray
|
||||
ipcMain.on('uploadClipboardFiles', async (evt, file) => {
|
||||
const img = await new Uploader(file, 'imgFromClipboard', window.webContents).upload()
|
||||
const img = await new Uploader(file, window.webContents).upload()
|
||||
if (img !== false) {
|
||||
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
|
||||
clipboard.writeText(pasteTemplate(pasteStyle, img[0].imgUrl))
|
||||
const url = img[0].url || img[0].imgUrl
|
||||
clipboard.writeText(pasteTemplate(pasteStyle, url))
|
||||
const notification = new Notification({
|
||||
title: '上传成功',
|
||||
body: img[0].imgUrl,
|
||||
@@ -372,9 +371,7 @@ ipcMain.on('uploadClipboardFiles', async (evt, file) => {
|
||||
icon: img[0].imgUrl
|
||||
})
|
||||
notification.show()
|
||||
img.forEach(item => {
|
||||
db.read().get('uploaded').insert(item).write()
|
||||
})
|
||||
db.read().get('uploaded').insert(img[0]).write()
|
||||
window.webContents.send('clipboardFiles', [])
|
||||
window.webContents.send('uploadFiles')
|
||||
if (settingWindow) {
|
||||
@@ -389,12 +386,13 @@ ipcMain.on('uploadClipboardFilesFromUploadPage', () => {
|
||||
|
||||
ipcMain.on('uploadChoosedFiles', async (evt, files) => {
|
||||
const input = files.map(item => item.path)
|
||||
const imgs = await new Uploader(input, 'imgFromUploader', evt.sender).upload()
|
||||
const imgs = await new Uploader(input, evt.sender).upload()
|
||||
if (imgs !== false) {
|
||||
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
|
||||
let pasteText = ''
|
||||
for (let i in imgs) {
|
||||
pasteText += pasteTemplate(pasteStyle, imgs[i].imgUrl) + '\r\n'
|
||||
const url = imgs[i].url || imgs[i].imgUrl
|
||||
pasteText += pasteTemplate(pasteStyle, url) + '\r\n'
|
||||
const notification = new Notification({
|
||||
title: '上传成功',
|
||||
body: imgs[i].imgUrl,
|
||||
@@ -403,11 +401,9 @@ ipcMain.on('uploadChoosedFiles', async (evt, files) => {
|
||||
setTimeout(() => {
|
||||
notification.show()
|
||||
}, i * 100)
|
||||
db.read().get('uploaded').insert(imgs[i]).write()
|
||||
}
|
||||
clipboard.writeText(pasteText)
|
||||
imgs.forEach(item => {
|
||||
db.read().get('uploaded').insert(item).write()
|
||||
})
|
||||
window.webContents.send('uploadFiles', imgs)
|
||||
if (settingWindow) {
|
||||
settingWindow.webContents.send('updateGallery')
|
||||
|
||||
85
src/main/utils/guiApi.js
Normal file
85
src/main/utils/guiApi.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import {
|
||||
dialog,
|
||||
BrowserWindow,
|
||||
clipboard,
|
||||
Notification
|
||||
} from 'electron'
|
||||
import db from '../../datastore'
|
||||
import Uploader from './uploader'
|
||||
import pasteTemplate from './pasteTemplate'
|
||||
const WEBCONTENTS = Symbol('WEBCONTENTS')
|
||||
const IPCMAIN = Symbol('IPCMAIN')
|
||||
|
||||
class GuiApi {
|
||||
constructor (ipcMain, webcontents) {
|
||||
this[WEBCONTENTS] = webcontents
|
||||
this[IPCMAIN] = ipcMain
|
||||
}
|
||||
|
||||
/**
|
||||
* for plugin showInputBox
|
||||
* @param {object} options
|
||||
* return type is string or ''
|
||||
*/
|
||||
showInputBox (options) {
|
||||
if (options === undefined) {
|
||||
options = {
|
||||
title: '',
|
||||
placeholder: ''
|
||||
}
|
||||
}
|
||||
this[WEBCONTENTS].send('showInputBox', options)
|
||||
return new Promise((resolve, reject) => {
|
||||
this[IPCMAIN].once('showInputBox', (event, value) => {
|
||||
resolve(value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* for plugin show file explorer
|
||||
* @param {object} options
|
||||
*/
|
||||
showFileExplorer (options) {
|
||||
if (options === undefined) {
|
||||
options = {}
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
dialog.showOpenDialog(BrowserWindow.fromWebContents(this[WEBCONTENTS]), options, filename => {
|
||||
resolve(filename)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* for plugin to upload file
|
||||
* @param {array} input
|
||||
*/
|
||||
async upload (input) {
|
||||
const imgs = await new Uploader(input, this[WEBCONTENTS]).upload()
|
||||
if (imgs !== false) {
|
||||
const pasteStyle = db.read().get('settings.pasteStyle').value() || 'markdown'
|
||||
let pasteText = ''
|
||||
for (let i in imgs) {
|
||||
const url = imgs[i].url || imgs[i].imgUrl
|
||||
pasteText += pasteTemplate(pasteStyle, url) + '\r\n'
|
||||
const notification = new Notification({
|
||||
title: '上传成功',
|
||||
body: imgs[i].imgUrl,
|
||||
icon: imgs[i].imgUrl
|
||||
})
|
||||
setTimeout(() => {
|
||||
notification.show()
|
||||
}, i * 100)
|
||||
db.read().get('uploaded').insert(imgs[i]).write()
|
||||
}
|
||||
clipboard.writeText(pasteText)
|
||||
this[WEBCONTENTS].send('uploadFiles', imgs)
|
||||
this[WEBCONTENTS].send('updateGallery')
|
||||
return imgs
|
||||
}
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export default GuiApi
|
||||
@@ -1,4 +1,5 @@
|
||||
import path from 'path'
|
||||
import GuiApi from './guiApi'
|
||||
|
||||
// eslint-disable-next-line
|
||||
const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
|
||||
@@ -50,6 +51,7 @@ const handleGetPluginList = (ipcMain, STORE_PATH, CONFIG_PATH) => {
|
||||
description: pluginPKG.description,
|
||||
logo: 'file://' + path.join(pluginPath, 'logo.png').split(path.sep).join('/'),
|
||||
version: pluginPKG.version,
|
||||
gui: pluginPKG.gui || false,
|
||||
config: {
|
||||
plugin: {
|
||||
name: pluginList[i].replace(/picgo-plugin-/, ''),
|
||||
@@ -66,6 +68,7 @@ const handleGetPluginList = (ipcMain, STORE_PATH, CONFIG_PATH) => {
|
||||
},
|
||||
enabled: picgo.getConfig(`plugins.${pluginList[i]}`),
|
||||
homepage: pluginPKG.homepage ? pluginPKG.homepage : '',
|
||||
guiActions: typeof plugin.guiActions === 'function',
|
||||
ing: false
|
||||
}
|
||||
list.push(obj)
|
||||
@@ -125,6 +128,17 @@ const handleGetPicBedConfig = (ipcMain, CONFIG_PATH) => {
|
||||
})
|
||||
}
|
||||
|
||||
const handlePluginActions = (ipcMain, CONFIG_PATH) => {
|
||||
ipcMain.on('pluginActions', (event, name) => {
|
||||
const picgo = new PicGo(CONFIG_PATH)
|
||||
const plugin = picgo.pluginLoader.getPlugin(`picgo-plugin-${name}`)
|
||||
const guiApi = new GuiApi(ipcMain, event.sender)
|
||||
if (plugin.guiActions && typeof plugin.guiActions === 'function') {
|
||||
plugin.guiActions(picgo, guiApi)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default (app, ipcMain) => {
|
||||
const STORE_PATH = app.getPath('userData')
|
||||
const CONFIG_PATH = path.join(STORE_PATH, '/data.json')
|
||||
@@ -133,4 +147,5 @@ export default (app, ipcMain) => {
|
||||
handlePluginUninstall(ipcMain, CONFIG_PATH)
|
||||
handlePluginUpdate(ipcMain, CONFIG_PATH)
|
||||
handleGetPicBedConfig(ipcMain, CONFIG_PATH)
|
||||
handlePluginActions(ipcMain, CONFIG_PATH)
|
||||
}
|
||||
|
||||
@@ -75,9 +75,8 @@ const waitForRename = (window, id) => {
|
||||
}
|
||||
|
||||
class Uploader {
|
||||
constructor (img, type, webContents) {
|
||||
constructor (img, webContents) {
|
||||
this.img = img
|
||||
this.type = type
|
||||
this.webContents = webContents
|
||||
}
|
||||
|
||||
@@ -142,7 +141,11 @@ class Uploader {
|
||||
}
|
||||
})
|
||||
picgo.on('failed', ctx => {
|
||||
console.log(ctx)
|
||||
const notification = new Notification({
|
||||
title: '上传失败',
|
||||
body: '请检查配置和上传的文件是否符合要求'
|
||||
})
|
||||
notification.show()
|
||||
resolve(false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
>
|
||||
</div>
|
||||
<div class="gallery-list__tool-panel">
|
||||
<i class="el-icon-document" @click="copy(item.imgUrl)"></i>
|
||||
<i class="el-icon-document" @click="copy(item)"></i>
|
||||
<i class="el-icon-edit-outline" @click="openDialog(item)"></i>
|
||||
<i class="el-icon-delete" @click="remove(item.id)"></i>
|
||||
<el-checkbox v-model="choosedList[item.id]" class="pull-right" @change=" handleBarActive = true"></el-checkbox>
|
||||
@@ -208,7 +208,8 @@ export default {
|
||||
this.idx = null
|
||||
this.changeZIndexForGallery(false)
|
||||
},
|
||||
copy (url) {
|
||||
copy (item) {
|
||||
const url = item.url || item.imgUrl
|
||||
const style = this.$db.read().get('settings.pasteStyle').value() || 'markdown'
|
||||
const copyLink = pasteStyle(style, url)
|
||||
const obj = {
|
||||
@@ -313,7 +314,9 @@ export default {
|
||||
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
|
||||
Object.keys(this.choosedList).forEach(key => {
|
||||
if (this.choosedList[key]) {
|
||||
copyString += pasteStyle(style, this.$db.read().get('uploaded').getById(key).value().imgUrl) + '\n'
|
||||
const item = this.$db.read().get('uploaded').getById(key).value()
|
||||
const url = item.url || item.imgUrl
|
||||
copyString += pasteStyle(style, url) + '\n'
|
||||
this.choosedList[key] = false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<el-row :gutter="10" class="plugin-list" v-loading="loading">
|
||||
<el-col :span="12" v-for="item in pluginList" :key="item.name">
|
||||
<div class="plugin-item" :class="{ 'darwin': os === 'darwin' }">
|
||||
<div class="cli-only-badge" v-if="!item.gui" title="CLI only">CLI</div>
|
||||
<img class="plugin-item__logo" :src="item.logo"
|
||||
onerror="this.src='static/logo.png'"
|
||||
>
|
||||
@@ -90,6 +91,20 @@
|
||||
<el-button type="primary" @click="handleConfirmConfig" round>确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
:title="inputBoxOptions.title || '输入框'"
|
||||
:visible.sync="showInputBoxVisible"
|
||||
:modal-append-to-body="false"
|
||||
@close="handleInputBoxClose"
|
||||
>
|
||||
<el-input
|
||||
v-model="inputBoxValue"
|
||||
:placeholder="inputBoxOptions.placeholder"></el-input>
|
||||
<span slot="footer">
|
||||
<el-button @click="showInputBoxVisible = false" round>取消</el-button>
|
||||
<el-button type="primary" @click="showInputBoxVisible = false" round>确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -113,7 +128,14 @@ export default {
|
||||
loading: true,
|
||||
needReload: false,
|
||||
id: '',
|
||||
os: ''
|
||||
os: '',
|
||||
// for showInputBox
|
||||
showInputBoxVisible: false,
|
||||
inputBoxValue: '',
|
||||
inputBoxOptions: {
|
||||
title: '',
|
||||
placeholder: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -183,6 +205,12 @@ export default {
|
||||
this.getPluginList()
|
||||
this.getSearchResult = debounce(this.getSearchResult, 50)
|
||||
this.needReload = this.$db.read().get('needReload').value()
|
||||
this.$electron.ipcRenderer.on('showInputBox', (evt, options) => {
|
||||
this.inputBoxValue = ''
|
||||
this.inputBoxOptions.title = options.title || ''
|
||||
this.inputBoxOptions.placeholder = options.placeholder || ''
|
||||
this.showInputBoxVisible = true
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
buildContextMenu (plugin) {
|
||||
@@ -247,6 +275,16 @@ export default {
|
||||
}
|
||||
menu.push(obj)
|
||||
}
|
||||
|
||||
if (plugin.guiActions) {
|
||||
menu.push({
|
||||
label: '运行Actions',
|
||||
click () {
|
||||
_this.$electron.ipcRenderer.send('pluginActions', plugin.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.menu = this.$electron.remote.Menu.buildFromTemplate(menu)
|
||||
this.menu.popup(this.$electron.remote.getCurrentWindow())
|
||||
},
|
||||
@@ -257,8 +295,21 @@ export default {
|
||||
this.$electron.ipcRenderer.send('getPicBeds')
|
||||
},
|
||||
installPlugin (item) {
|
||||
item.ing = true
|
||||
this.$electron.ipcRenderer.send('installPlugin', item.name)
|
||||
if (!item.gui) {
|
||||
this.$confirm('该插件未对可视化界面进行优化, 是否继续安装?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
item.ing = true
|
||||
this.$electron.ipcRenderer.send('installPlugin', item.name)
|
||||
}).catch(() => {
|
||||
console.log('Install canceled')
|
||||
})
|
||||
} else {
|
||||
item.ing = true
|
||||
this.$electron.ipcRenderer.send('installPlugin', item.name)
|
||||
}
|
||||
},
|
||||
uninstallPlugin (val) {
|
||||
this.pluginList.forEach(item => {
|
||||
@@ -350,6 +401,7 @@ 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,
|
||||
gui: item.package.gui || false,
|
||||
ing: false // installing or uninstalling
|
||||
}
|
||||
},
|
||||
@@ -372,6 +424,9 @@ export default {
|
||||
if (url) {
|
||||
this.$electron.remote.shell.openExternal(url)
|
||||
}
|
||||
},
|
||||
handleInputBoxClose () {
|
||||
this.$electron.ipcRenderer.send('showInputBox', this.inputBoxValue)
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
@@ -379,6 +434,7 @@ export default {
|
||||
this.$electron.ipcRenderer.removeAllListeners('installSuccess')
|
||||
this.$electron.ipcRenderer.removeAllListeners('uninstallSuccess')
|
||||
this.$electron.ipcRenderer.removeAllListeners('updateSuccess')
|
||||
this.$electron.ipcRenderer.removeAllListeners('showInputBox')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -422,6 +478,15 @@ $darwinBg = #172426
|
||||
user-select text
|
||||
transition all .2s ease-in-out
|
||||
margin-bottom 10px
|
||||
position relative
|
||||
.cli-only-badge
|
||||
position absolute
|
||||
right 0px
|
||||
top 0
|
||||
font-size 12px
|
||||
padding 3px 8px
|
||||
background #49B1F5
|
||||
color #eee
|
||||
&.darwin
|
||||
background transparentify($darwinBg, #000, 0.75)
|
||||
&:hover
|
||||
|
||||
Reference in New Issue
Block a user