perf: editor input 更新

2.0/email-builder
Lei OT 11 months ago
parent c8f6fa886f
commit 24a3fd878c

@ -1,11 +1,26 @@
import { useState, useEffect } from 'react'
import LexicalEditor from '@/components/LexicalEditor'
const LexicalEditorInput = (props) => {
const { id, value = {}, onChange } = props
const [defaultHtml, setDefaultHtml] = useState('');
useEffect(() => {
if (value.html) {
setDefaultHtml(value.html)
}
return () => {}
}, [value])
/**
* 触发onChange
* changedValue: { editorStateJSON, htmlContent, textContent }
*/
const triggerChange = (changedValue) => {
onChange?.({
...value,
// ...value,
...changedValue,
})
}
@ -15,11 +30,9 @@ const LexicalEditorInput = (props) => {
id={id}
{...{ isRichText: true }}
onChange={(val) => {
triggerChange({
html: val.html,
})
triggerChange(val)
}}
initialValue={value.html}
defaultValue={defaultHtml}
/>
)
}

@ -87,10 +87,13 @@ function LexicalDefaultValuePlugin({ value = "" }= {}) {
const nodes = $generateNodesFromDOM(editor, dom);
if (clear) {
root.clear();
// $getRoot().clear();
// $getRoot().select();
}
const p = $createParagraphNode();
const _p = nodes.filter(n => n).forEach((n) => {
// const p = $createParagraphNode();
// const _p =
nodes.filter(n => n.__size !== 0).forEach((n) => {
const paragraphNode = $createParagraphNode();
paragraphNode.append(n);
// p.append(paragraphNode);
@ -108,7 +111,7 @@ function LexicalDefaultValuePlugin({ value = "" }= {}) {
updateHTML(editor, value, true);
});
}
}, []);
}, [value]);
return null;
}
@ -140,7 +143,7 @@ function MyOnChangePlugin({ ignoreHistoryMergeTagChange = true, ignoreSelectionC
// setEditorContent(content);
if (typeof onChange === 'function') {
onChange({ editorState, editor, tags, html, textContent });
onChange({ editorStateJSON: editorState.toJSON(), editor, tags, htmlContent: html, textContent });
}
});
});
@ -149,7 +152,7 @@ function MyOnChangePlugin({ ignoreHistoryMergeTagChange = true, ignoreSelectionC
return null;
}
export default function Editor({ isRichText, isDebug, editorRef, onChange, initialValue, ...props }) {
export default function Editor({ isRichText, isDebug, editorRef, onChange, defaultValue, stateJson, ...props }) {
return (
<LexicalComposer initialConfig={editorConfig}>
<div className='editor-container'>
@ -163,7 +166,7 @@ export default function Editor({ isRichText, isDebug, editorRef, onChange, initi
)}
<HistoryPlugin />
{(import.meta.env.DEV && isDebug) && <TreeViewPlugin />}
<LexicalDefaultValuePlugin value={initialValue} />
<LexicalDefaultValuePlugin value={defaultValue} />
<AutoFocusPlugin />
<CodeHighlightPlugin />
<ListPlugin />

@ -103,7 +103,7 @@ const useSnippetStore = create(devtools((set, get) => ({
formData.append('owner', formValues.owner)
formData.append('type', formValues.category)
formData.append('title', formValues.title)
formData.append('adi_content', formValues.content.html)
formData.append('adi_content', formValues.content.htmlContent)
formData.append('opi_sn', 383)
return postForm(postSnippetUrl, formData)
@ -115,7 +115,7 @@ const useSnippetStore = create(devtools((set, get) => ({
title: formValues.title,
owner: formValues.owner,
category: formValues.category,
content: formValues.content
content: { html: formValues.content.htmlContent }
}
}))
} else {
@ -125,4 +125,4 @@ const useSnippetStore = create(devtools((set, get) => ({
},
}), { name: 'snippetStore' }))
export default useSnippetStore
export default useSnippetStore

@ -48,8 +48,6 @@ const BubbleEmail = ({ onOpenEditor, onOpenEmail, ...message }) => {
// titleColor={message.sender !== 'me' ? '#4f46e5' : ''} // 600
notch={false}
position={message.sender === 'me' ? 'right' : 'left'}
// debug: 0 todo:
replyButton={false}
onReplyClick={() => onOpenEditor(message.msgOrigin)}
onForwardClick={ () => { handleResend(message.msgOrigin); }}
onOpen={() => handlePreview(message)}

@ -100,12 +100,12 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, conversationid,
setShowBcc(true);
};
const handleEditorChange = ({ editorState, html, textContent }) => {
const handleEditorChange = ({ editorStateJSON, htmlContent, textContent }) => {
// console.log('textContent', textContent);
// console.log('html', html);
setHtmlContent(html);
setHtmlContent(htmlContent);
setTextContent(textContent);
form.setFieldValue('content', html);
form.setFieldValue('content', htmlContent);
form.setFieldValue('abstract', getAbstract(textContent));
};
@ -417,7 +417,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, conversationid,
<Input />
</Form.Item>
</Form>
<LexicalEditor {...{ isRichText }} onChange={handleEditorChange} initialValue={initialContent} />
<LexicalEditor {...{ isRichText }} onChange={handleEditorChange} defaultValue={initialContent} />
</DnDModal>
</ConfigProvider>

@ -1,43 +1,17 @@
import {
Flex,
Row,
Col,
Tag,
List,
Form,
Input,
Button,
Space,
Modal,
Select,
Divider,
message,
} from 'antd'
import { useState, useRef, useEffect } from 'react'
import LexicalEditorInput from './LexicalEditorInput'
import { Row, Col, Tag, List, Form, Input, Button, Space, Modal, Select, message } from 'antd'
import { useState, useEffect } from 'react'
import EditorInput from '../../components/EditorInput'
import HtmlPreview from './HtmlPreview'
import useSnippetStore from '@/stores/SnippetStore'
import useAuthStore from '@/stores/AuthStore'
import { isEmpty, isNotEmpty } from '@/utils/commons'
function SnippetList() {
const [messageApi, contextHolder] = message.useMessage()
const [searchform] = Form.useForm()
const [snippetForm] = Form.useForm()
const [
fetchParamList,
ownerList,
typeList,
typeAllList,
fetchSnippetList,
snippetList,
fetchSnippetDetail,
currentSnippet,
saveOrUpdateSnippet
] = useSnippetStore((state) => [
const [fetchParamList, ownerList, typeList, typeAllList, fetchSnippetList, snippetList, fetchSnippetDetail, currentSnippet, saveOrUpdateSnippet] = useSnippetStore((state) => [
state.fetchParamList,
state.ownerList,
state.typeList,
@ -46,7 +20,7 @@ function SnippetList() {
state.snippetList,
state.fetchSnippetDetail,
state.currentSnippet,
state.saveOrUpdateSnippet
state.saveOrUpdateSnippet,
])
const [loginUser] = useAuthStore((state) => [state.loginUser])
@ -70,8 +44,7 @@ function SnippetList() {
const handleSnippetSelected = (snippet) => {
setHtmlLoading(true)
fetchSnippetDetail(snippet)
.finally(() => setHtmlLoading(false))
fetchSnippetDetail(snippet).finally(() => setHtmlLoading(false))
}
const handelSnippetEdit = () => {
@ -103,6 +76,7 @@ function SnippetList() {
form={snippetForm}
layout='vertical'
className='max-w-4xl'
initialValues={currentSnippet}
onFinish={onSnippetFinish}
onFinishFailed={onSnippetFailed}
autoComplete='off'>
@ -123,19 +97,17 @@ function SnippetList() {
]}>
<Input />
</Form.Item>
<Form.Item label='所有者' name='owner'
<Form.Item
label='所有者'
name='owner'
rules={[
{
required: true,
message: '所有者必选',
},
]}>
<Select
options={ownerList}
showSearch
optionFilterProp='label'
notFoundContent={'找不到'}></Select>
</Form.Item>
<Select options={ownerList} showSearch optionFilterProp='label' notFoundContent={'找不到'}></Select>
</Form.Item>
<Form.Item
label='类型'
name='category'
@ -145,8 +117,7 @@ function SnippetList() {
message: '类型必选',
},
]}>
<Select options={typeList}>
</Select>
<Select options={typeList}></Select>
</Form.Item>
<Form.Item
label='内容'
@ -157,7 +128,7 @@ function SnippetList() {
message: '内容必填',
},
]}>
<LexicalEditorInput />
<EditorInput />
</Form.Item>
</Modal>
@ -171,12 +142,7 @@ function SnippetList() {
type: '',
}}>
<Form.Item label='所有者' name='owner'>
<Select
className='!w-40'
options={ownerList}
showSearch
optionFilterProp='label'
notFoundContent={'找不到'}></Select>
<Select className='!w-40' options={ownerList} showSearch optionFilterProp='label' notFoundContent={'找不到'}></Select>
</Form.Item>
<Form.Item label='类别' name='type'>
<Select className='!w-40' options={typeAllList} />
@ -221,10 +187,13 @@ function SnippetList() {
/>
</Col>
<Col span={16}>
<HtmlPreview value={currentSnippet.content.html} loading={isHtmlLoading}
<HtmlPreview
value={currentSnippet.content.html}
loading={isHtmlLoading}
onEdit={() => handelSnippetEdit()}
onCopied={() => messageApi.success('已复制')}
onDelete={() => console.info('onDelete')} />
onDelete={() => console.info('onDelete')}
/>
</Col>
</Row>
</Space>

Loading…
Cancel
Save