feat: 增加 PicGo 图床支持

This commit is contained in:
purocean
2021-10-23 11:22:08 +08:00
parent 1244926a4b
commit e1bb32b137
3 changed files with 122 additions and 0 deletions
+1
View File
@@ -73,6 +73,7 @@ V3 核心目标是重构代码,提升应用健壮性、可拓展性、Markdown
- 文档交叉链接跳转:支持在文档中引入其他文档,互相跳转
- 脚注功能:支持在文档中书写脚注
- 容器块:支持类似 VuePress 默认主题的自定义容器
- 图床:支持 [PicGo](https://picgo.github.io/PicGo-Doc/) 图床
- 自定义插件:支持编写 JavaScript 插件拓展编辑器功能。插件放置在 `主目录/plugins` 中,文档待完善
## 界面截图
+2
View File
@@ -38,6 +38,7 @@ import markdownEcharts from '@fe/plugins/markdown-echarts'
import markdownLuckysheet from '@fe/plugins/markdown-luckysheet'
import markdownContainer from '@fe/plugins/markdown-container'
import syncScroll from '@fe/plugins/sync-scroll'
import imageHostingPicgo from '@fe/plugins/image-hosting-picgo'
export default [
documentHistoryStack,
@@ -80,4 +81,5 @@ export default [
markdownLuckysheet,
markdownContainer,
syncScroll,
imageHostingPicgo,
]
+119
View File
@@ -0,0 +1,119 @@
import { Plugin, Ctx } from '@fe/context/plugin'
import { FLAG_DEMO } from '@fe/support/global-args'
export default {
name: 'image-hosting-picgo',
register: (ctx: Ctx) => {
const logger = ctx.utils.getLogger('plugin.image-hosting-picgo')
const uploadActionName = 'plugin.image-hosting-picgo.upload'
const settingKeyUrl = 'plugin.image-hosting-picgo.server-url'
const settingKeyPaste = 'plugin.image-hosting-picgo.enable-paste-image'
ctx.setting.tapSchema((schema) => {
schema.properties[settingKeyUrl] = {
title: 'PicGo 接口',
description: 'PicGo 默认接口地址:http://127.0.0.1:36677/upload',
type: 'string',
defaultValue: '',
pattern: '^(http://|https://|$)',
options: {
patternmessage: '必须以 http:// 开头',
inputAttributes: { placeholder: 'http://127.0.0.1:36677/upload' }
},
}
schema.properties[settingKeyPaste] = {
title: '粘贴图片使用 PicGo 图床',
type: 'boolean',
format: 'checkbox',
defaultValue: false,
}
})
ctx.action.registerAction({
name: uploadActionName,
handler: async (file: File) => {
if (FLAG_DEMO) {
ctx.ui.useToast().show('warning', 'DEMO 模式下此功能不可用')
return URL.createObjectURL(file)
}
const url = ctx.setting.getSettings()[settingKeyUrl]
if (!url) {
ctx.ui.useToast().show('warning', '请先配置 PicGo 图床接口地址')
ctx.action.getActionHandler('status-bar.show-setting')()
throw new Error('未配置 PicGo 图床上传地址')
}
ctx.ui.useToast().show('info', '上传中……')
logger.debug('upload', url, file)
const tmpFileName = 'picgo-tmp-file-' + file.name
try {
const { data: { path } } = await ctx.api.writeTmpFile(tmpFileName, await ctx.utils.fileToBase64URL(file), true)
logger.debug('tmp file', path)
const { result } = await ctx.api.proxyRequest(
url,
{
method: 'post',
body: JSON.stringify({ list: [path] }),
headers: { 'Content-Type': 'application/json' }
},
).then(r => r.json())
if (result.length > 0) {
return result[0]
}
} catch (error) {
ctx.ui.useToast().show('warning', '上传失败')
throw new Error('上传失败')
} finally {
ctx.api.deleteTmpFile(tmpFileName)
}
}
})
ctx.registerHook('ON_PASTE_IMAGE', async (file: File) => {
if (!ctx.setting.getSettings()[settingKeyPaste]) {
return false
}
await insertImage(file)
return true
})
async function insertImage (file: File) {
if (!ctx.store.state.currentFile) {
throw new Error('当前未打开文件')
}
const url = await ctx.action.getActionHandler(uploadActionName)(file)
ctx.editor.insert(`![图片](${url})\n`)
}
function addImage () {
const input = window.document.createElement('input')
input.type = 'file'
input.multiple = true
input.onchange = async () => {
for (let i = 0; i < input.files!.length; i++) {
await insertImage(input.files![i])
}
}
input.click()
}
ctx.editor.whenEditorReady().then(({ editor }) => {
editor.addAction({
id: 'plugin.image-hosting-picgo.add-image',
contextMenuGroupId: 'modification',
label: '上传图片(PicGo)',
run: addImage,
})
})
}
} as Plugin