You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
2.8 KiB
128 lines
2.8 KiB
interface BuildVditorOptionsInput {
|
|
value: string
|
|
isMobile: boolean
|
|
onInput: (value: string) => void
|
|
onUploadError: () => void
|
|
onEditorReady?: () => void
|
|
}
|
|
|
|
const DESKTOP_TOOLBAR: ReadonlyArray<string> = [
|
|
'emoji',
|
|
'headings',
|
|
'bold',
|
|
'italic',
|
|
'strike',
|
|
'|',
|
|
'line',
|
|
'list',
|
|
'ordered-list',
|
|
'check',
|
|
'quote',
|
|
'|',
|
|
'code',
|
|
'inline-code',
|
|
'insert-before',
|
|
'insert-after',
|
|
'|',
|
|
'upload',
|
|
'link',
|
|
'table',
|
|
'|',
|
|
'undo',
|
|
'redo',
|
|
'|',
|
|
'fullscreen',
|
|
'edit-mode',
|
|
]
|
|
|
|
const MOBILE_TOOLBAR: ReadonlyArray<string> = [
|
|
'bold',
|
|
'italic',
|
|
'headings',
|
|
'|',
|
|
'list',
|
|
'ordered-list',
|
|
'|',
|
|
'link',
|
|
'upload',
|
|
'code',
|
|
'|',
|
|
'preview',
|
|
]
|
|
|
|
export function buildPostBodyMarkdownEditorVditorOptions(input: BuildVditorOptionsInput): Record<string, unknown> {
|
|
return {
|
|
value: input.value,
|
|
lang: 'zh_CN',
|
|
cdn: '/vditor',
|
|
icon: 'material',
|
|
cache: { enable: false },
|
|
mode: 'ir',
|
|
preview: {
|
|
mode: 'editor',
|
|
actions: [] as string[],
|
|
},
|
|
toolbar: input.isMobile ? MOBILE_TOOLBAR : DESKTOP_TOOLBAR,
|
|
upload: {
|
|
url: '/api/file/upload',
|
|
fieldName: 'file',
|
|
multiple: true,
|
|
accept: 'image/*',
|
|
format(files: File[], responseText: string) {
|
|
try {
|
|
const parsed = JSON.parse(responseText) as {
|
|
files?: Array<{ url?: string }>
|
|
data?: { files?: Array<{ url?: string }> }
|
|
}
|
|
const nestedFiles = parsed?.data?.files
|
|
const rootFiles = parsed?.files
|
|
const uploaded = Array.isArray(nestedFiles)
|
|
? nestedFiles
|
|
: (Array.isArray(rootFiles) ? rootFiles : [])
|
|
const succMap: Record<string, string> = {}
|
|
uploaded.forEach((item, index) => {
|
|
const url = item?.url?.trim()
|
|
if (!url) {
|
|
return
|
|
}
|
|
const fallbackName = `upload-${index + 1}`
|
|
const sourceName = files[index]?.name?.trim() || fallbackName
|
|
succMap[sourceName] = url
|
|
})
|
|
return JSON.stringify({
|
|
msg: '',
|
|
code: 0,
|
|
data: {
|
|
errFiles: [] as string[],
|
|
succMap,
|
|
},
|
|
})
|
|
}
|
|
catch {
|
|
return JSON.stringify({
|
|
msg: 'upload response parse failed',
|
|
code: 1,
|
|
data: {
|
|
errFiles: [] as string[],
|
|
succMap: {} as Record<string, string>,
|
|
},
|
|
})
|
|
}
|
|
},
|
|
error() {
|
|
input.onUploadError()
|
|
},
|
|
},
|
|
input(value: string) {
|
|
input.onInput(value)
|
|
},
|
|
after() {
|
|
input.onEditorReady?.()
|
|
},
|
|
}
|
|
}
|
|
|
|
export const postBodyMarkdownEditorToolbarPresets = {
|
|
desktop: DESKTOP_TOOLBAR,
|
|
mobile: MOBILE_TOOLBAR,
|
|
}
|
|
|