📦 Chore: update electron from v6 -> v16

This commit is contained in:
PiEgg
2022-01-04 23:40:28 +08:00
parent 459953f391
commit ea20d3b971
61 changed files with 6928 additions and 5582 deletions

View File

@@ -23,7 +23,8 @@ export default class extends Vue {
this.value = true
}
}
choosePicBed (val: string) {
choosePicBed () {
this.saveConfig({
'picBed.current': this.type,
'picBed.uploader': this.type

View File

@@ -83,8 +83,9 @@ export default class extends Vue {
handleConfigChange (val: any) {
this.handleConfig(val)
}
async validate () {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
// @ts-ignore
this.$refs.form.validate((valid: boolean) => {
if (valid) {
@@ -109,7 +110,7 @@ export default class extends Vue {
return `transformer.${this.id}`
}
default:
return `unknown`
return 'unknown'
}
}
@@ -119,8 +120,10 @@ export default class extends Vue {
if (val.length > 0) {
this.configList = cloneDeep(val).map((item: any) => {
let defaultValue = item.default !== undefined
? item.default : item.type === 'checkbox'
? [] : null
? item.default
: item.type === 'checkbox'
? []
: null
if (item.type === 'checkbox') {
const defaults = item.choices.filter((i: any) => {
return i.checked

View File

@@ -15,7 +15,7 @@
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import { remote, ipcRenderer, IpcRendererEvent } from 'electron'
import { ipcRenderer, IpcRendererEvent } from 'electron'
import {
SHOW_INPUT_BOX,
SHOW_INPUT_BOX_RESPONSE
@@ -30,30 +30,36 @@ export default class extends Vue {
title: '',
placeholder: ''
}
created () {
ipcRenderer.on(SHOW_INPUT_BOX, this.ipcEventHandler)
this.$bus.$on(SHOW_INPUT_BOX, this.initInputBoxValue)
}
ipcEventHandler (evt: IpcRendererEvent, options: IShowInputBoxOption) {
this.initInputBoxValue(options)
}
initInputBoxValue (options: IShowInputBoxOption) {
this.inputBoxValue = options.value || ''
this.inputBoxOptions.title = options.title || ''
this.inputBoxOptions.placeholder = options.placeholder || ''
this.showInputBoxVisible = true
}
handleInputBoxCancel () {
// TODO: RPCServer
this.showInputBoxVisible = false
ipcRenderer.send(SHOW_INPUT_BOX, '')
this.$bus.$emit(SHOW_INPUT_BOX_RESPONSE, '')
}
handleInputBoxConfirm () {
this.showInputBoxVisible = false
ipcRenderer.send(SHOW_INPUT_BOX, this.inputBoxValue)
this.$bus.$emit(SHOW_INPUT_BOX_RESPONSE, this.inputBoxValue)
}
beforeDestroy () {
ipcRenderer.removeListener(SHOW_INPUT_BOX, this.ipcEventHandler)
this.$bus.$off(SHOW_INPUT_BOX)

View File

@@ -148,29 +148,18 @@ import { Component, Vue, Watch } from 'vue-property-decorator'
import QrcodeVue from 'qrcode.vue'
import pick from 'lodash/pick'
import pkg from 'root/package.json'
import keyDetect from '@/utils/key-binding'
import {
remote,
ipcRenderer,
IpcRendererEvent,
clipboard
} from 'electron'
// import db from '#/datastore'
import mixin from '@/utils/mixin'
import InputBoxDialog from '@/components/InputBoxDialog.vue'
import {
SHOW_PRIVACY_MESSAGE,
OPEN_DEVTOOLS
MINIMIZE_WINDOW,
CLOSE_WINDOW,
SHOW_MAIN_PAGE_MENU
} from '~/universal/events/constants'
import { IConfig } from 'picgo/dist/src/types/index'
const { Menu, dialog, BrowserWindow } = remote
const customLinkRule = (rule: string, value: string, callback: (arg0?: Error) => void) => {
if (!/\$url/.test(value)) {
return callback(new Error('必须含有$url'))
} else {
return callback()
}
}
@Component({
name: 'main-page',
mixins: [mixin],
@@ -182,7 +171,6 @@ const customLinkRule = (rule: string, value: string, callback: (arg0?: Error) =>
export default class extends Vue {
version = process.env.NODE_ENV === 'production' ? pkg.version : 'Dev'
defaultActive = 'upload'
menu: Electron.Menu | null = null
visible = false
keyBindingVisible = false
customLinkVisible = false
@@ -193,13 +181,13 @@ export default class extends Vue {
choosedPicBedForQRCode: string[] = []
created () {
this.os = process.platform
this.buildMenu()
ipcRenderer.send('getPicBeds')
ipcRenderer.on('getPicBeds', this.getPicBeds)
this.handleGetPicPeds()
}
@Watch('choosedPicBedForQRCode')
choosedPicBedForQRCodeChange (val: string[], oldVal: string[]) {
choosedPicBedForQRCodeChange (val: string[]) {
if (val.length > 0) {
this.$nextTick(async () => {
const picBedConfig = await this.getConfig('picBed')
@@ -235,77 +223,38 @@ export default class extends Vue {
}
}
}
minimizeWindow () {
const window = BrowserWindow.getFocusedWindow()
window!.minimize()
ipcRenderer.send(MINIMIZE_WINDOW)
}
closeWindow () {
const window = BrowserWindow.getFocusedWindow()
if (process.platform === 'linux') {
window!.hide()
} else {
window!.close()
}
}
buildMenu () {
const _this = this
const template = [
{
label: '关于',
click () {
dialog.showMessageBox({
title: 'PicGo',
message: 'PicGo',
detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`
})
}
},
{
label: '赞助PicGo',
click () {
_this.visible = true
}
},
{
label: '生成图床配置二维码',
click () {
_this.qrcodeVisible = true
}
},
{
label: '隐私协议',
click () {
ipcRenderer.send(SHOW_PRIVACY_MESSAGE)
}
},
{
label: '打开调试器',
click () {
ipcRenderer.send(OPEN_DEVTOOLS)
}
}
]
this.menu = Menu.buildFromTemplate(template)
ipcRenderer.send(CLOSE_WINDOW)
}
openDialog () {
// this.menu!.popup(remote.getCurrentWindow())
this.menu!.popup()
ipcRenderer.send(SHOW_MAIN_PAGE_MENU)
}
openMiniWindow () {
ipcRenderer.send('openMiniWindow')
}
handleCopyPicBedConfig () {
clipboard.writeText(this.picBedConfigString)
this.$message.success('图床配置复制成功')
}
getPicBeds (event: IpcRendererEvent, picBeds: IPicBedType[]) {
this.picBed = picBeds
}
beforeRouteEnter (to: any, from: any, next: any) {
beforeRouteEnter (to: any, next: any) {
next((vm: this) => {
vm.defaultActive = to.name
})
}
beforeDestroy () {
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)
}

View File

@@ -110,10 +110,9 @@
<script lang="ts">
// @ts-ignore
import gallerys from 'vue-gallery'
import pasteStyle from '#/utils/pasteTemplate'
import { IPasteStyle } from '#/types/enum'
import { Component, Vue, Watch } from 'vue-property-decorator'
import { IResult } from '@picgo/store/dist/types'
import { PASTE_TEXT } from '#/events/constants'
import {
ipcRenderer,
clipboard,
@@ -133,11 +132,13 @@ export default class extends Vue {
urlProperty: 'imgUrl',
closeOnSlideClick: true
}
dialogVisible = false
imgInfo = {
id: '',
imgUrl: ''
}
choosedList: IObjT<boolean> = {}
choosedPicBed: string[] = []
lastChoosed: number = -1
@@ -152,6 +153,7 @@ export default class extends Vue {
UBB: 'UBB',
Custom: 'Custom'
}
picBed: IPicBedType[] = []
@Watch('$route')
handleRouteUpdate (to: any, from: any) {
@@ -163,8 +165,9 @@ export default class extends Vue {
this.updateGallery()
}
}
async created () {
ipcRenderer.on('updateGallery', (event: IpcRendererEvent) => {
ipcRenderer.on('updateGallery', () => {
this.$nextTick(async () => {
this.updateGallery()
})
@@ -173,10 +176,12 @@ export default class extends Vue {
ipcRenderer.on('getPicBeds', this.getPicBeds)
this.updateGallery()
}
mounted () {
document.addEventListener('keydown', this.handleDetectShiftKey)
document.addEventListener('keyup', this.handleDetectShiftKey)
}
handleDetectShiftKey (event: KeyboardEvent) {
if (event.key === 'Shift') {
if (event.type === 'keydown') {
@@ -186,9 +191,11 @@ export default class extends Vue {
}
}
}
get filterList () {
return this.getGallery()
}
get isAllSelected () {
const values = Object.values(this.choosedList)
if (values.length === 0) {
@@ -199,9 +206,11 @@ export default class extends Vue {
})
}
}
getPicBeds (event: IpcRendererEvent, picBeds: IPicBedType[]) {
this.picBed = picBeds
}
getGallery (): ImgInfo[] {
if (this.searchText || this.choosedPicBed.length > 0) {
return this.images
@@ -220,6 +229,7 @@ export default class extends Vue {
return this.images
}
}
async updateGallery () {
this.images = (await this.$$db.get({ orderBy: 'desc' })).data
}
@@ -228,12 +238,13 @@ export default class extends Vue {
handleFilterListChange () {
this.clearChoosedList()
}
handleChooseImage (val: boolean, index: number) {
if (val === true) {
this.handleBarActive = true
if (this.lastChoosed !== -1 && this.isShiftKeyPress) {
let min = Math.min(this.lastChoosed, index)
let max = Math.max(this.lastChoosed, index)
const min = Math.min(this.lastChoosed, index)
const max = Math.max(this.lastChoosed, index)
for (let i = min + 1; i < max; i++) {
const id = this.filterList[i].id!
this.$set(this.choosedList, id, true)
@@ -242,6 +253,7 @@ export default class extends Vue {
this.lastChoosed = index
}
}
clearChoosedList () {
this.isShiftKeyPress = false
Object.keys(this.choosedList).forEach(key => {
@@ -249,10 +261,12 @@ export default class extends Vue {
})
this.lastChoosed = -1
}
zoomImage (index: number) {
this.idx = index
this.changeZIndexForGallery(true)
}
changeZIndexForGallery (isOpen: boolean) {
if (isOpen) {
// @ts-ignore
@@ -262,25 +276,25 @@ export default class extends Vue {
document.querySelector('.main-content.el-row').style.zIndex = 10
}
}
handleClose () {
this.idx = null
this.changeZIndexForGallery(false)
}
async copy (item: ImgInfo) {
const style = await this.getConfig<IPasteStyle>('settings.pasteStyle') || IPasteStyle.MARKDOWN
const customLink = await this.getConfig<string>('settings.customLink')
const copyLink = pasteStyle(style, item, customLink)
const copyLink = await ipcRenderer.invoke(PASTE_TEXT, item)
const obj = {
title: '复制链接成功',
body: copyLink,
icon: item.url || item.imgUrl
}
const myNotification = new Notification(obj.title, obj)
clipboard.writeText(copyLink)
myNotification.onclick = () => {
return true
}
}
remove (id: string) {
this.$confirm('此操作将把该图片移出相册, 是否继续?', '提示', {
confirmButtonText: '确定',
@@ -304,11 +318,13 @@ export default class extends Vue {
return true
})
}
openDialog (item: ImgInfo) {
this.imgInfo.id = item.id!
this.imgInfo.imgUrl = item.imgUrl as string
this.dialogVisible = true
}
async confirmModify () {
await this.$$db.updateById(this.imgInfo.id, {
imgUrl: this.imgInfo.imgUrl
@@ -325,26 +341,31 @@ export default class extends Vue {
this.dialogVisible = false
this.updateGallery()
}
choosePicBed (type: string) {
let idx = this.choosedPicBed.indexOf(type)
const idx = this.choosedPicBed.indexOf(type)
if (idx !== -1) {
this.choosedPicBed.splice(idx, 1)
} else {
this.choosedPicBed.push(type)
}
}
cleanSearch () {
this.searchText = ''
}
isMultiple (obj: IObj) {
return Object.values(obj).some(item => item)
}
toggleSelectAll () {
const result = !this.isAllSelected
this.filterList.forEach(item => {
this.$set(this.choosedList, item.id!, result)
})
}
multiRemove () {
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
const multiRemoveNumber = Object.values(this.choosedList).filter(item => item).length
@@ -354,7 +375,7 @@ export default class extends Vue {
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
let files: IResult<ImgInfo>[] = []
const files: IResult<ImgInfo>[] = []
const imageIDList = Object.keys(this.choosedList)
for (let i = 0; i < imageIDList.length; i++) {
const key = imageIDList[i]
@@ -383,11 +404,10 @@ export default class extends Vue {
})
}
}
async multiCopy () {
if (Object.values(this.choosedList).some(item => item)) {
const copyString: string[] = []
const style = await this.getConfig<IPasteStyle>('settings.pasteStyle') || IPasteStyle.MARKDOWN
const customLink = await this.getConfig<string>('settings.customLink')
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
const imageIDList = Object.keys(this.choosedList)
for (let i = 0; i < imageIDList.length; i++) {
@@ -395,7 +415,8 @@ export default class extends Vue {
if (this.choosedList[key]) {
const item = await this.$$db.getById<ImgInfo>(key)
if (item) {
copyString.push(pasteStyle(style, item, customLink))
const txt = await ipcRenderer.invoke(PASTE_TEXT, item)
copyString.push(txt)
this.choosedList[key] = false
}
}
@@ -411,9 +432,11 @@ export default class extends Vue {
}
}
}
toggleHandleBar () {
this.handleBarActive = !this.handleBarActive
}
// getPasteStyle () {
// this.pasteStyle = this.$db.get('settings.pasteStyle') || 'markdown'
// }
@@ -421,6 +444,7 @@ export default class extends Vue {
this.saveConfig('settings.pasteStyle', val)
this.pasteStyle = val
}
beforeDestroy () {
ipcRenderer.removeAllListeners('updateGallery')
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)

View File

@@ -20,10 +20,9 @@ import mixin from '@/utils/mixin'
import { Component, Vue, Watch } from 'vue-property-decorator'
import {
ipcRenderer,
IpcRendererEvent,
remote
IpcRendererEvent
} from 'electron'
import { SHOW_PRIVACY_MESSAGE, OPEN_DEVTOOLS } from '~/universal/events/constants'
import { SHOW_MINI_PAGE_MENU } from '~/universal/events/constants'
@Component({
name: 'mini-page',
mixins: [mixin]
@@ -55,6 +54,7 @@ export default class extends Vue {
})
this.getPicBeds()
}
mounted () {
window.addEventListener('mousedown', this.handleMouseDown, false)
window.addEventListener('mousemove', this.handleMouseMove, false)
@@ -73,27 +73,31 @@ export default class extends Vue {
}, 1200)
}
}
getPicBeds () {
this.picBed = ipcRenderer.sendSync('getPicBeds')
this.buildMenu()
}
onDrop (e: DragEvent) {
this.dragover = false
this.ipcSendFiles(e.dataTransfer!.files)
}
openUploadWindow () {
// @ts-ignore
document.getElementById('file-uploader').click()
}
onChange (e: any) {
this.ipcSendFiles(e.target.files)
// @ts-ignore
document.getElementById('file-uploader').value = ''
}
ipcSendFiles (files: FileList) {
let sendFiles: IFileWithPath[] = []
Array.from(files).forEach((item, index) => {
let obj = {
const sendFiles: IFileWithPath[] = []
Array.from(files).forEach((item) => {
const obj = {
name: item.name,
path: item.path
}
@@ -101,6 +105,7 @@ export default class extends Vue {
})
ipcRenderer.send('uploadChoosedFiles', sendFiles)
}
handleMouseDown (e: MouseEvent) {
this.dragging = true
this.wX = e.pageX
@@ -108,20 +113,23 @@ export default class extends Vue {
this.screenX = e.screenX
this.screenY = e.screenY
}
handleMouseMove (e: MouseEvent) {
e.preventDefault()
e.stopPropagation()
if (this.dragging) {
const xLoc = e.screenX - this.wX
const yLoc = e.screenY - this.wY
remote.BrowserWindow.getFocusedWindow()!.setBounds({
x: xLoc,
y: yLoc,
width: 64,
height: 64
})
// const xLoc = e.screenX - this.wX
// const yLoc = e.screenY - this.wY
// FIXME: drag
// remote.BrowserWindow.getFocusedWindow()!.setBounds({
// x: xLoc,
// y: yLoc,
// width: 64,
// height: 64
// })
}
}
handleMouseUp (e: MouseEvent) {
this.dragging = false
if (this.screenX === e.screenX && this.screenY === e.screenY) {
@@ -133,77 +141,11 @@ export default class extends Vue {
}
}
}
openContextMenu () {
this.menu!.popup()
}
async buildMenu () {
const _this = this
const current = await this.getConfig('picBed.current')
const submenu = this.picBed.filter(item => item.visible).map(item => {
return {
label: item.name,
type: 'radio',
checked: current === item.type,
click () {
_this.saveConfig({
'picBed.current': item.type,
'picBed.uploader': item.type
})
ipcRenderer.send('syncPicBed')
}
}
})
const template = [
{
label: '打开详细窗口',
click () {
ipcRenderer.send('openSettingWindow')
}
},
{
label: '选择默认图床',
type: 'submenu',
submenu
},
{
label: '剪贴板图片上传',
click () {
ipcRenderer.send('uploadClipboardFilesFromUploadPage')
}
},
{
label: '隐藏窗口',
click () {
remote.BrowserWindow.getFocusedWindow()!.hide()
}
},
{
label: '隐私协议',
click () {
ipcRenderer.send(SHOW_PRIVACY_MESSAGE)
}
},
{
label: '重启应用',
click () {
remote.app.relaunch()
remote.app.exit(0)
}
},
{
label: '打开调试器',
click () {
ipcRenderer.send(OPEN_DEVTOOLS)
}
},
{
role: 'quit',
label: '退出'
}
]
// @ts-ignore
this.menu = remote.Menu.buildFromTemplate(template)
ipcRenderer.send(SHOW_MINI_PAGE_MENU)
}
beforeDestroy () {
ipcRenderer.removeAllListeners('uploadProgress')
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)

View File

@@ -339,10 +339,9 @@
import keyDetect from '@/utils/key-binding'
import pkg from 'root/package.json'
import { IConfig } from 'picgo/dist/src/types/index'
import { PICGO_OPEN_FILE } from '#/events/constants'
import { PICGO_OPEN_FILE, OPEN_URL } from '#/events/constants'
import {
ipcRenderer,
remote
ipcRenderer
} from 'electron'
import { Component, Vue } from 'vue-property-decorator'
// import db from '#/datastore'
@@ -373,6 +372,7 @@ export default class extends Vue {
autoCopyUrl: true,
checkBetaUpdate: true
}
picBed: IPicBedType[] = []
logFileVisible = false
keyBindingVisible = false
@@ -383,9 +383,11 @@ export default class extends Vue {
customLink = {
value: '$url'
}
shortKey: IShortKeyMap = {
upload: ''
}
proxy = ''
npmRegistry = ''
npmProxy = ''
@@ -394,6 +396,7 @@ export default class extends Vue {
{ validator: customLinkRule, trigger: 'blur' }
]
}
logLevel = {
all: '全部-All',
success: '成功-Success',
@@ -402,11 +405,13 @@ export default class extends Vue {
warn: '提醒-Warn',
none: '不记录日志-None'
}
server = {
port: 36677,
host: '127.0.0.1',
enable: true
}
version = pkg.version
latestVersion = ''
os = ''
@@ -418,12 +423,14 @@ export default class extends Vue {
return false
}
}
created () {
this.os = process.platform
ipcRenderer.send('getPicBeds')
ipcRenderer.on('getPicBeds', this.getPicBeds)
this.initData()
}
async initData () {
const config = (await this.getConfig<IConfig>())!
if (config !== undefined) {
@@ -469,21 +476,27 @@ export default class extends Vue {
if (item.visible) {
return item.name
}
}) as string[]
return null
}).filter(item => item) as string[]
}
openFile (file: string) {
ipcRenderer.send(PICGO_OPEN_FILE, file)
}
openLogSetting () {
this.logFileVisible = true
}
keyDetect (type: string, event: KeyboardEvent) {
this.shortKey[type] = keyDetect(event).join('+')
}
async cancelCustomLink () {
this.customLinkVisible = false
this.customLink.value = await this.getConfig<string>('settings.customLink') || '$url'
}
confirmCustomLink () {
// @ts-ignore
this.$refs.customLink.validate((valid: boolean) => {
@@ -496,10 +509,12 @@ export default class extends Vue {
}
})
}
async cancelProxy () {
this.proxyVisible = false
this.proxy = await this.getConfig<string>('picBed.proxy') || ''
}
confirmProxy () {
this.proxyVisible = false
this.saveConfig({
@@ -514,12 +529,15 @@ export default class extends Vue {
return true
}
}
updateHelperChange (val: boolean) {
this.saveConfig('settings.showUpdateTip', val)
}
checkBetaUpdateChange (val: boolean) {
this.saveConfig('settings.checkBetaUpdate', val)
}
handleShowPicBedListChange (val: string[]) {
const list = this.picBed.map(item => {
if (!val.includes(item.name)) {
@@ -534,20 +552,24 @@ export default class extends Vue {
})
ipcRenderer.send('getPicBeds')
}
handleAutoStartChange (val: boolean) {
this.saveConfig('settings.autoStart', val)
ipcRenderer.send('autoStart', val)
}
handleRename (val: boolean) {
this.saveConfig({
'settings.rename': val
})
}
handleAutoRename (val: boolean) {
this.saveConfig({
'settings.autoRename': val
})
}
compareVersion2Update (current: string, latest: string) {
const currentVersion = current.split('.').map(item => parseInt(item))
const latestVersion = latest.split('.').map(item => parseInt(item))
@@ -562,6 +584,7 @@ export default class extends Vue {
}
return false
}
checkUpdate () {
this.checkUpdateVisible = true
this.$http.get(releaseUrl)
@@ -576,24 +599,29 @@ export default class extends Vue {
})
})
}
confirmCheckVersion () {
if (this.needUpdate) {
remote.shell.openExternal(downloadUrl)
ipcRenderer.send(OPEN_URL, downloadUrl)
}
this.checkUpdateVisible = false
}
cancelCheckVersion () {
this.checkUpdateVisible = false
}
handleUploadNotification (val: boolean) {
this.saveConfig({
'settings.uploadNotification': val
})
}
handleMiniWindowOntop (val: boolean) {
this.saveConfig('settings.miniWindowOntop', val)
this.$message.info('需要重启生效')
}
handleAutoCopyUrl (val: boolean) {
this.saveConfig('settings.autoCopy', val)
const successNotification = new Notification('设置自动复制链接', {
@@ -603,6 +631,7 @@ export default class extends Vue {
return true
}
}
confirmLogLevelSetting () {
if (this.form.logLevel.length === 0) {
return this.$message.error('请选择日志记录等级')
@@ -618,6 +647,7 @@ export default class extends Vue {
}
this.logFileVisible = false
}
async cancelLogLevelSetting () {
this.logFileVisible = false
let logLevel = await this.getConfig<string | string[]>('settings.logLevel')
@@ -630,6 +660,7 @@ export default class extends Vue {
}
this.form.logLevel = logLevel
}
confirmServerSetting () {
// @ts-ignore
this.server.port = parseInt(this.server.port, 10)
@@ -645,6 +676,7 @@ export default class extends Vue {
this.serverVisible = false
ipcRenderer.send('updateServer')
}
async cancelServerSetting () {
this.serverVisible = false
this.server = await this.getConfig('settings.server') || {
@@ -653,10 +685,11 @@ export default class extends Vue {
enable: true
}
}
handleLevelDisabled (val: string) {
let currentLevel = val
const currentLevel = val
let flagLevel
let result = this.form.logLevel.some(item => {
const result = this.form.logLevel.some(item => {
if (item === 'all' || item === 'none') {
flagLevel = item
}
@@ -673,12 +706,15 @@ export default class extends Vue {
}
return false
}
goConfigPage () {
remote.shell.openExternal('https://picgo.github.io/PicGo-Doc/zh/guide/config.html#picgo设置')
ipcRenderer.send(OPEN_URL, 'https://picgo.github.io/PicGo-Doc/zh/guide/config.html#picgo设置')
}
goShortCutPage () {
this.$router.push('shortKey')
}
beforeDestroy () {
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)
}

View File

@@ -109,11 +109,17 @@ import ConfigForm from '@/components/ConfigForm.vue'
import { debounce } from 'lodash'
import {
ipcRenderer,
remote,
IpcRendererEvent
} from 'electron'
import { handleStreamlinePluginName } from '~/universal/utils/common'
const { Menu } = remote
import {
OPEN_URL,
RELOAD_APP,
PICGO_CONFIG_PLUGIN,
PICGO_HANDLE_PLUGIN_ING,
PICGO_TOGGLE_PLUGIN,
SHOW_PLUGIN_PAGE_MENU
} from '#/events/constants'
@Component({
name: 'plugin',
@@ -144,6 +150,7 @@ export default class extends Vue {
? `picgo-plugin-${this.searchText}`
: this.searchText
}
@Watch('npmSearchText')
onNpmSearchTextChange (val: string) {
if (val) {
@@ -154,6 +161,7 @@ export default class extends Vue {
this.getPluginList()
}
}
@Watch('dialogVisible')
onDialogVisible (val: boolean) {
if (val) {
@@ -164,6 +172,7 @@ export default class extends Vue {
document.querySelector('.main-content.el-row').style.zIndex = 10
}
}
async created () {
this.os = process.platform
ipcRenderer.on('hideLoading', () => {
@@ -214,105 +223,45 @@ export default class extends Vue {
})
this.pluginNameList = this.pluginNameList.filter(item => item !== plugin)
})
ipcRenderer.on(PICGO_CONFIG_PLUGIN, (evt: IpcRendererEvent, currentType: string, configName: string, config: any) => {
this.currentType = currentType
this.configName = configName
this.dialogVisible = true
this.config = config
})
ipcRenderer.on(PICGO_HANDLE_PLUGIN_ING, (evt: IpcRendererEvent, fullName: string) => {
this.pluginList.forEach(item => {
if (item.fullName === fullName || (item.name === fullName)) {
item.ing = true
}
})
this.loading = true
})
ipcRenderer.on(PICGO_TOGGLE_PLUGIN, (evt: IpcRendererEvent, fullName: string, enabled: boolean) => {
const plugin = this.pluginList.find(item => item.fullName === fullName)
if (plugin) {
plugin.enabled = enabled
this.getPicBeds()
this.needReload = true
}
})
this.getPluginList()
this.getSearchResult = debounce(this.getSearchResult, 50)
this.needReload = await this.getConfig<boolean>('needReload') || false
}
async buildContextMenu (plugin: IPicGoPlugin) {
const _this = this
let menu = [{
label: '启用插件',
enabled: !plugin.enabled,
click () {
_this.saveConfig({
[`picgoPlugins.${plugin.fullName}`]: true
})
plugin.enabled = true
_this.getPicBeds()
_this.needReload = true
}
}, {
label: '禁用插件',
enabled: plugin.enabled,
click () {
_this.saveConfig({
[`picgoPlugins.${plugin.fullName}`]: false
})
plugin.enabled = false
_this.getPicBeds()
if (plugin.config.transformer.name) {
_this.handleRestoreState('transformer', plugin.config.transformer.name)
}
if (plugin.config.uploader.name) {
_this.handleRestoreState('uploader', plugin.config.uploader.name)
}
_this.needReload = true
}
}, {
label: '卸载插件',
click () {
_this.uninstallPlugin(plugin.fullName)
}
}, {
label: '更新插件',
click () {
_this.updatePlugin(plugin.fullName)
}
}]
for (let i in plugin.config) {
if (plugin.config[i].config.length > 0) {
const obj = {
label: `配置${i} - ${plugin.config[i].fullName || plugin.config[i].name}`,
click () {
_this.currentType = i
_this.configName = plugin.config[i].fullName || plugin.config[i].name
_this.dialogVisible = true
_this.config = plugin.config[i].config
},
enabled: plugin.enabled
}
menu.push(obj)
}
}
// handle transformer
if (plugin.config.transformer.name) {
let currentTransformer = await this.getConfig<string>('picBed.transformer') || 'path'
let pluginTransformer = plugin.config.transformer.name
const obj = {
label: `${currentTransformer === pluginTransformer ? '禁用' : '启用'}transformer - ${plugin.config.transformer.name}`,
click () {
_this.toggleTransformer(plugin.config.transformer.name)
}
}
menu.push(obj)
}
// plugin custom menus
if (plugin.guiMenu) {
menu.push({
// @ts-ignore
type: 'separator'
})
for (let i of plugin.guiMenu) {
menu.push({
label: i.label,
click () {
ipcRenderer.send('pluginActions', plugin.fullName, i.label)
}
})
}
}
this.menu = Menu.buildFromTemplate(menu)
this.menu.popup()
ipcRenderer.send(SHOW_PLUGIN_PAGE_MENU, plugin)
}
getPluginList () {
ipcRenderer.send('getPluginList')
}
getPicBeds () {
ipcRenderer.send('getPicBeds')
}
installPlugin (item: IPicGoPlugin) {
if (!item.gui) {
this.$confirm('该插件未对可视化界面进行优化, 是否继续安装?', '提示', {
@@ -330,6 +279,7 @@ export default class extends Vue {
ipcRenderer.send('installPlugin', item.fullName)
}
}
uninstallPlugin (val: string) {
this.pluginList.forEach(item => {
if (item.name === val) {
@@ -339,6 +289,7 @@ export default class extends Vue {
this.loading = true
ipcRenderer.send('uninstallPlugin', val)
}
updatePlugin (val: string) {
this.pluginList.forEach(item => {
if (item.fullName === val) {
@@ -348,10 +299,11 @@ export default class extends Vue {
this.loading = true
ipcRenderer.send('updatePlugin', val)
}
reloadApp () {
remote.app.relaunch()
remote.app.exit(0)
ipcRenderer.send(RELOAD_APP)
}
async handleReload () {
this.saveConfig({
needReload: true
@@ -364,21 +316,11 @@ export default class extends Vue {
this.reloadApp()
}
}
cleanSearch () {
this.searchText = ''
}
async toggleTransformer (transformer: string) {
let currentTransformer = await this.getConfig<string>('picBed.transformer') || 'path'
if (currentTransformer === transformer) {
this.saveConfig({
'picBed.transformer': 'path'
})
} else {
this.saveConfig({
'picBed.transformer': transformer
})
}
}
async handleConfirmConfig () {
// @ts-ignore
const result = await this.$refs.configForm.validate()
@@ -410,6 +352,7 @@ export default class extends Vue {
this.getPluginList()
}
}
getSearchResult (val: string) {
// this.$http.get(`https://api.npms.io/v2/search?q=${val}`)
this.$http.get(`https://registry.npmjs.com/-/v1/search?text=${val}`)
@@ -428,6 +371,7 @@ export default class extends Vue {
this.loading = false
})
}
handleSearchResult (item: INPMSearchResultObject) {
const name = handleStreamlinePluginName(item.package.name)
let gui = false
@@ -450,6 +394,7 @@ export default class extends Vue {
ing: false // installing or uninstalling
}
}
// restore Uploader & Transformer
async handleRestoreState (item: string, name: string) {
if (item === 'uploader') {
@@ -470,18 +415,26 @@ export default class extends Vue {
}
}
}
openHomepage (url: string) {
if (url) {
remote.shell.openExternal(url)
ipcRenderer.send(OPEN_URL, url)
}
}
goAwesomeList () {
remote.shell.openExternal('https://github.com/PicGo/Awesome-PicGo')
ipcRenderer.send(OPEN_URL, 'https://github.com/PicGo/Awesome-PicGo')
}
saveConfig (data: IObj) {
ipcRenderer.send('picgoSaveData', data)
}
handleImportLocalPlugin () {
ipcRenderer.send('importLocalPlugin')
this.loading = true
}
beforeDestroy () {
ipcRenderer.removeAllListeners('pluginList')
ipcRenderer.removeAllListeners('installPlugin')

View File

@@ -41,12 +41,15 @@ export default class extends Vue {
this.id = id
})
}
confirmName () {
ipcRenderer.send(`rename${this.id}`, this.fileName)
}
cancel () {
ipcRenderer.send(`rename${this.id}`, null)
}
beforeDestroy () {
ipcRenderer.removeAllListeners('rename')
}

View File

@@ -118,35 +118,43 @@ export default class extends Vue {
}
})
}
@Watch('keyBindingVisible')
onKeyBindingVisibleChange (val: boolean) {
ipcRenderer.send(TOGGLE_SHORTKEY_MODIFIED_MODE, val)
}
calcOrigin (item: string) {
const [origin] = item.split(':')
return origin
}
calcOriginShowName (item: string) {
return item.replace('picgo-plugin-', '')
}
toggleEnable (item: IShortKeyConfig) {
const status = !item.enable
item.enable = status
ipcRenderer.send('bindOrUnbindShortKey', item, item.from)
}
keyDetect (event: KeyboardEvent) {
this.shortKey = keyDetect(event).join('+')
}
async openKeyBindingDialog (config: IShortKeyConfig, index: number) {
this.command = `${config.from}:${config.name}`
this.shortKey = await this.getConfig(`settings.shortKey.${this.command}.key`) || ''
this.currentIndex = index
this.keyBindingVisible = true
}
async cancelKeyBinding () {
this.keyBindingVisible = false
this.shortKey = await this.getConfig<string>(`settings.shortKey.${this.command}.key`) || ''
}
async confirmKeyBinding () {
const oldKey = await this.getConfig<string>(`settings.shortKey.${this.command}.key`)
const config = Object.assign({}, this.list[this.currentIndex])
@@ -159,6 +167,7 @@ export default class extends Vue {
}
})
}
beforeDestroy () {
ipcRenderer.send(TOGGLE_SHORTKEY_MODIFIED_MODE, false)
}

View File

@@ -28,10 +28,9 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import mixin from '@/utils/mixin'
import pasteTemplate from '#/utils/pasteTemplate'
import { ipcRenderer, clipboard } from 'electron'
import { IPasteStyle } from '#/types/enum'
import { ipcRenderer } from 'electron'
import { IResult } from '@picgo/store/dist/types'
import { PASTE_TEXT } from '#/events/constants'
@Component({
name: 'tray-page',
@@ -44,28 +43,31 @@ export default class extends Vue {
body: '',
icon: ''
}
clipboardFiles: ImgInfo[] = []
uploadFlag = false
get reverseList () {
return this.files.slice().reverse()
}
async getData () {
this.files = (await this.$$db.get<ImgInfo>({ orderBy: 'desc', limit: 5 })).data
}
async copyTheLink (item: ImgInfo) {
this.notification.body = item.imgUrl!
this.notification.icon = item.imgUrl!
const myNotification = new Notification(this.notification.title, this.notification)
const pasteStyle = await this.getConfig<IPasteStyle>('settings.pasteStyle') || IPasteStyle.MARKDOWN
const customLink = await this.getConfig<string>('settings.customLink')
clipboard.writeText(pasteTemplate(pasteStyle, item, customLink))
ipcRenderer.invoke(PASTE_TEXT, item)
myNotification.onclick = () => {
return true
}
}
calcHeight (width: number, height: number): number {
return height * 160 / width
}
disableDragFile () {
window.addEventListener('dragover', (e) => {
e = e || event
@@ -76,6 +78,7 @@ export default class extends Vue {
e.preventDefault()
}, false)
}
uploadClipboardFiles () {
if (this.uploadFlag) {
return
@@ -83,6 +86,7 @@ export default class extends Vue {
this.uploadFlag = true
ipcRenderer.send('uploadClipboardFiles')
}
mounted () {
this.disableDragFile()
this.getData()
@@ -96,15 +100,16 @@ export default class extends Vue {
ipcRenderer.on('clipboardFiles', (event: Event, files: ImgInfo[]) => {
this.clipboardFiles = files
})
ipcRenderer.on('uploadFiles', async (event: Event) => {
ipcRenderer.on('uploadFiles', async () => {
this.files = (await this.$$db.get<ImgInfo>({ orderBy: 'desc', limit: 5 })).data
console.log(this.files)
this.uploadFlag = false
})
ipcRenderer.on('updateFiles', (event: Event) => {
ipcRenderer.on('updateFiles', () => {
this.getData()
})
}
beforeDestroy () {
ipcRenderer.removeAllListeners('dragFiles')
ipcRenderer.removeAllListeners('clipboardFiles')

View File

@@ -60,17 +60,16 @@
import { Component, Vue, Watch } from 'vue-property-decorator'
import {
ipcRenderer,
IpcRendererEvent,
remote
IpcRendererEvent
} from 'electron'
import {
SHOW_INPUT_BOX,
SHOW_INPUT_BOX_RESPONSE
SHOW_INPUT_BOX_RESPONSE,
SHOW_UPLOAD_PAGE_MENU
} from '~/universal/events/constants'
import {
isUrl
} from '~/universal/utils/common'
const { Menu } = remote
@Component({
name: 'upload'
})
@@ -82,7 +81,6 @@ export default class extends Vue {
pasteStyle = ''
picBed: IPicBedType[] = []
picBedName = ''
menu: Electron.Menu | null= null
mounted () {
ipcRenderer.on('uploadProgress', (event: IpcRendererEvent, progress: number) => {
if (progress !== -1) {
@@ -102,6 +100,7 @@ export default class extends Vue {
ipcRenderer.on('getPicBeds', this.getPicBeds)
this.$bus.$on(SHOW_INPUT_BOX_RESPONSE, this.handleInputBoxValue)
}
@Watch('progress')
onProgressChange (val: number) {
if (val === 100) {
@@ -114,12 +113,14 @@ export default class extends Vue {
}, 1200)
}
}
beforeDestroy () {
this.$bus.$off(SHOW_INPUT_BOX_RESPONSE)
ipcRenderer.removeAllListeners('uploadProgress')
ipcRenderer.removeAllListeners('syncPicBed')
ipcRenderer.removeListener('getPicBeds', this.getPicBeds)
}
onDrop (e: DragEvent) {
this.dragover = false
const items = e.dataTransfer!.items
@@ -136,6 +137,7 @@ export default class extends Vue {
this.ipcSendFiles(e.dataTransfer!.files)
}
}
handleURLDrag (items: DataTransferItemList, dataTransfer: DataTransfer) {
// text/html
// Use this data to get a more precise URL
@@ -151,17 +153,20 @@ export default class extends Vue {
this.$message.error('请拖入合法的图片文件或者图片URL地址')
}
}
openUplodWindow () {
document.getElementById('file-uploader')!.click()
}
onChange (e: any) {
this.ipcSendFiles(e.target.files);
(document.getElementById('file-uploader') as HTMLInputElement).value = ''
}
ipcSendFiles (files: FileList) {
let sendFiles: IFileWithPath[] = []
Array.from(files).forEach((item, index) => {
let obj = {
const sendFiles: IFileWithPath[] = []
Array.from(files).forEach((item) => {
const obj = {
name: item.name,
path: item.path
}
@@ -169,17 +174,21 @@ export default class extends Vue {
})
ipcRenderer.send('uploadChoosedFiles', sendFiles)
}
async getPasteStyle () {
this.pasteStyle = await this.getConfig('settings.pasteStyle') || 'markdown'
}
handlePasteStyleChange (val: string) {
this.saveConfig({
'settings.pasteStyle': val
})
}
uploadClipboardFiles () {
ipcRenderer.send('uploadClipboardFilesFromUploadPage')
}
async uploadURLFiles () {
const str = await navigator.clipboard.readText()
this.$bus.$emit(SHOW_INPUT_BOX, {
@@ -188,6 +197,7 @@ export default class extends Vue {
placeholder: 'http://或者https://开头'
})
}
handleInputBoxValue (val: string) {
if (val === '') return false
if (isUrl(val)) {
@@ -198,6 +208,7 @@ export default class extends Vue {
this.$message.error('请输入合法的URL')
}
}
async getDefaultPicBed () {
const currentPicBed = await this.getConfig<string>('picBed.current')
this.picBed.forEach(item => {
@@ -206,34 +217,14 @@ export default class extends Vue {
}
})
}
getPicBeds (event: Event, picBeds: IPicBedType[]) {
this.picBed = picBeds
this.getDefaultPicBed()
}
async handleChangePicBed () {
await this.buildMenu()
// this.menu.popup(remote.getCurrentWindow())
this.menu!.popup()
}
async buildMenu () {
const _this = this
const currentPicBed = await this.getConfig<string>('picBed.current')
const submenu = this.picBed.filter(item => item.visible).map(item => {
return {
label: item.name,
type: 'radio',
checked: currentPicBed === item.type,
click () {
_this.saveConfig({
'picBed.current': item.type,
'picBed.uploader': item.type
})
ipcRenderer.send('syncPicBed')
}
}
})
// @ts-ignore
this.menu = Menu.buildFromTemplate(submenu)
ipcRenderer.send(SHOW_UPLOAD_PAGE_MENU)
}
}
</script>

View File

@@ -86,12 +86,14 @@ export default class extends Vue {
customUrl: '',
options: ''
}
async created () {
const config = await this.getConfig<IAliYunConfig>('picBed.aliyun')
if (config) {
this.form = Object.assign({}, config)
}
}
confirm () {
// @ts-ignore
this.$refs.aliyun.validate((valid) => {

View File

@@ -71,12 +71,14 @@ export default class extends Vue {
customUrl: '',
branch: ''
}
async created () {
const config = await this.getConfig<IGitHubConfig>('picBed.github')
if (config) {
this.form = Object.assign({}, config)
}
}
confirm () {
// @ts-ignore
this.$refs.github.validate((valid) => {

View File

@@ -48,12 +48,14 @@ export default class extends Vue {
clientId: '',
proxy: ''
}
async created () {
const config = await this.getConfig<IImgurConfig>('picBed.imgur')
if (config) {
this.form = Object.assign({}, config)
}
}
confirm () {
// @ts-ignore
this.$refs.imgur.validate((valid) => {

View File

@@ -52,6 +52,7 @@ export default class extends Vue {
ipcRenderer.send('getPicBedConfig', this.$route.params.type)
ipcRenderer.on('getPicBedConfig', this.getPicBeds)
}
async handleConfirm () {
// @ts-ignore
const result = await this.$refs.configForm.validate()
@@ -67,6 +68,7 @@ export default class extends Vue {
}
}
}
setDefaultPicBed (type: string) {
this.saveConfig({
'picBed.current': type,
@@ -81,10 +83,12 @@ export default class extends Vue {
return true
}
}
getPicBeds (event: IpcRendererEvent, config: any[], name: string) {
this.config = config
this.picBedName = name
}
beforeDestroy () {
ipcRenderer.removeListener('getPicBedConfig', this.getPicBeds)
}

View File

@@ -88,12 +88,14 @@ export default class extends Vue {
options: '',
path: ''
}
async created () {
const config = await this.getConfig<IQiniuConfig>('picBed.qiniu')
if (config) {
this.form = Object.assign({}, config)
}
}
confirm () {
// @ts-ignore
this.$refs.qiniu.validate((valid) => {

View File

@@ -41,12 +41,14 @@ export default class extends Vue {
form: ISMMSConfig = {
token: ''
}
async created () {
const config = await this.getConfig<string | boolean>('picBed.smms.token')
if (typeof config !== 'boolean') {
this.form.token = config || ''
}
}
confirm () {
// @ts-ignore
this.$refs.smms.validate((valid) => {

View File

@@ -86,9 +86,10 @@
</div>
</template>
<script lang="ts">
import { ipcRenderer } from 'electron'
import { Component, Vue } from 'vue-property-decorator'
import mixin from '@/utils/ConfirmButtonMixin'
import { remote } from 'electron'
import { OPEN_URL } from '#/events/constants'
@Component({
name: 'tcyun',
mixins: [mixin]
@@ -104,12 +105,14 @@ export default class extends Vue {
customUrl: '',
version: 'v4'
}
async created () {
const config = await this.getConfig<ITcYunConfig>('picBed.tcyun')
if (config) {
this.form = Object.assign({}, config)
}
}
confirm () {
// @ts-ignore
this.$refs.tcyun.validate((valid) => {
@@ -128,8 +131,9 @@ export default class extends Vue {
}
})
}
openWiki () {
remote.shell.openExternal('https://github.com/Molunerfinn/PicGo/wiki/%E8%AF%A6%E7%BB%86%E7%AA%97%E5%8F%A3%E7%9A%84%E4%BD%BF%E7%94%A8#腾讯云cos')
ipcRenderer.send(OPEN_URL, 'https://picgo.github.io/PicGo-Doc/zh/guide/config.html#%E8%85%BE%E8%AE%AF%E4%BA%91cos')
}
}
</script>

View File

@@ -79,12 +79,14 @@ export default class extends Vue {
options: '',
path: ''
}
async created () {
const config = await this.getConfig<IUpYunConfig>('picBed.upyun')
if (config) {
this.form = Object.assign({}, config)
}
}
confirm () {
// @ts-ignore
this.$refs.tcyun.validate((valid) => {

View File

@@ -1,5 +1,4 @@
import { Component, Vue } from 'vue-property-decorator'
import { ipcRenderer } from 'electron'
import { IConfig } from 'picgo/dist/src/types'
@Component
export default class extends Vue {
@@ -10,6 +9,7 @@ export default class extends Vue {
this.defaultPicBed = config?.picBed?.uploader || config?.picBed?.current || 'smms'
}
}
setDefaultPicBed (type: string) {
this.saveConfig({
'picBed.current': type,

View File

@@ -15,26 +15,32 @@ export class GalleryDB implements IGalleryDB {
const res = await this.msgHandler<IGetResult<T>>(PICGO_GET_DB, filter)
return res
}
async insert<T> (value: T): Promise<IResult<T>> {
const res = await this.msgHandler<IResult<T>>(PICGO_INSERT_DB, value)
return res
}
async insertMany<T> (value: T[]): Promise<IResult<T>[]> {
const res = await this.msgHandler<IResult<T>[]>(PICGO_INSERT_MANY_DB, value)
return res
}
async updateById (id: string, value: IObject): Promise<boolean> {
const res = await this.msgHandler<boolean>(PICGO_UPDATE_BY_ID_DB, id, value)
return res
}
async getById<T> (id: string): Promise<IResult<T> | undefined> {
const res = await this.msgHandler<IResult<T> | undefined>(PICGO_GET_BY_ID_DB, id)
return res
}
async removeById (id: string): Promise<void> {
const res = await this.msgHandler<void>(PICGO_REMOVE_BY_ID_DB, id)
return res
}
private msgHandler<T> (method: string, ...args: any[]): Promise<T> {
return new Promise((resolve) => {
const callbackId = uuid()

View File

@@ -14,16 +14,16 @@ const isSpecialKey = (keyCode: number) => {
const keyDetect = (event: KeyboardEvent) => {
const meta = process.platform === 'darwin' ? 'Cmd' : 'Super'
let specialKey = {
const specialKey = {
Ctrl: event.ctrlKey,
Shift: event.shiftKey,
Alt: event.altKey,
[meta]: event.metaKey
}
let pressKey = []
const pressKey = []
for (let i in specialKey) {
for (const i in specialKey) {
if (specialKey[i]) {
pressKey.push(i)
}

View File

@@ -13,6 +13,7 @@ export default class extends Vue {
}
ipcRenderer.send(PICGO_SAVE_CONFIG, config)
}
getConfig<T> (key?: string): Promise<T | undefined> {
return new Promise((resolve) => {
const callbackId = uuid()

View File

@@ -4,11 +4,13 @@ export default class extends Vue {
mounted () {
this.disableDragEvent()
}
disableDragEvent () {
window.addEventListener('dragenter', this.disableDrag, false)
window.addEventListener('dragover', this.disableDrag)
window.addEventListener('drop', this.disableDrag)
}
disableDrag (e: DragEvent) {
const dropzone = document.getElementById('upload-area')
if (dropzone === null || !dropzone.contains(<Node>e.target)) {
@@ -17,6 +19,7 @@ export default class extends Vue {
e.dataTransfer!.dropEffect = 'none'
}
}
beforeDestroy () {
window.removeEventListener('dragenter', this.disableDrag, false)
window.removeEventListener('dragover', this.disableDrag)