提交 3a33655a authored 作者: 王鹏飞's avatar 王鹏飞

refactor(admin): host media feature dialogs

上级 ebd6bb75
import { useState, forwardRef, useImperativeHandle } from "react"; import { useState } from "react";
import { Modal, Divider, Upload, Input, Space, Button, Form, Spin, message } from "antd"; import { Modal, Divider, Upload, Input, Space, Button, Form, Spin, message } from "antd";
import { CloudUploadOutlined } from "@ant-design/icons"; import { CloudUploadOutlined } from "@ant-design/icons";
import { SlateTransforms, SlateEditor, SlateElement } from "@wangeditor/editor"; import { SlateTransforms, SlateEditor, SlateElement } from "@wangeditor/editor";
...@@ -7,24 +7,17 @@ import { uploadFile } from "@/utils/oss"; ...@@ -7,24 +7,17 @@ import { uploadFile } from "@/utils/oss";
const { Dragger } = Upload; const { Dragger } = Upload;
const AudioModal = (props, ref) => { const AudioModal = ({ open, onClose, runtime }) => {
const { editor } = props; const { editor } = runtime;
const fileAccept = [".mp3", ".wav", ".ogg"]; const fileAccept = [".mp3", ".wav", ".ogg"];
const [form] = Form.useForm(); const [form] = Form.useForm();
const [visible, setVisible] = useState(false);
const [uploading, setUploading] = useState(false); // 文件上传状态 const [uploading, setUploading] = useState(false); // 文件上传状态
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
const [file, setFile] = useState({}); const [file, setFile] = useState({});
const [audioUrl, setAudioUrl] = useState(""); const [audioUrl, setAudioUrl] = useState("");
useImperativeHandle(ref, () => {
return {
setVisible,
};
});
const uploadProps = { const uploadProps = {
name: "file", name: "file",
maxCount: 1, maxCount: 1,
...@@ -90,13 +83,13 @@ const AudioModal = (props, ref) => { ...@@ -90,13 +83,13 @@ const AudioModal = (props, ref) => {
setProgress(0); setProgress(0);
setUploading(false); setUploading(false);
form.resetFields(); form.resetFields();
setVisible(false); onClose();
}; };
return ( return (
<div> <div>
<Modal <Modal
open={visible} open={open}
footer={null} footer={null}
centered centered
destroyOnHidden destroyOnHidden
...@@ -107,7 +100,7 @@ const AudioModal = (props, ref) => { ...@@ -107,7 +100,7 @@ const AudioModal = (props, ref) => {
wrapper: "editor-wrapper-customer", wrapper: "editor-wrapper-customer",
}} }}
maskClosable={false} maskClosable={false}
onCancel={() => setVisible(false)} onCancel={onClose}
> >
<Divider /> <Divider />
<div className="editor-content-form"> <div className="editor-content-form">
...@@ -164,7 +157,7 @@ const AudioModal = (props, ref) => { ...@@ -164,7 +157,7 @@ const AudioModal = (props, ref) => {
</Form.Item> </Form.Item>
<Form.Item className="editor-form-buttons"> <Form.Item className="editor-form-buttons">
<Space> <Space>
<Button type="default" disabled={uploading} onClick={() => setVisible(false)}> <Button type="default" disabled={uploading} onClick={onClose}>
取消 取消
</Button> </Button>
<Button type="primary" disabled={uploading} htmlType="submit"> <Button type="primary" disabled={uploading} htmlType="submit">
...@@ -179,4 +172,4 @@ const AudioModal = (props, ref) => { ...@@ -179,4 +172,4 @@ const AudioModal = (props, ref) => {
); );
}; };
export default forwardRef(AudioModal); export default AudioModal;
import { defineEditorFeature } from '../../core/define-editor-feature' import { defineEditorFeature } from '../../core/define-editor-feature'
import menu from './menu' import menu from './menu'
import nodeModule from './node' import nodeModule from './node'
import { openEditorDialog } from '../../core/editor-dialog'
import AudioDialog from './AudioDialog'
export default defineEditorFeature({ export default defineEditorFeature({
id: 'audio', id: 'audio',
menus: [{ order: 50, config: menu }], menus: [{ order: 50, config: menu }],
nodeModules: [{ order: 50, types: ['chapterAudio'], module: nodeModule }], nodeModules: [{ order: 50, types: ['chapterAudio'], module: nodeModule }],
events: [{ name: 'AudioMenuClick', handler: ({ runtime }) => runtime.openAudio() }], dialogs: [{ id: 'audio.insert', component: AudioDialog }],
events: [{ name: 'AudioMenuClick', handler: ({ editor }) => openEditorDialog(editor, 'audio.insert') }],
}) })
import { useState, useEffect, forwardRef, useImperativeHandle } from "react"; import { useState, useEffect } from "react";
import { Modal, Divider, Space, Button, message } from "antd"; import { Modal, Divider, Space, Button, message } from "antd";
// import formulaEditor from 'easy-formula-editor'; // import formulaEditor from 'easy-formula-editor';
import "../../index.less"; import "../../index.less";
const FormulaModal = (props, ref) => { const FormulaModal = ({ open, onClose, runtime }) => {
const { editor } = props; const { editor } = runtime;
const [visible, setVisible] = useState(false);
const [editor2, setEditor2] = useState(null); const [editor2, setEditor2] = useState(null);
useImperativeHandle(ref, () => {
return {
setVisible,
};
});
useEffect(() => { useEffect(() => {
if (visible) { if (open) {
setTimeout(() => { setTimeout(() => {
const editor2 = new formulaEditor(); const editor2 = new formulaEditor();
// 增加预设公式 // 增加预设公式
...@@ -28,7 +21,7 @@ const FormulaModal = (props, ref) => { ...@@ -28,7 +21,7 @@ const FormulaModal = (props, ref) => {
} else { } else {
editor2 && editor2.destoryDom(); editor2 && editor2.destoryDom();
} }
}, [visible]); }, [open]);
const insertFormula = () => { const insertFormula = () => {
editor.restoreSelection(); editor.restoreSelection();
...@@ -44,7 +37,7 @@ const FormulaModal = (props, ref) => { ...@@ -44,7 +37,7 @@ const FormulaModal = (props, ref) => {
formulaHtml: html, formulaHtml: html,
children: [{ text: "" }], children: [{ text: "" }],
}); });
setVisible(false); onClose();
} else { } else {
message.error("请选择公式内容!"); message.error("请选择公式内容!");
} }
...@@ -53,7 +46,7 @@ const FormulaModal = (props, ref) => { ...@@ -53,7 +46,7 @@ const FormulaModal = (props, ref) => {
return ( return (
<div> <div>
<Modal <Modal
open={visible} open={open}
footer={null} footer={null}
centered centered
destroyOnHidden destroyOnHidden
...@@ -64,7 +57,7 @@ const FormulaModal = (props, ref) => { ...@@ -64,7 +57,7 @@ const FormulaModal = (props, ref) => {
wrapper: "editor-wrapper-customer", wrapper: "editor-wrapper-customer",
}} }}
maskClosable={false} maskClosable={false}
onCancel={() => setVisible(false)} onCancel={onClose}
width="900px" width="900px"
> >
<Divider /> <Divider />
...@@ -73,7 +66,7 @@ const FormulaModal = (props, ref) => { ...@@ -73,7 +66,7 @@ const FormulaModal = (props, ref) => {
</div> </div>
<div className="formula-buttons"> <div className="formula-buttons">
<Space> <Space>
<Button type="default" onClick={() => setVisible(false)}> <Button type="default" onClick={onClose}>
取消 取消
</Button> </Button>
<Button type="primary" onClick={insertFormula}> <Button type="primary" onClick={insertFormula}>
...@@ -86,4 +79,4 @@ const FormulaModal = (props, ref) => { ...@@ -86,4 +79,4 @@ const FormulaModal = (props, ref) => {
); );
}; };
export default forwardRef(FormulaModal); export default FormulaModal;
import { defineEditorFeature } from '../../core/define-editor-feature' import { defineEditorFeature } from '../../core/define-editor-feature'
import menu from './menu' import menu from './menu'
import nodeModule from './node' import nodeModule from './node'
import { openEditorDialog } from '../../core/editor-dialog'
import FormulaDialog from './FormulaDialog'
export default defineEditorFeature({ export default defineEditorFeature({
id: 'formula', id: 'formula',
menus: [{ order: 60, config: menu }], menus: [{ order: 60, config: menu }],
nodeModules: [{ order: 80, types: ['chapterFormula'], module: nodeModule }], nodeModules: [{ order: 80, types: ['chapterFormula'], module: nodeModule }],
events: [{ name: 'FormulaMenuClick', handler: ({ runtime }) => runtime.openFormula() }], dialogs: [{ id: 'formula.insert', component: FormulaDialog }],
events: [{ name: 'FormulaMenuClick', handler: ({ editor }) => openEditorDialog(editor, 'formula.insert') }],
}) })
import { useState, useEffect, forwardRef, useImperativeHandle } from "react"; import { useState, useEffect } from "react";
import { Modal, Divider, Upload, Input, Space, Button, Form, Spin, message } from "antd"; import { Modal, Divider, Upload, Input, Space, Button, Form, Spin, message } from "antd";
import { CloudUploadOutlined } from "@ant-design/icons"; import { CloudUploadOutlined } from "@ant-design/icons";
import { SlateTransforms, SlateEditor, SlateElement } from "@wangeditor/editor"; import { SlateTransforms, SlateEditor, SlateElement } from "@wangeditor/editor";
...@@ -8,12 +8,11 @@ import { uploadFile } from "@/utils/oss"; ...@@ -8,12 +8,11 @@ import { uploadFile } from "@/utils/oss";
const { Dragger } = Upload; const { Dragger } = Upload;
const VideoModal = (props, ref) => { const VideoModal = ({ open, onClose, runtime }) => {
const { editor } = props; const { editor } = runtime;
const fileAccept = [".ogg", ".mp4", ".webm"]; const fileAccept = [".ogg", ".mp4", ".webm"];
const [form] = Form.useForm(); const [form] = Form.useForm();
const [visible, setVisible] = useState(false);
const [uploading, setUploading] = useState(false); // 文件上传状态 const [uploading, setUploading] = useState(false); // 文件上传状态
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
const [file, setFile] = useState({}); const [file, setFile] = useState({});
...@@ -21,16 +20,10 @@ const VideoModal = (props, ref) => { ...@@ -21,16 +20,10 @@ const VideoModal = (props, ref) => {
const [videoUrl, setVideoUrl] = useState(""); const [videoUrl, setVideoUrl] = useState("");
useEffect(() => { useEffect(() => {
if (!visible) { if (!open) {
setVideoUrl(""); setVideoUrl("");
} }
}, [visible]); }, [open]);
useImperativeHandle(ref, () => {
return {
setVisible,
};
});
const uploadProps = { const uploadProps = {
name: "file", name: "file",
...@@ -97,13 +90,13 @@ const VideoModal = (props, ref) => { ...@@ -97,13 +90,13 @@ const VideoModal = (props, ref) => {
setProgress(0); setProgress(0);
setUploading(false); setUploading(false);
form.resetFields(); form.resetFields();
setVisible(false); onClose();
}; };
return ( return (
<div> <div>
<Modal <Modal
open={visible} open={open}
footer={null} footer={null}
centered centered
destroyOnHidden destroyOnHidden
...@@ -114,7 +107,7 @@ const VideoModal = (props, ref) => { ...@@ -114,7 +107,7 @@ const VideoModal = (props, ref) => {
wrapper: "editor-wrapper-customer", wrapper: "editor-wrapper-customer",
}} }}
maskClosable={false} maskClosable={false}
onCancel={() => setVisible(false)} onCancel={onClose}
> >
<Divider /> <Divider />
<div className="editor-content-form"> <div className="editor-content-form">
...@@ -175,7 +168,7 @@ const VideoModal = (props, ref) => { ...@@ -175,7 +168,7 @@ const VideoModal = (props, ref) => {
</Form.Item> </Form.Item>
<Form.Item className="editor-form-buttons"> <Form.Item className="editor-form-buttons">
<Space> <Space>
<Button type="default" disabled={uploading} onClick={() => setVisible(false)}> <Button type="default" disabled={uploading} onClick={onClose}>
取消 取消
</Button> </Button>
<Button type="primary" disabled={uploading} htmlType="submit"> <Button type="primary" disabled={uploading} htmlType="submit">
...@@ -190,4 +183,4 @@ const VideoModal = (props, ref) => { ...@@ -190,4 +183,4 @@ const VideoModal = (props, ref) => {
); );
}; };
export default forwardRef(VideoModal); export default VideoModal;
import { defineEditorFeature } from '../../core/define-editor-feature' import { defineEditorFeature } from '../../core/define-editor-feature'
import menu from './menu' import menu from './menu'
import nodeModule from './node' import nodeModule from './node'
import { openEditorDialog } from '../../core/editor-dialog'
import VideoDialog from './VideoDialog'
export default defineEditorFeature({ export default defineEditorFeature({
id: 'video', id: 'video',
menus: [{ order: 40, config: menu }], menus: [{ order: 40, config: menu }],
nodeModules: [{ order: 40, types: ['chapterVideo'], module: nodeModule }], nodeModules: [{ order: 40, types: ['chapterVideo'], module: nodeModule }],
events: [{ name: 'VideoMenuClick', handler: ({ runtime }) => runtime.openVideo() }], dialogs: [{ id: 'video.insert', component: VideoDialog }],
events: [{ name: 'VideoMenuClick', handler: ({ editor }) => openEditorDialog(editor, 'video.insert') }],
}) })
...@@ -23,12 +23,9 @@ import relativeTime from "dayjs/plugin/relativeTime"; ...@@ -23,12 +23,9 @@ import relativeTime from "dayjs/plugin/relativeTime";
dayjs.extend(relativeTime); dayjs.extend(relativeTime);
import VideoModal from "../features/video/VideoDialog";
import AudioModal from "../features/audio/AudioDialog";
import ChapterTitleModal from "../features/chapter-structure/TitleDialog"; import ChapterTitleModal from "../features/chapter-structure/TitleDialog";
import ChapterItemModal from "../features/chapter-structure/SectionDialog"; import ChapterItemModal from "../features/chapter-structure/SectionDialog";
import PracticeModal from "../features/practice/PracticeInsertDialog"; import PracticeModal from "../features/practice/PracticeInsertDialog";
import FormulaModal from "../features/formula/FormulaDialog";
import TooltipModal from "../features/tooltip/TooltipDialog"; import TooltipModal from "../features/tooltip/TooltipDialog";
import LinkModal from "../features/link/LinkDialog"; import LinkModal from "../features/link/LinkDialog";
import ExpandModal from "../features/expand-read/ExpandReadDialog"; import ExpandModal from "../features/expand-read/ExpandReadDialog";
...@@ -237,9 +234,6 @@ const WangEditorCustomer = (props, ref) => { ...@@ -237,9 +234,6 @@ const WangEditorCustomer = (props, ref) => {
], ],
}; };
const videoRef = useRef();
const audioRef = useRef();
const formulaRef = useRef();
const tooltipRef = useRef(); const tooltipRef = useRef();
const chapterTitleRef = useRef(); const chapterTitleRef = useRef();
const chapterItemRef = useRef(); const chapterItemRef = useRef();
...@@ -330,12 +324,9 @@ const WangEditorCustomer = (props, ref) => { ...@@ -330,12 +324,9 @@ const WangEditorCustomer = (props, ref) => {
}; };
const featureRuntime = { const featureRuntime = {
openVideo: () => videoRef.current?.setVisible(true),
openAudio: () => audioRef.current?.setVisible(true),
openTitle: () => setTitleVisible(true), openTitle: () => setTitleVisible(true),
openSection: () => setSectionVisible(true), openSection: () => setSectionVisible(true),
openPractice: () => setPracticeOpenVisible(true), openPractice: () => setPracticeOpenVisible(true),
openFormula: () => formulaRef.current?.setVisible(true),
openTooltip: () => setTooltipVisible(true), openTooltip: () => setTooltipVisible(true),
openLink: () => setLinkVisible(true), openLink: () => setLinkVisible(true),
openExpandRead: () => setExpandVisible(true), openExpandRead: () => setExpandVisible(true),
...@@ -426,8 +417,6 @@ const WangEditorCustomer = (props, ref) => { ...@@ -426,8 +417,6 @@ const WangEditorCustomer = (props, ref) => {
/> />
</div> </div>
{!isView && <EditorSidebar editor={editor} toolbarConfig={toolbarConfig} toolbarRef={toolbarRef} tabKey={tabKey} onTabChange={tabKeyChange} colorList={colorList} onApplyColor={setColor} />} {!isView && <EditorSidebar editor={editor} toolbarConfig={toolbarConfig} toolbarRef={toolbarRef} tabKey={tabKey} onTabChange={tabKeyChange} colorList={colorList} onApplyColor={setColor} />}
<VideoModal ref={videoRef} editor={editor} />
<AudioModal ref={audioRef} editor={editor} />
<Modal <Modal
open={titleVisible} open={titleVisible}
footer={null} footer={null}
...@@ -498,7 +487,6 @@ const WangEditorCustomer = (props, ref) => { ...@@ -498,7 +487,6 @@ const WangEditorCustomer = (props, ref) => {
/> />
</Modal> </Modal>
<FormulaModal ref={formulaRef} editor={editor} />
<Modal <Modal
open={tooltipVisible} open={tooltipVisible}
footer={null} footer={null}
......
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论