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;