mirror of https://github.com/fantasticit/think.git
fix: render author of document
parent
8cbfbd71d1
commit
faf83ad35b
|
@ -0,0 +1,42 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Space, Avatar } from '@douyinfe/semi-ui';
|
||||||
|
import { LocaleTime } from 'components/locale-time';
|
||||||
|
import { IconUser } from '@douyinfe/semi-icons';
|
||||||
|
import { IDocument } from '@think/domains';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
document: IDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Author: React.FC<IProps> = ({ document }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
borderTop: '1px solid var(--semi-color-border)',
|
||||||
|
marginTop: 24,
|
||||||
|
padding: '16px 0',
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: 'normal',
|
||||||
|
color: 'var(--semi-color-text-0)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Space>
|
||||||
|
<Avatar size="small" src={document.createUser && document.createUser.avatar}>
|
||||||
|
<IconUser />
|
||||||
|
</Avatar>
|
||||||
|
<div>
|
||||||
|
<p style={{ margin: 0 }}>
|
||||||
|
创建者:
|
||||||
|
{document.createUser && document.createUser.name}
|
||||||
|
</p>
|
||||||
|
<p style={{ margin: '8px 0 0' }}>
|
||||||
|
最近更新日期:
|
||||||
|
<LocaleTime date={document.updatedAt} timeago />
|
||||||
|
{' ⦁ '}阅读量:
|
||||||
|
{document.views}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -2,21 +2,8 @@ import Router from 'next/router';
|
||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import {
|
import { Layout, Nav, Space, Button, Typography, Skeleton, Tooltip, Popover, BackTop, Spin } from '@douyinfe/semi-ui';
|
||||||
Layout,
|
import { IconEdit, IconArticle } from '@douyinfe/semi-icons';
|
||||||
Nav,
|
|
||||||
Space,
|
|
||||||
Avatar,
|
|
||||||
Button,
|
|
||||||
Typography,
|
|
||||||
Skeleton,
|
|
||||||
Tooltip,
|
|
||||||
Popover,
|
|
||||||
BackTop,
|
|
||||||
Spin,
|
|
||||||
} from '@douyinfe/semi-ui';
|
|
||||||
import { LocaleTime } from 'components/locale-time';
|
|
||||||
import { IconUser, IconEdit, IconArticle } from '@douyinfe/semi-icons';
|
|
||||||
import { Seo } from 'components/seo';
|
import { Seo } from 'components/seo';
|
||||||
import { DataRender } from 'components/data-render';
|
import { DataRender } from 'components/data-render';
|
||||||
import { DocumentShare } from 'components/document/share';
|
import { DocumentShare } from 'components/document/share';
|
||||||
|
@ -31,6 +18,7 @@ import { useUser } from 'data/user';
|
||||||
import { useDocumentDetail } from 'data/document';
|
import { useDocumentDetail } from 'data/document';
|
||||||
import { triggerJoinUser } from 'event';
|
import { triggerJoinUser } from 'event';
|
||||||
import { CollaborationEditor } from 'tiptap/editor';
|
import { CollaborationEditor } from 'tiptap/editor';
|
||||||
|
import { Author } from './author';
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
const { Header } = Layout;
|
const { Header } = Layout;
|
||||||
|
@ -70,37 +58,7 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
|
||||||
const target = element && element.querySelector('.ProseMirror .title');
|
const target = element && element.querySelector('.ProseMirror .title');
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
return createPortal(
|
return createPortal(<Author document={document} />, target);
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
borderTop: '1px solid var(--semi-color-border)',
|
|
||||||
marginTop: 24,
|
|
||||||
padding: '16px 0',
|
|
||||||
fontSize: 13,
|
|
||||||
fontWeight: 'normal',
|
|
||||||
color: 'var(--semi-color-text-0)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Space>
|
|
||||||
<Avatar size="small" src={document.createUser && document.createUser.avatar}>
|
|
||||||
<IconUser />
|
|
||||||
</Avatar>
|
|
||||||
<div>
|
|
||||||
<p style={{ margin: 0 }}>
|
|
||||||
创建者:
|
|
||||||
{document.createUser && document.createUser.name}
|
|
||||||
</p>
|
|
||||||
<p style={{ margin: '8px 0 0' }}>
|
|
||||||
最近更新日期:
|
|
||||||
<LocaleTime date={document.updatedAt} timeago />
|
|
||||||
{' ⦁ '}阅读量:
|
|
||||||
{document.views}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</Space>
|
|
||||||
</div>,
|
|
||||||
target
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useMemo, useRef, useCallback } from 'react';
|
import React, { useMemo, useRef, useCallback } from 'react';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import {
|
import {
|
||||||
Layout,
|
Layout,
|
||||||
|
@ -26,6 +27,7 @@ import { useDocumentStyle } from 'hooks/use-document-style';
|
||||||
import { usePublicDocument } from 'data/document';
|
import { usePublicDocument } from 'data/document';
|
||||||
import { DocumentSkeleton } from 'tiptap/components/skeleton';
|
import { DocumentSkeleton } from 'tiptap/components/skeleton';
|
||||||
import { CollaborationEditor } from 'tiptap/editor';
|
import { CollaborationEditor } from 'tiptap/editor';
|
||||||
|
import { Author } from '../author';
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
const { Header, Content } = Layout;
|
const { Header, Content } = Layout;
|
||||||
|
@ -44,6 +46,21 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
|
||||||
return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth;
|
return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth;
|
||||||
}, [width]);
|
}, [width]);
|
||||||
|
|
||||||
|
const renderAuthor = useCallback(
|
||||||
|
(element) => {
|
||||||
|
if (!document) return null;
|
||||||
|
|
||||||
|
const target = element && element.querySelector('.ProseMirror .title');
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
return createPortal(<Author document={data} />, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
[data]
|
||||||
|
);
|
||||||
|
|
||||||
const handleOk = useCallback(() => {
|
const handleOk = useCallback(() => {
|
||||||
$form.current.validate().then((values) => {
|
$form.current.validate().then((values) => {
|
||||||
query(values.password);
|
query(values.password);
|
||||||
|
@ -121,7 +138,7 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
|
||||||
}}
|
}}
|
||||||
loadingContent={
|
loadingContent={
|
||||||
<div className={cls(styles.editorWrap, editorWrapClassNames)} style={{ fontSize }}>
|
<div className={cls(styles.editorWrap, editorWrapClassNames)} style={{ fontSize }}>
|
||||||
1<DocumentSkeleton />
|
<DocumentSkeleton />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
normalContent={() => {
|
normalContent={() => {
|
||||||
|
@ -132,7 +149,14 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
|
||||||
style={{ fontSize }}
|
style={{ fontSize }}
|
||||||
>
|
>
|
||||||
<Seo title={data.title} />
|
<Seo title={data.title} />
|
||||||
<CollaborationEditor menubar={false} editable={false} user={null} id={documentId} type="document" />
|
<CollaborationEditor
|
||||||
|
menubar={false}
|
||||||
|
editable={false}
|
||||||
|
user={null}
|
||||||
|
id={documentId}
|
||||||
|
type="document"
|
||||||
|
renderInEditorPortal={renderAuthor}
|
||||||
|
/>
|
||||||
<ImageViewer containerSelector="#js-share-document-editor-container" />
|
<ImageViewer containerSelector="#js-share-document-editor-container" />
|
||||||
<BackTop target={() => document.querySelector('#js-share-document-editor-container').parentNode} />
|
<BackTop target={() => document.querySelector('#js-share-document-editor-container').parentNode} />
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue