From 820c1038db5aec9c954fed3764c7848166f962b6 Mon Sep 17 00:00:00 2001 From: Takagi <1103069291@qq.com> Date: Thu, 14 Mar 2024 13:02:07 +0800 Subject: [PATCH] pref: refactor default editor audio block upload logic (#5421) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area ui /area editor #### What this PR does / why we need it: 重构默认编辑器音频组件。使其支持上传、取消上传、从附件库选择、替换等功能。 #### How to test it? 直接拖动、复制或选择文件上传一个音频,查看是否显示上传进度条,取消、重试功能是否正常 #### Which issue(s) this PR fixes: Fixes #5239 #### Does this PR introduce a user-facing change? ```release-note 重构编辑器音频组件的上传逻辑,增加选择文件上传、上传进度条、取消、重试等机制。 ``` --- ui/src/components/editor/DefaultEditor.vue | 7 +- .../editor/components/EditorLinkObtain.vue | 4 +- .../editor/extensions/audio/AudioView.vue | 196 ++++++++++++++++++ .../editor/extensions/audio/index.ts | 42 ++++ ui/src/components/editor/extensions/index.ts | 8 +- ui/src/components/editor/utils/upload.ts | 19 ++ 6 files changed, 272 insertions(+), 4 deletions(-) create mode 100644 ui/src/components/editor/extensions/audio/AudioView.vue create mode 100644 ui/src/components/editor/extensions/audio/index.ts diff --git a/ui/src/components/editor/DefaultEditor.vue b/ui/src/components/editor/DefaultEditor.vue index 0a584e9bcf..b097e1d983 100644 --- a/ui/src/components/editor/DefaultEditor.vue +++ b/ui/src/components/editor/DefaultEditor.vue @@ -53,6 +53,7 @@ import { } from "@halo-dev/richtext-editor"; // ui custom extension import { + UiExtensionAudio, UiExtensionImage, UiExtensionUpload, UiExtensionVideo, @@ -272,7 +273,11 @@ onMounted(() => { uploadVideo: props.uploadImage, }) : ExtensionVideo, - ExtensionAudio, + currentUserHasPermission(["uc:attachments:manage"]) + ? UiExtensionAudio.configure({ + uploadAudio: props.uploadImage, + }) + : ExtensionAudio, ExtensionCharacterCount, ExtensionFontSize, ExtensionColor, diff --git a/ui/src/components/editor/components/EditorLinkObtain.vue b/ui/src/components/editor/components/EditorLinkObtain.vue index 2fa867bb94..9d66200bfb 100644 --- a/ui/src/components/editor/components/EditorLinkObtain.vue +++ b/ui/src/components/editor/components/EditorLinkObtain.vue @@ -1,6 +1,6 @@ + + diff --git a/ui/src/components/editor/extensions/audio/index.ts b/ui/src/components/editor/extensions/audio/index.ts new file mode 100644 index 0000000000..539e610bc0 --- /dev/null +++ b/ui/src/components/editor/extensions/audio/index.ts @@ -0,0 +1,42 @@ +import { ExtensionAudio, VueNodeViewRenderer } from "@halo-dev/richtext-editor"; +import type { AxiosRequestConfig } from "axios"; +import type { Attachment } from "@halo-dev/api-client"; +import AudioView from "./AudioView.vue"; + +interface UiAudioOptions { + uploadAudio?: ( + file: File, + options?: AxiosRequestConfig + ) => Promise; +} + +const Audio = ExtensionAudio.extend({ + addOptions() { + const { parent } = this; + return { + ...parent?.(), + uploadAudio: undefined, + }; + }, + + addAttributes() { + return { + ...this.parent?.(), + file: { + default: null, + renderHTML() { + return {}; + }, + parseHTML() { + return null; + }, + }, + }; + }, + + addNodeView() { + return VueNodeViewRenderer(AudioView); + }, +}); + +export default Audio; diff --git a/ui/src/components/editor/extensions/index.ts b/ui/src/components/editor/extensions/index.ts index 0e71565611..024d2f36ec 100644 --- a/ui/src/components/editor/extensions/index.ts +++ b/ui/src/components/editor/extensions/index.ts @@ -1,4 +1,10 @@ import UiExtensionImage from "./image"; import UiExtensionVideo from "./video"; import UiExtensionUpload from "./upload"; -export { UiExtensionImage, UiExtensionUpload, UiExtensionVideo }; +import UiExtensionAudio from "./audio"; +export { + UiExtensionImage, + UiExtensionUpload, + UiExtensionVideo, + UiExtensionAudio, +}; diff --git a/ui/src/components/editor/utils/upload.ts b/ui/src/components/editor/utils/upload.ts index 6fc62aa4b3..eb3643b0da 100644 --- a/ui/src/components/editor/utils/upload.ts +++ b/ui/src/components/editor/utils/upload.ts @@ -3,6 +3,7 @@ import { CoreEditor } from "@halo-dev/richtext-editor"; import type { Attachment } from "@halo-dev/api-client"; import Image from "../extensions/image"; import ExtensionVideo from "../extensions/video"; +import ExtensionAudio from "../extensions/audio"; import type { AxiosRequestConfig } from "axios"; export interface FileProps { @@ -31,6 +32,11 @@ export const handleFileEvent = ({ file, editor }: FileProps) => { return true; } + if (file.type.startsWith("audio/")) { + uploadAudio({ file, editor }); + return true; + } + return true; }; @@ -60,6 +66,19 @@ export const uploadVideo = ({ file, editor }: FileProps) => { editor.view.dispatch(editor.view.state.tr.replaceSelectionWith(node)); }; +/** + * Uploads an audio file and inserts it into the editor. + * + * @param {FileProps} { file, editor } - File to be uploaded and the editor instance + */ +export const uploadAudio = ({ file, editor }: FileProps) => { + const { view } = editor; + const node = view.props.state.schema.nodes[ExtensionAudio.name].create({ + file: file, + }); + editor.view.dispatch(editor.view.state.tr.replaceSelectionWith(node)); +}; + export interface UploadFetchResponse { controller: AbortController; onUploadProgress: (progress: number) => void;