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,19 +51,18 @@ export const DocumentEditor: React.FC<IProps> = ({ documentId }) => {
}, [document, documentId]);
const actions = useMemo(
() =>
docAuthLoading ? null : (
<Space>
{document && authority.readable && (
<DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} />
)}
<DocumentShare key="share" documentId={documentId} />
<DocumentVersion key="version" documentId={documentId} onSelect={triggerUseDocumentVersion} />
<DocumentStar key="star" documentId={documentId} />
<DocumentStyle />
</Space>
),
[docAuthLoading, documentId, document, authority]
() => (
<Space>
{document && authority.readable && (
<DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} />
)}
<DocumentShare key="share" documentId={documentId} />
<DocumentVersion key="version" documentId={documentId} onSelect={triggerUseDocumentVersion} />
<DocumentStar key="star" documentId={documentId} />
<DocumentStyle />
</Space>
),
[documentId, document, authority]
);
useEffect(() => {
@ -120,36 +119,18 @@ export const DocumentEditor: React.FC<IProps> = ({ documentId }) => {
{isMobile && <div className={styles.mobileToolbar}>{actions}</div>}
</header>
<main className={styles.contentWrap}>
<DataRender
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' }}>
<SecureDocumentIllustration />
</div>
}
normalContent={() => {
return (
<>
<Seo title={document.title} />
<Editor
user={user}
documentId={document.id}
authority={authority}
className={editorWrapClassNames}
style={{ fontSize }}
/>
</>
);
}}
{docAuthError && (
<div style={{ margin: '10vh', textAlign: 'center' }}>
<SecureDocumentIllustration />
</div>
)}
{document && <Seo title={document.title} />}
<Editor
user={user}
documentId={documentId}
authority={authority}
className={editorWrapClassNames}
style={{ fontSize }}
/>
</main>
</div>

View File

@ -76,34 +76,31 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
}, [document]);
const actions = useMemo(
() =>
docAuthLoading ? null : (
<Space>
{document && authority.readable && (
<DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} />
)}
{authority && authority.editable && (
<Tooltip key="edit" content="编辑" position="bottom">
<Button icon={<IconEdit />} onMouseDown={gotoEdit} />
</Tooltip>
)}
{authority && authority.readable && (
<>
<DocumentShare key="share" documentId={documentId} />
<DocumentVersion key="version" documentId={documentId} />
<DocumentStar key="star" documentId={documentId} />
</>
)}
<DocumentStyle />
</Space>
),
[docAuthLoading, document, documentId, authority, gotoEdit]
() => (
<Space>
{document && authority.readable && (
<DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} />
)}
{authority && authority.editable && (
<Tooltip key="edit" content="编辑" position="bottom">
<Button icon={<IconEdit />} onMouseDown={gotoEdit} />
</Tooltip>
)}
{authority && authority.readable && (
<>
<DocumentShare key="share" documentId={documentId} />
<DocumentVersion key="version" documentId={documentId} />
<DocumentStar key="star" documentId={documentId} />
</>
)}
<DocumentStyle />
</Space>
),
[document, documentId, authority, gotoEdit]
);
const editBtnStyle = useMemo(() => getEditBtnStyle(isMobile ? 16 : 100), [isMobile]);
if (!documentId) return null;
return (
<div className={styles.wrap}>
<Header className={styles.headerWrap}>
@ -134,50 +131,31 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
<Layout className={styles.contentWrap}>
<div ref={setContainer}>
<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 id="js-reader-container">
{document && <Seo title={document.title} />}
{user && (
<CollaborationEditor
editable={false}
user={user}
id={documentId}
type="document"
renderInEditorPortal={renderAuthor}
onAwarenessUpdate={triggerJoinUser}
/>
)}
{user && (
<div className={styles.commentWrap}>
<CommentEditor documentId={documentId} />
</div>
}
normalContent={() => {
return (
<div id="js-reader-container">
<Seo title={document.title} />
{user && (
<CollaborationEditor
editable={false}
user={user}
id={documentId}
type="document"
initialContent={document.content}
renderInEditorPortal={renderAuthor}
onAwarenessUpdate={triggerJoinUser}
/>
)}
{user && (
<div className={styles.commentWrap}>
<CommentEditor documentId={document.id} />
</div>
)}
{!isMobile && authority && authority.editable && container && (
<BackTop style={editBtnStyle} onClick={gotoEdit} target={() => container} visibilityHeight={200}>
<IconEdit />
</BackTop>
)}
<ImageViewer containerSelector="#js-reader-container" />
{container && (
<BackTop style={{ bottom: 65, right: isMobile ? 16 : 100 }} target={() => container} />
)}
</div>
);
}}
/>
)}
{!isMobile && authority && authority.editable && container && (
<BackTop style={editBtnStyle} onClick={gotoEdit} target={() => container} visibilityHeight={200}>
<IconEdit />
</BackTop>
)}
<ImageViewer containerSelector="#js-reader-container" />
{container && <BackTop style={{ bottom: 65, right: isMobile ? 16 : 100 }} target={() => container} />}
</div>
</div>
</div>
</Layout>

View File

@ -1,7 +1,6 @@
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 { DataRender } from 'components/data-render';
import { DocumentStyle } from 'components/document/style';
import { Seo } from 'components/seo';
import { Theme } from 'components/theme';
@ -52,68 +51,55 @@ export const TemplateEditor: React.FC<IProps> = ({ templateId }) => {
}, [data]);
return (
<DataRender
loading={loading}
loadingContent={
<div style={{ margin: 24 }}>
<Spin></Spin>
</div>
}
error={error}
normalContent={() => {
return (
<>
<Seo title={data.title} />
<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 checked={isPublic} 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 }}>
{mounted && (
<CollaborationEditor
menubar
editable
user={user}
id={data.id}
type="template"
onTitleUpdate={setTitle}
/>
)}
</div>
</div>
</main>
<>
{data && <Seo title={data.title} />}
<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 checked={isPublic} 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 }}>
{mounted && data && (
<CollaborationEditor
menubar
editable
user={user}
id={data.id}
type="template"
onTitleUpdate={setTitle}
/>
)}
</div>
</>
);
}}
/>
</div>
</main>
</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>
);
};