mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-22 22:21:09 +08:00
168 lines
4.3 KiB
JavaScript
168 lines
4.3 KiB
JavaScript
import Vditor from 'vditor'
|
||
import 'vditor/dist/index.css'
|
||
import { API_BASE_URL } from '../main'
|
||
import { getToken, authState } from './auth'
|
||
import { searchUsers, fetchFollowings, fetchAdmins } from './user'
|
||
|
||
export function getEditorTheme() {
|
||
return document.documentElement.dataset.theme === 'dark' ? 'dark' : 'classic'
|
||
}
|
||
|
||
export function getPreviewTheme() {
|
||
return document.documentElement.dataset.theme === 'dark' ? 'dark' : 'light'
|
||
}
|
||
|
||
export function createVditor(editorId, options = {}) {
|
||
const {
|
||
placeholder = '',
|
||
preview = {},
|
||
input,
|
||
after
|
||
} = options
|
||
|
||
const fetchMentions = async (value) => {
|
||
if (!value) {
|
||
const [followings, admins] = await Promise.all([
|
||
fetchFollowings(authState.username),
|
||
fetchAdmins()
|
||
])
|
||
const combined = [...followings, ...admins]
|
||
const seen = new Set()
|
||
return combined.filter(u => {
|
||
if (seen.has(u.id)) return false
|
||
seen.add(u.id)
|
||
return true
|
||
})
|
||
}
|
||
return searchUsers(value)
|
||
}
|
||
|
||
let vditor
|
||
vditor = new Vditor(editorId, {
|
||
placeholder,
|
||
height: 'auto',
|
||
theme: getEditorTheme(),
|
||
preview: Object.assign({ theme: { current: getPreviewTheme() } }, preview),
|
||
hint: {
|
||
extend: [
|
||
{
|
||
key: '@',
|
||
hint: async (key) => {
|
||
const list = await fetchMentions(key)
|
||
return list.map(u => ({
|
||
value: `@[${u.username}]`,
|
||
html: `<img src="${u.avatar}" /> @${u.username}`
|
||
}))
|
||
},
|
||
},
|
||
],
|
||
},
|
||
cdn: 'https://openisle-1307107697.cos.ap-guangzhou.myqcloud.com/assert/vditor',
|
||
toolbar: [
|
||
'emoji',
|
||
'bold',
|
||
'italic',
|
||
'strike',
|
||
'|',
|
||
'list',
|
||
'line',
|
||
'quote',
|
||
'code',
|
||
'inline-code',
|
||
'|',
|
||
'undo',
|
||
'redo',
|
||
'|',
|
||
'link',
|
||
'upload'
|
||
],
|
||
upload: {
|
||
accept: 'image/*,video/*',
|
||
multiple: false,
|
||
handler: async (files) => {
|
||
const file = files[0]
|
||
vditor.tip('å›¾ç‰‡ä¸Šä¼ ä¸', 0)
|
||
vditor.disabled()
|
||
const res = await fetch(
|
||
`${API_BASE_URL}/api/upload/presign?filename=${encodeURIComponent(file.name)}`,
|
||
{ headers: { Authorization: `Bearer ${getToken()}` } }
|
||
)
|
||
if (!res.ok) {
|
||
vditor.enable()
|
||
vditor.tip('获å<C2B7>–ä¸Šä¼ åœ°å<C2B0>€å¤±è´¥')
|
||
return '获å<C2B7>–ä¸Šä¼ åœ°å<C2B0>€å¤±è´¥'
|
||
}
|
||
const info = await res.json()
|
||
const put = await fetch(info.uploadUrl, { method: 'PUT', body: file })
|
||
if (!put.ok) {
|
||
vditor.enable()
|
||
vditor.tip('ä¸Šä¼ å¤±è´¥')
|
||
return 'ä¸Šä¼ å¤±è´¥'
|
||
}
|
||
|
||
const ext = file.name.split('.').pop().toLowerCase()
|
||
const imageExts = [
|
||
'apng',
|
||
'bmp',
|
||
'gif',
|
||
'ico',
|
||
'cur',
|
||
'jpg',
|
||
'jpeg',
|
||
'jfif',
|
||
'pjp',
|
||
'pjpeg',
|
||
'png',
|
||
'svg',
|
||
'webp'
|
||
]
|
||
const audioExts = ['wav', 'mp3', 'ogg']
|
||
let md
|
||
if (imageExts.includes(ext)) {
|
||
md = ``
|
||
} else if (audioExts.includes(ext)) {
|
||
md = `<audio controls="controls" src="${info.fileUrl}"></audio>`
|
||
} else {
|
||
md = `[${file.name}](${info.fileUrl})`
|
||
}
|
||
vditor.insertValue(md + '\n')
|
||
vditor.enable()
|
||
vditor.tip('ä¸Šä¼ æˆ<C3A6>功')
|
||
return null
|
||
}
|
||
},
|
||
// upload: {
|
||
// fieldName: 'file',
|
||
// url: `${API_BASE_URL}/api/upload`,
|
||
// accept: 'image/*,video/*',
|
||
// multiple: false,
|
||
// headers: { Authorization: `Bearer ${getToken()}` },
|
||
// format(files, responseText) {
|
||
// const res = JSON.parse(responseText)
|
||
// if (res.code === 0) {
|
||
// return JSON.stringify({
|
||
// code: 0,
|
||
// msg: '',
|
||
// data: {
|
||
// errFiles: [],
|
||
// succMap: { [files[0].name]: res.data.url }
|
||
// }
|
||
// })
|
||
// } else {
|
||
// return JSON.stringify({
|
||
// code: 1,
|
||
// msg: 'ä¸Šä¼ å¤±è´¥',
|
||
// data: { errFiles: files.map(f => f.name), succMap: {} }
|
||
// })
|
||
// }
|
||
// }
|
||
// },
|
||
toolbarConfig: { pin: true },
|
||
cache: { enable: false },
|
||
input,
|
||
after
|
||
})
|
||
|
||
return vditor
|
||
}
|