client: improve render editor

This commit is contained in:
fantasticit 2022-05-25 13:05:24 +08:00
parent 6768ecc0e2
commit a534e799c1
4 changed files with 119 additions and 263 deletions

View File

@ -51,8 +51,7 @@ export const DocumentEditor: React.FC<IProps> = ({ documentId }) => {
}, [document, documentId]); }, [document, documentId]);
const actions = useMemo( const actions = useMemo(
() => () => (
docAuthLoading ? null : (
<Space> <Space>
{document && authority.readable && ( {document && authority.readable && (
<DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} /> <DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} />
@ -63,7 +62,7 @@ export const DocumentEditor: React.FC<IProps> = ({ documentId }) => {
<DocumentStyle /> <DocumentStyle />
</Space> </Space>
), ),
[docAuthLoading, documentId, document, authority] [documentId, document, authority]
); );
useEffect(() => { useEffect(() => {
@ -120,37 +119,19 @@ export const DocumentEditor: React.FC<IProps> = ({ documentId }) => {
{isMobile && <div className={styles.mobileToolbar}>{actions}</div>} {isMobile && <div className={styles.mobileToolbar}>{actions}</div>}
</header> </header>
<main className={styles.contentWrap}> <main className={styles.contentWrap}>
<DataRender {docAuthError && (
loading={docAuthLoading}
loadingContent={
<div style={{ margin: '10vh auto' }}>
<Spin tip="正在为您读取文档中...">
{/* FIXME: semi-design 的问题,不加 div文字会换行! */}
<div></div>
</Spin>
</div>
}
error={docAuthError}
errorContent={
<div style={{ margin: '10vh', textAlign: 'center' }}> <div style={{ margin: '10vh', textAlign: 'center' }}>
<SecureDocumentIllustration /> <SecureDocumentIllustration />
</div> </div>
} )}
normalContent={() => { {document && <Seo title={document.title} />}
return (
<>
<Seo title={document.title} />
<Editor <Editor
user={user} user={user}
documentId={document.id} documentId={documentId}
authority={authority} authority={authority}
className={editorWrapClassNames} className={editorWrapClassNames}
style={{ fontSize }} style={{ fontSize }}
/> />
</>
);
}}
/>
</main> </main>
</div> </div>
); );

View File

@ -76,8 +76,7 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
}, [document]); }, [document]);
const actions = useMemo( const actions = useMemo(
() => () => (
docAuthLoading ? null : (
<Space> <Space>
{document && authority.readable && ( {document && authority.readable && (
<DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} /> <DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} />
@ -97,13 +96,11 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
<DocumentStyle /> <DocumentStyle />
</Space> </Space>
), ),
[docAuthLoading, document, documentId, authority, gotoEdit] [document, documentId, authority, gotoEdit]
); );
const editBtnStyle = useMemo(() => getEditBtnStyle(isMobile ? 16 : 100), [isMobile]); const editBtnStyle = useMemo(() => getEditBtnStyle(isMobile ? 16 : 100), [isMobile]);
if (!documentId) return null;
return ( return (
<div className={styles.wrap}> <div className={styles.wrap}>
<Header className={styles.headerWrap}> <Header className={styles.headerWrap}>
@ -134,35 +131,21 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
<Layout className={styles.contentWrap}> <Layout className={styles.contentWrap}>
<div ref={setContainer}> <div ref={setContainer}>
<div className={cls(styles.editorWrap, editorWrapClassNames)} style={{ fontSize }}> <div className={cls(styles.editorWrap, editorWrapClassNames)} style={{ fontSize }}>
<DataRender
loading={docAuthLoading}
error={docAuthError}
loadingContent={
<div style={{ margin: '10vh auto' }}>
<Spin tip="正在为您读取文档中...">
{/* FIXME: semi-design 的问题,不加 div文字会换行! */}
<div></div>
</Spin>
</div>
}
normalContent={() => {
return (
<div id="js-reader-container"> <div id="js-reader-container">
<Seo title={document.title} /> {document && <Seo title={document.title} />}
{user && ( {user && (
<CollaborationEditor <CollaborationEditor
editable={false} editable={false}
user={user} user={user}
id={documentId} id={documentId}
type="document" type="document"
initialContent={document.content}
renderInEditorPortal={renderAuthor} renderInEditorPortal={renderAuthor}
onAwarenessUpdate={triggerJoinUser} onAwarenessUpdate={triggerJoinUser}
/> />
)} )}
{user && ( {user && (
<div className={styles.commentWrap}> <div className={styles.commentWrap}>
<CommentEditor documentId={document.id} /> <CommentEditor documentId={documentId} />
</div> </div>
)} )}
{!isMobile && authority && authority.editable && container && ( {!isMobile && authority && authority.editable && container && (
@ -171,13 +154,8 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
</BackTop> </BackTop>
)} )}
<ImageViewer containerSelector="#js-reader-container" /> <ImageViewer containerSelector="#js-reader-container" />
{container && ( {container && <BackTop style={{ bottom: 65, right: isMobile ? 16 : 100 }} target={() => container} />}
<BackTop style={{ bottom: 65, right: isMobile ? 16 : 100 }} target={() => container} />
)}
</div> </div>
);
}}
/>
</div> </div>
</div> </div>
</Layout> </Layout>

View File

@ -1,7 +1,6 @@
import { IconChevronLeft } from '@douyinfe/semi-icons'; import { IconChevronLeft } from '@douyinfe/semi-icons';
import { Button, Nav, Popconfirm, Space, Spin, Switch, Tooltip, Typography } from '@douyinfe/semi-ui'; import { Button, Nav, Popconfirm, Space, Switch, Tooltip, Typography } from '@douyinfe/semi-ui';
import cls from 'classnames'; import cls from 'classnames';
import { DataRender } from 'components/data-render';
import { DocumentStyle } from 'components/document/style'; import { DocumentStyle } from 'components/document/style';
import { Seo } from 'components/seo'; import { Seo } from 'components/seo';
import { Theme } from 'components/theme'; import { Theme } from 'components/theme';
@ -51,19 +50,9 @@ export const TemplateEditor: React.FC<IProps> = ({ templateId }) => {
setTitle(data.title); setTitle(data.title);
}, [data]); }, [data]);
return (
<DataRender
loading={loading}
loadingContent={
<div style={{ margin: 24 }}>
<Spin></Spin>
</div>
}
error={error}
normalContent={() => {
return ( return (
<> <>
<Seo title={data.title} /> {data && <Seo title={data.title} />}
<div className={styles.wrap}> <div className={styles.wrap}>
<header> <header>
<Nav <Nav
@ -97,7 +86,7 @@ export const TemplateEditor: React.FC<IProps> = ({ templateId }) => {
<main className={styles.contentWrap}> <main className={styles.contentWrap}>
<div className={styles.editorWrap}> <div className={styles.editorWrap}>
<div className={cls(styles.contentWrap, editorWrapClassNames)} style={{ fontSize }}> <div className={cls(styles.contentWrap, editorWrapClassNames)} style={{ fontSize }}>
{mounted && ( {mounted && data && (
<CollaborationEditor <CollaborationEditor
menubar menubar
editable editable
@ -113,7 +102,4 @@ export const TemplateEditor: React.FC<IProps> = ({ templateId }) => {
</div> </div>
</> </>
); );
}}
/>
);
}; };

View File

@ -1,89 +0,0 @@
import { IconChevronLeft } from '@douyinfe/semi-icons';
import { Button, Nav, Popconfirm, Space, Switch, Tooltip, Typography } from '@douyinfe/semi-ui';
import { ILoginUser, ITemplate } from '@think/domains';
import cls from 'classnames';
import { DocumentStyle } from 'components/document/style';
import { Theme } from 'components/theme';
import { User } from 'components/user';
import { useDocumentStyle } from 'hooks/use-document-style';
import { useWindowSize } from 'hooks/use-window-size';
import Router from 'next/router';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { CollaborationEditor } from 'tiptap/editor';
import styles from './index.module.scss';
const { Text } = Typography;
interface IProps {
user: ILoginUser;
data: ITemplate;
updateTemplate: (arg) => Promise<ITemplate>;
deleteTemplate: () => Promise<void>;
}
export const Editor: React.FC<IProps> = ({ user, data, updateTemplate, deleteTemplate }) => {
const { width: windowWidth } = useWindowSize();
const [title, setTitle] = useState(data.title);
const [isPublic, setPublic] = useState(false);
const { width, fontSize } = useDocumentStyle();
const editorWrapClassNames = useMemo(() => {
return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth;
}, [width]);
const goback = useCallback(() => {
Router.back();
}, []);
const handleDelte = useCallback(() => {
deleteTemplate().then(() => {
goback();
});
}, [deleteTemplate, goback]);
useEffect(() => {
if (!data) return;
setPublic(data.isPublic);
}, [data]);
return (
<div className={styles.wrap}>
<header>
<Nav
style={{ overflow: 'auto' }}
mode="horizontal"
header={
<>
<Tooltip content="返回" position="bottom">
<Button onClick={goback} icon={<IconChevronLeft />} style={{ marginRight: 16 }} />
</Tooltip>
<Text strong ellipsis={{ showTooltip: true }} style={{ width: ~~(windowWidth / 4) }}>
{title}
</Text>
</>
}
footer={
<Space>
<DocumentStyle />
<Tooltip position="bottom" content={isPublic ? '公开模板' : '个人模板'}>
<Switch onChange={(v) => updateTemplate({ isPublic: v })}></Switch>
</Tooltip>
<Popconfirm title="删除模板" content="模板删除后不可恢复,谨慎操作!" onConfirm={handleDelte}>
<Button type="danger"></Button>
</Popconfirm>
<Theme />
<User />
</Space>
}
></Nav>
</header>
<main className={styles.contentWrap}>
<div className={styles.editorWrap}>
<div className={cls(styles.contentWrap, editorWrapClassNames)} style={{ fontSize }}>
<CollaborationEditor menubar editable user={user} id={data.id} type="template" onTitleUpdate={setTitle} />
</div>
</div>
</main>
</div>
);
};