mirror of https://github.com/halo-dev/halo-admin
chore: use @halo-dev/editor instead of halo-editor (#447)
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/450/head
parent
e12c56e352
commit
e8275370c4
|
@ -25,13 +25,13 @@
|
||||||
"@codemirror/lang-html": "^0.19.4",
|
"@codemirror/lang-html": "^0.19.4",
|
||||||
"@codemirror/lang-java": "^0.19.1",
|
"@codemirror/lang-java": "^0.19.1",
|
||||||
"@halo-dev/admin-api": "^1.0.0-alpha.48",
|
"@halo-dev/admin-api": "^1.0.0-alpha.48",
|
||||||
|
"@halo-dev/editor": "^3.0.0-alpha.0",
|
||||||
"ant-design-vue": "^1.7.8",
|
"ant-design-vue": "^1.7.8",
|
||||||
"dayjs": "^1.10.7",
|
"dayjs": "^1.10.7",
|
||||||
"enquire.js": "^2.1.6",
|
"enquire.js": "^2.1.6",
|
||||||
"filepond": "^4.30.3",
|
"filepond": "^4.30.3",
|
||||||
"filepond-plugin-file-validate-type": "^1.2.6",
|
"filepond-plugin-file-validate-type": "^1.2.6",
|
||||||
"filepond-plugin-image-preview": "^4.6.10",
|
"filepond-plugin-image-preview": "^4.6.10",
|
||||||
"halo-editor": "^2.8.4",
|
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
"marked": "^4.0.10",
|
"marked": "^4.0.10",
|
||||||
"md5.js": "^1.3.5",
|
"md5.js": "^1.3.5",
|
||||||
|
|
811
pnpm-lock.yaml
811
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -1,30 +1,30 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="h-full">
|
<div class="h-full">
|
||||||
<halo-editor
|
<halo-editor
|
||||||
ref="md"
|
ref="editor"
|
||||||
v-model="originalContentData"
|
v-model="originalContentData"
|
||||||
:boxShadow="false"
|
:boxShadow="false"
|
||||||
:ishljs="true"
|
:toolbars="markdownEditorToolbars"
|
||||||
:toolbars="toolbars"
|
:uploadRequest="handleAttachmentUpload"
|
||||||
autofocus
|
autofocus
|
||||||
@imgAdd="handleAttachmentUpload"
|
@change="handleChange"
|
||||||
@openImagePicker="attachmentSelectVisible = true"
|
@openImagePicker="attachmentSelectVisible = true"
|
||||||
@save="handleSaveDraft"
|
@save="handleSave"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AttachmentSelectModal :visible.sync="attachmentSelectVisible" @confirm="handleSelectAttachment" />
|
<AttachmentSelectModal :visible.sync="attachmentSelectVisible" @confirm="handleSelectAttachment" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { toolbars } from '@/core/const'
|
import haloEditor from '@halo-dev/editor'
|
||||||
import { haloEditor } from 'halo-editor'
|
import '@halo-dev/editor/dist/lib/style.css'
|
||||||
import 'halo-editor/dist/css/index.css'
|
|
||||||
import apiClient from '@/utils/api-client'
|
import apiClient from '@/utils/api-client'
|
||||||
|
import { markdownEditorToolbars } from '@/core/constant'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MarkdownEditor',
|
name: 'MarkdownEditor',
|
||||||
components: {
|
components: {
|
||||||
haloEditor
|
haloEditor: haloEditor.editor
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
originalContent: {
|
originalContent: {
|
||||||
|
@ -35,39 +35,50 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
toolbars,
|
markdownEditorToolbars,
|
||||||
originalContentData: '',
|
|
||||||
attachmentSelectVisible: false
|
attachmentSelectVisible: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
computed: {
|
||||||
originalContent(val) {
|
originalContentData: {
|
||||||
this.originalContentData = val
|
get() {
|
||||||
},
|
return this.originalContent
|
||||||
originalContentData(val) {
|
},
|
||||||
this.$emit('onContentChange', val)
|
set(value) {
|
||||||
|
this.$emit('update:originalContent', value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async handleAttachmentUpload(pos, $file) {
|
handleAttachmentUpload(file) {
|
||||||
try {
|
return new Promise((resolve, reject) => {
|
||||||
const response = await apiClient.attachment.upload($file)
|
const hideLoading = this.$message.loading('上传中...', 0)
|
||||||
const responseObject = response.data
|
apiClient.attachment
|
||||||
const HaloEditor = this.$refs.md
|
.upload(file)
|
||||||
HaloEditor.$img2Url(pos, encodeURI(responseObject.path))
|
.then(response => {
|
||||||
} catch (e) {
|
const attachment = response.data
|
||||||
this.$log.error('update image error: ', e)
|
resolve({
|
||||||
}
|
name: attachment.name,
|
||||||
},
|
path: encodeURI(attachment.path)
|
||||||
handleSelectAttachment({ markdown }) {
|
})
|
||||||
this.$refs.md.insertText(this.$refs.md.getTextareaDom(), {
|
})
|
||||||
prefix: '',
|
.catch(e => {
|
||||||
subfix: '',
|
this.$log.error('upload image error: ', e)
|
||||||
str: markdown.join('\n')
|
reject(e)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hideLoading()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleSaveDraft() {
|
handleSelectAttachment({ markdown }) {
|
||||||
this.$emit('onSaveDraft')
|
this.$refs.editor.insetAtCursor(markdown.join('\n'))
|
||||||
|
},
|
||||||
|
handleSave() {
|
||||||
|
this.$emit('save')
|
||||||
|
},
|
||||||
|
handleChange({ originalContent, renderContent }) {
|
||||||
|
this.$emit('change', { originalContent, renderContent })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
const toolbars = {
|
|
||||||
bold: true, // 粗体
|
|
||||||
italic: true, // 斜体
|
|
||||||
header: true, // 标题
|
|
||||||
underline: true, // 下划线
|
|
||||||
strikethrough: true, // 中划线
|
|
||||||
quote: true, // 引用
|
|
||||||
ol: true, // 有序列表
|
|
||||||
ul: true, // 无序列表
|
|
||||||
link: true, // 链接
|
|
||||||
code: true, // code
|
|
||||||
table: true, // 表格
|
|
||||||
fullscreen: true, // 全屏编辑
|
|
||||||
readmodel: true, // 沉浸式阅读
|
|
||||||
htmlcode: true, // 展示html源码
|
|
||||||
undo: true, // 上一步
|
|
||||||
redo: true, // 下一步
|
|
||||||
trash: true, // 清空
|
|
||||||
navigation: true, // 导航目录
|
|
||||||
subfield: true, // 单双栏模式
|
|
||||||
preview: true, // 预览
|
|
||||||
imagelink: true // 图片链接
|
|
||||||
}
|
|
||||||
|
|
||||||
export { toolbars }
|
|
|
@ -1,3 +1,29 @@
|
||||||
|
export const markdownEditorToolbars = {
|
||||||
|
bold: true,
|
||||||
|
italic: true,
|
||||||
|
header: true,
|
||||||
|
underline: true,
|
||||||
|
strikethrough: true,
|
||||||
|
superscript: true,
|
||||||
|
subscript: true,
|
||||||
|
quote: true,
|
||||||
|
ol: true,
|
||||||
|
ul: true,
|
||||||
|
link: true,
|
||||||
|
imagelink: true,
|
||||||
|
code: true,
|
||||||
|
table: true,
|
||||||
|
undo: true,
|
||||||
|
redo: true,
|
||||||
|
save: true,
|
||||||
|
navigation: true,
|
||||||
|
subfield: true,
|
||||||
|
fullscreen: true,
|
||||||
|
readmodel: true,
|
||||||
|
htmlcode: true,
|
||||||
|
preview: true
|
||||||
|
}
|
||||||
|
|
||||||
export const actionLogTypes = {
|
export const actionLogTypes = {
|
||||||
BLOG_INITIALIZED: {
|
BLOG_INITIALIZED: {
|
||||||
value: 0,
|
value: 0,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<page-view
|
<page-view
|
||||||
:title="postToStage.title ? postToStage.title : '新文章'"
|
|
||||||
:sub-title="postToStage.inProgress ? '当前内容已保存,但还未发布。' : ''"
|
:sub-title="postToStage.inProgress ? '当前内容已保存,但还未发布。' : ''"
|
||||||
|
:title="postToStage.title ? postToStage.title : '新文章'"
|
||||||
affix
|
affix
|
||||||
>
|
>
|
||||||
<template slot="extra">
|
<template slot="extra">
|
||||||
|
@ -17,9 +17,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="editor" :style="{ height: editorHeight }">
|
<div id="editor" :style="{ height: editorHeight }">
|
||||||
<MarkdownEditor
|
<MarkdownEditor
|
||||||
:originalContent="postToStage.originalContent"
|
:originalContent.sync="postToStage.originalContent"
|
||||||
@onContentChange="onContentChange"
|
@change="onContentChange"
|
||||||
@onSaveDraft="handleSaveDraft()"
|
@save="handleSaveDraft()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -101,7 +101,21 @@ export default {
|
||||||
return '当前页面数据未保存,确定要离开吗?'
|
return '当前页面数据未保存,确定要离开吗?'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
beforeMount() {
|
||||||
|
document.addEventListener('keydown', this.onRegisterSaveShortcut)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
document.removeEventListener('keydown', this.onRegisterSaveShortcut)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
onRegisterSaveShortcut(e) {
|
||||||
|
if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && e.keyCode === 83) {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
this.handleSaveDraft()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
handleSaveDraft: debounce(async function () {
|
handleSaveDraft: debounce(async function () {
|
||||||
if (this.postToStage.id) {
|
if (this.postToStage.id) {
|
||||||
// Update the post content
|
// Update the post content
|
||||||
|
@ -173,9 +187,9 @@ export default {
|
||||||
handleRestoreSavedStatus() {
|
handleRestoreSavedStatus() {
|
||||||
this.contentChanges = 0
|
this.contentChanges = 0
|
||||||
},
|
},
|
||||||
onContentChange(val) {
|
onContentChange({ originalContent }) {
|
||||||
this.contentChanges++
|
this.contentChanges++
|
||||||
this.postToStage.originalContent = val
|
this.postToStage.originalContent = originalContent
|
||||||
},
|
},
|
||||||
onPostSavedCallback() {
|
onPostSavedCallback() {
|
||||||
this.contentChanges = 0
|
this.contentChanges = 0
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
|
|
||||||
<div id="editor" :style="{ height: editorHeight }">
|
<div id="editor" :style="{ height: editorHeight }">
|
||||||
<MarkdownEditor
|
<MarkdownEditor
|
||||||
:originalContent="sheetToStage.originalContent"
|
:originalContent.sync="sheetToStage.originalContent"
|
||||||
@onContentChange="onContentChange"
|
@change="onContentChange"
|
||||||
@onSaveDraft="handleSaveDraft()"
|
@save="handleSaveDraft()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -103,7 +103,21 @@ export default {
|
||||||
return '当前页面数据未保存,确定要离开吗?'
|
return '当前页面数据未保存,确定要离开吗?'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
beforeMount() {
|
||||||
|
document.addEventListener('keydown', this.onRegisterSaveShortcut)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
document.removeEventListener('keydown', this.onRegisterSaveShortcut)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
onRegisterSaveShortcut(e) {
|
||||||
|
if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && e.keyCode === 83) {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
this.handleSaveDraft()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
handleSaveDraft: debounce(async function () {
|
handleSaveDraft: debounce(async function () {
|
||||||
if (this.sheetToStage.id) {
|
if (this.sheetToStage.id) {
|
||||||
try {
|
try {
|
||||||
|
@ -175,9 +189,9 @@ export default {
|
||||||
handleRestoreSavedStatus() {
|
handleRestoreSavedStatus() {
|
||||||
this.contentChanges = 0
|
this.contentChanges = 0
|
||||||
},
|
},
|
||||||
onContentChange(val) {
|
onContentChange({ originalContent }) {
|
||||||
this.contentChanges++
|
this.contentChanges++
|
||||||
this.sheetToStage.originalContent = val
|
this.sheetToStage.originalContent = originalContent
|
||||||
},
|
},
|
||||||
onSheetSavedCallback() {
|
onSheetSavedCallback() {
|
||||||
this.contentChanges = 0
|
this.contentChanges = 0
|
||||||
|
|
Loading…
Reference in New Issue