PicList/src/renderer/components/SettingView/Plugin.vue

372 lines
10 KiB
Vue
Raw Normal View History

2018-09-17 04:52:01 -04:00
<template>
<div id="plugin-view">
<div class="view-title">
插件设置
</div>
2018-09-28 05:31:22 -04:00
<el-row class="handle-bar" :class="{ 'cut-width': pluginList.length > 6 }">
2018-09-17 04:52:01 -04:00
<el-input
v-model="searchText"
placeholder="搜索npm上的PicGo插件"
size="small"
2018-09-28 05:31:22 -04:00
>
<i slot="suffix" class="el-input__icon el-icon-close" v-if="searchText" @click="cleanSearch" style="cursor: pointer"></i>
</el-input>
2018-09-17 04:52:01 -04:00
</el-row>
2018-09-28 05:31:22 -04:00
<el-row :gutter="10" class="plugin-list" v-loading="loading">
<el-col :span="12" v-for="(item, index) in pluginList" :key="item.name">
2018-09-17 04:52:01 -04:00
<div class="plugin-item">
2018-09-28 05:31:22 -04:00
<img class="plugin-item__logo" :src="item.logo"
onerror="this.src='static/logo.png'"
>
2018-09-17 04:52:01 -04:00
<div class="plugin-item__content">
<div class="plugin-item__name">
2018-10-10 05:25:44 -04:00
{{ item.name }} <small>{{ ' ' + item.version }}</small>
2018-09-17 04:52:01 -04:00
</div>
<div class="plugin-item__desc">
{{ item.description }}
2018-09-17 04:52:01 -04:00
</div>
<div class="plugin-item__info-bar">
<span class="plugin-item__author">
{{ item.author }}
2018-09-17 04:52:01 -04:00
</span>
<span class="plugin-item__config" >
2018-09-28 05:31:22 -04:00
<template v-if="searchText">
<template v-if="!item.hasInstall">
<span class="config-button install" v-if="!item.installing" @click="installPlugin(item)">
安装
</span>
<span v-else="item.installing" class="config-button installing">
安装中
</span>
<span class="config-button reload" v-if="item.reload" @click="reloadApp">
重启
</span>
</template>
</template>
<template v-else>
2018-09-28 05:31:22 -04:00
<span class="config-button" v-if="item.reload" @click="reloadApp">
重启
</span>
<i
class="el-icon-setting"
@click="buildContextMenu(item)"
></i>
2018-09-28 05:31:22 -04:00
</template>
2018-09-17 04:52:01 -04:00
</span>
</div>
</div>
</div>
</el-col>
</el-row>
2018-09-19 05:27:09 -04:00
<el-dialog
:visible.sync="dialogVisible"
:modal-append-to-body="false"
:title="`配置${configName}`"
width="70%"
>
<config-form
:config="config"
:type="currentType"
:name="configName"
ref="configForm"
>
</config-form>
<span slot="footer">
<el-button @click="dialogVisible = false" round>取消</el-button>
<el-button type="primary" @click="handleConfirmConfig" round>确定</el-button>
</span>
</el-dialog>
2018-09-17 04:52:01 -04:00
</div>
</template>
<script>
2018-09-19 05:27:09 -04:00
import ConfigForm from '../ConfigForm'
2018-09-28 05:31:22 -04:00
import { debounce } from 'lodash'
import mixin from '../mixin'
2018-09-17 04:52:01 -04:00
export default {
name: 'plugin',
mixins: [mixin],
2018-09-19 05:27:09 -04:00
components: {
ConfigForm
},
2018-09-17 04:52:01 -04:00
data () {
return {
searchText: '',
pluginList: [],
2018-09-19 05:27:09 -04:00
menu: null,
config: [],
currentType: '',
configName: '',
2018-09-28 05:31:22 -04:00
dialogVisible: false,
pluginNameList: [],
loading: true
}
},
computed: {
npmSearchText () {
return this.searchText.match('picgo-plugin-')
? this.searchText
: this.searchText !== ''
? `picgo-plugin-${this.searchText}`
: this.searchText
}
},
watch: {
npmSearchText (val) {
if (val) {
this.loading = true
this.getSearchResult(val)
} else {
this.getPluginList()
}
}
},
created () {
this.$electron.ipcRenderer.on('pluginList', (evt, list) => {
2018-10-09 05:11:24 -04:00
this.pluginList = list.map(item => {
item.reload = false
return item
})
2018-09-28 05:31:22 -04:00
this.pluginNameList = list.map(item => item.name)
this.loading = false
})
this.$electron.ipcRenderer.on('installSuccess', (evt, plugin) => {
this.loading = false
this.pluginList.forEach(item => {
if (item.name === plugin) {
item.installing = false
item.reload = 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.getPluginList()
2018-09-28 05:31:22 -04:00
this.getSearchResult = debounce(this.getSearchResult, 250)
},
methods: {
buildContextMenu (plugin) {
const _this = this
let menu = [{
label: '启用插件',
enabled: !plugin.enabled,
click () {
2018-09-19 05:27:09 -04:00
_this.$db.read().set(`plugins.picgo-plugin-${plugin.name}`, true).write()
plugin.enabled = true
2018-09-20 02:49:20 -04:00
// plugin.reload = true
}
}, {
label: '禁用插件',
enabled: plugin.enabled,
click () {
2018-09-19 05:27:09 -04:00
_this.$db.read().set(`plugins.picgo-plugin-${plugin.name}`, false).write()
plugin.enabled = false
2018-09-20 02:49:20 -04:00
// plugin.reload = true
}
2018-09-28 23:32:44 -04:00
}, {
label: '卸载插件',
click () {
_this.loading = true
_this.uninstallPlugin(plugin.name)
}
}]
2018-09-19 05:27:09 -04:00
for (let i in plugin.config) {
if (plugin.config[i].config.length > 0) {
const obj = {
label: `配置${i} - ${plugin.config[i].name}`,
click () {
2018-09-20 02:49:20 -04:00
_this.currentType = i
2018-09-19 05:27:09 -04:00
_this.configName = plugin.config[i].name
_this.dialogVisible = true
_this.config = plugin.config[i].config
}
}
menu.push(obj)
}
}
this.menu = this.$electron.remote.Menu.buildFromTemplate(menu)
this.menu.popup(this.$electron.remote.getCurrentWindow())
},
getPluginList () {
this.$electron.ipcRenderer.send('getPluginList')
},
installPlugin (item) {
item.installing = true
this.$electron.ipcRenderer.send('installPlugin', item.name)
2018-09-28 05:31:22 -04:00
},
2018-09-28 23:32:44 -04:00
uninstallPlugin (val) {
this.$electron.ipcRenderer.send('uninstallPlugin', val)
},
reloadApp () {
this.$electron.remote.app.relaunch()
this.$electron.remote.app.exit(0)
2018-09-19 05:27:09 -04:00
},
2018-09-28 05:31:22 -04:00
cleanSearch () {
this.searchText = ''
},
2018-09-20 02:49:20 -04:00
async handleConfirmConfig () {
const result = await this.$refs.configForm.validate()
if (result !== false) {
switch (this.currentType) {
case 'plugin':
this.$db.read().set(`picgo-plugin-${this.configName}`, result).write()
break
case 'uploader':
this.$db.read().set(`picBed.${this.configName}`, result).write()
break
case 'transformer':
this.$db.read().set(`transformer.${this.configName}`, result).write()
break
}
const successNotification = new window.Notification('设置结果', {
body: '设置成功'
})
successNotification.onclick = () => {
return true
}
this.dialogVisible = false
this.getPluginList()
}
2018-09-28 05:31:22 -04:00
},
getSearchResult: function (val) {
2018-10-12 02:56:25 -04:00
// this.$http.get(`https://api.npms.io/v2/search?q=${val}`)
this.$http.get(`https://registry.npmjs.com/-/v1/search?text=${val}`)
2018-09-28 05:31:22 -04:00
.then(res => {
2018-10-12 02:56:25 -04:00
this.pluginList = res.data.objects.map(item => {
2018-09-28 05:31:22 -04:00
return this.handleSearchResult(item)
})
this.loading = false
})
.catch(err => {
console.log(err)
this.loading = false
})
},
handleSearchResult (item) {
return {
name: item.package.name.replace(/picgo-plugin-/, ''),
author: item.package.author.name,
description: item.package.description,
logo: `https://cdn.jsdelivr.net/npm/${item.package.name}/logo.png`,
config: {},
homepage: item.package.links ? item.package.links.homepage : '',
hasInstall: this.pluginNameList.some(plugin => plugin === item.package.name.replace(/picgo-plugin-/, '')),
2018-10-10 05:25:44 -04:00
version: item.package.version,
2018-09-28 23:32:44 -04:00
installing: false,
2018-09-28 05:31:22 -04:00
reload: false
}
2018-09-17 04:52:01 -04:00
}
2018-10-09 05:11:24 -04:00
},
beforeDestroy () {
this.$electron.ipcRenderer.removeAllListeners('pluginList')
this.$electron.ipcRenderer.removeAllListeners('installSuccess')
this.$electron.ipcRenderer.removeAllListeners('uninstallSuccess')
2018-09-17 04:52:01 -04:00
}
}
</script>
<style lang='stylus'>
#plugin-view
2018-09-28 05:31:22 -04:00
position relative
2018-09-17 04:52:01 -04:00
padding 0 20px 0
2018-09-28 05:31:22 -04:00
.plugin-list
height: 339px;
box-sizing: border-box;
padding: 8px 15px;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
top: 70px;
left: 5px;
transition: all 0.2s ease-in-out 0.1s;
width: 100%
.el-loading-mask
left: 20px
width: calc(100% - 40px)
.view-title
color #eee
font-size 20px
text-align center
margin 10px auto
2018-09-17 04:52:01 -04:00
.handle-bar
margin-bottom 20px
2018-09-28 05:31:22 -04:00
&.cut-width
padding-right: 8px
2018-09-17 04:52:01 -04:00
.el-input__inner
border-radius 0
.plugin-item
box-sizing border-box
height 80px
background #444
padding 8px
user-select text
transition all .2s ease-in-out
cursor pointer
margin-bottom 10px
2018-09-17 04:52:01 -04:00
&:hover
background #333
&__logo
width 64px
height 64px
float left
&__content
float left
width calc(100% - 72px)
2018-09-17 04:52:01 -04:00
height 64px
color #aaa
margin-left 8px
display flex
flex-direction column
justify-content space-between
&__name
font-size 16px
height 22px
line-height 22px
2018-09-19 05:27:09 -04:00
// font-weight 600
font-weight 600
2018-09-17 04:52:01 -04:00
&__desc
font-size 14px
height 21px
line-height 21px
overflow hidden
text-overflow ellipsis
white-space nowrap
&__info-bar
font-size 14px
height 21px
line-height 28px
position relative
2018-09-17 04:52:01 -04:00
&__author
overflow hidden
text-overflow ellipsis
white-space nowrap
&__config
float right
font-size 16px
2018-09-28 05:31:22 -04:00
.config-button
font-size 12px
color #ddd
background #222
padding 1px 8px
height 18px
line-height 18px
text-align center
position absolute
top 4px
right 20px
2018-09-28 05:31:22 -04:00
transition all .2s ease-in-out
&.reload
right 0px
&.installing
right 0px
2018-09-28 05:31:22 -04:00
&.install
right 0px
&:hover
background: #1B9EF3
color #fff
2018-09-17 04:52:01 -04:00
</style>