PicList/src/main/apis/gui/index.ts

180 lines
5.1 KiB
TypeScript
Raw Normal View History

2019-01-11 04:22:33 -05:00
import {
dialog,
BrowserWindow,
2019-12-19 06:17:21 -05:00
Notification,
ipcMain
2019-01-11 04:22:33 -05:00
} from 'electron'
2021-08-01 02:50:25 -04:00
import path from 'path'
import db, { GalleryDB } from 'apis/core/datastore'
import { dbPathChecker, defaultConfigPath } from 'apis/core/datastore/dbChecker'
import uploader from 'apis/app/uploader'
2019-12-19 06:17:21 -05:00
import pasteTemplate from '#/utils/pasteTemplate'
import { handleCopyUrl } from '~/main/utils/common'
import {
getWindowId,
getSettingWindowId
} from '@core/bus/apis'
import {
SHOW_INPUT_BOX
} from '~/universal/events/constants'
2021-08-01 02:50:25 -04:00
import { DBStore } from '@picgo/store'
type PromiseResType<T> = T extends Promise<infer R> ? R : T
2019-01-11 04:22:33 -05:00
2020-04-12 10:34:45 -04:00
// Cross-process support may be required in the future
class GuiApi implements IGuiApi {
private static instance: GuiApi
private windowId: number = -1
private settingWindowId: number = -1
private constructor () {
console.log('init guiapi')
}
public static getInstance (): GuiApi {
if (!GuiApi.instance) {
GuiApi.instance = new GuiApi()
}
return GuiApi.instance
}
private async showSettingWindow () {
this.settingWindowId = await getSettingWindowId()
const settingWindow = BrowserWindow.fromId(this.settingWindowId)
if (settingWindow.isVisible()) {
return true
2019-01-11 04:22:33 -05:00
}
settingWindow.show()
return new Promise<void>((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000) // TODO: a better way to wait page loaded.
})
}
private getWebcontentsByWindowId (id: number) {
return BrowserWindow.fromId(id).webContents
}
async showInputBox (options: IShowInputBoxOption = {
title: '',
placeholder: ''
}) {
await this.showSettingWindow()
this.getWebcontentsByWindowId(this.settingWindowId)
.send(SHOW_INPUT_BOX, options)
return new Promise<string>((resolve, reject) => {
ipcMain.once(SHOW_INPUT_BOX, (event: Event, value: string) => {
2019-01-11 04:22:33 -05:00
resolve(value)
})
})
}
showFileExplorer (options: IShowFileExplorerOption = {}) {
return new Promise<string>(async (resolve, reject) => {
this.windowId = await getWindowId()
dialog.showOpenDialog(BrowserWindow.fromId(this.windowId), options, (filename: string) => {
2019-01-11 04:22:33 -05:00
resolve(filename)
})
})
}
async upload (input: IUploadOption) {
this.windowId = await getWindowId()
const webContents = this.getWebcontentsByWindowId(this.windowId)
const imgs = await uploader.setWebContents(webContents).upload(input)
2019-01-11 04:22:33 -05:00
if (imgs !== false) {
2019-09-11 07:30:08 -04:00
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
const pasteText: string[] = []
2019-12-19 06:17:21 -05:00
for (let i = 0; i < imgs.length; i++) {
2021-08-01 02:50:25 -04:00
pasteText.push(pasteTemplate(pasteStyle, imgs[i], db.get('settings.customLink')))
2019-01-11 04:22:33 -05:00
const notification = new Notification({
title: '上传成功',
2019-12-19 06:17:21 -05:00
body: imgs[i].imgUrl as string,
2019-01-11 04:22:33 -05:00
icon: imgs[i].imgUrl
})
setTimeout(() => {
notification.show()
}, i * 100)
2021-07-26 23:58:24 -04:00
await GalleryDB.getInstance().insert(imgs[i])
2019-01-11 04:22:33 -05:00
}
handleCopyUrl(pasteText.join('\n'))
webContents.send('uploadFiles', imgs)
webContents.send('updateGallery')
2019-01-11 04:22:33 -05:00
return imgs
}
return []
}
showNotification (options: IShowNotificationOption = {
2019-03-27 04:38:15 -04:00
title: '',
body: ''
}) {
const notification = new Notification({
title: options.title,
body: options.body
})
notification.show()
}
2019-03-27 04:38:15 -04:00
showMessageBox (options: IShowMessageBoxOption = {
2019-03-27 04:38:15 -04:00
title: '',
message: '',
type: 'info',
buttons: ['Yes', 'No']
}) {
return new Promise<IShowMessageBoxResult>(async (resolve, reject) => {
this.windowId = await getWindowId()
2019-03-27 04:38:15 -04:00
dialog.showMessageBox(
BrowserWindow.fromId(this.windowId),
2019-12-19 06:17:21 -05:00
options
).then((res) => {
resolve({
result: res.response,
checkboxChecked: res.checkboxChecked
2019-03-27 04:38:15 -04:00
})
2019-12-19 06:17:21 -05:00
})
2019-03-27 04:38:15 -04:00
})
}
2021-08-01 02:50:25 -04:00
/**
* get picgo config/data path
*/
async getConfigPath () {
const currentConfigPath = dbPathChecker()
const galleryDBPath = path.join(path.dirname(currentConfigPath), 'picgo.db')
return {
defaultConfigPath,
currentConfigPath,
galleryDBPath
}
}
get galleryDB (): DBStore {
return new Proxy<DBStore>(GalleryDB.getInstance(), {
get (target, prop: keyof DBStore) {
if (prop === 'removeById') {
return new Proxy(GalleryDB.getInstance().removeById, {
apply (target, ctx, args) {
return new Promise((resolve) => {
const guiApi = GuiApi.getInstance()
guiApi.showMessageBox({
title: '警告',
message: '有插件正在试图删除一些相册图片,是否继续',
type: 'info',
buttons: ['Yes', 'No']
}).then(res => {
if (res.result === 0) {
resolve(Reflect.apply(target, ctx, args))
} else {
resolve(undefined)
}
})
})
}
2021-08-01 02:50:25 -04:00
})
}
return Reflect.get(target, prop)
}
})
}
2019-01-11 04:22:33 -05:00
}
export default GuiApi