feat: improve loading state content

This commit is contained in:
fantasticit 2022-04-03 10:29:44 +08:00
parent da0f601423
commit 6113ecc101
8 changed files with 64 additions and 77 deletions

View File

@ -92,7 +92,7 @@ export const CommentEditor: React.FC<IProps> = ({ documentId }) => {
error={error} error={error}
loadingContent={ loadingContent={
<> <>
{Array.from({ length: 5 }, (_, i) => i).map((i) => ( {Array.from({ length: 3 }, (_, i) => i).map((i) => (
<CommentItemPlaceholder key={i} /> <CommentItemPlaceholder key={i} />
))} ))}
</> </>

View File

@ -1,4 +1,4 @@
import React, { useMemo, useEffect, useRef } from 'react'; import React, { useMemo, useEffect } from 'react';
import { useEditor, EditorContent } from '@tiptap/react'; import { useEditor, EditorContent } from '@tiptap/react';
import { Layout } from '@douyinfe/semi-ui'; import { Layout } from '@douyinfe/semi-ui';
import { IDocument, ILoginUser } from '@think/domains'; import { IDocument, ILoginUser } from '@think/domains';
@ -10,6 +10,7 @@ import {
getCollaborationCursorExtension, getCollaborationCursorExtension,
getProvider, getProvider,
destoryProvider, destoryProvider,
DocumentSkeleton,
} from 'tiptap'; } from 'tiptap';
import { DataRender } from 'components/data-render'; import { DataRender } from 'components/data-render';
import { ImageViewer } from 'components/image-viewer'; import { ImageViewer } from 'components/image-viewer';
@ -26,8 +27,6 @@ interface IProps {
} }
export const Editor: React.FC<IProps> = ({ user, documentId, document }) => { export const Editor: React.FC<IProps> = ({ user, documentId, document }) => {
if (!user) return null;
const provider = useMemo(() => { const provider = useMemo(() => {
return getProvider({ return getProvider({
targetId: documentId, targetId: documentId,
@ -70,6 +69,7 @@ export const Editor: React.FC<IProps> = ({ user, documentId, document }) => {
return ( return (
<DataRender <DataRender
loading={loading} loading={loading}
loadingContent={<DocumentSkeleton />}
error={null} error={null}
normalContent={() => { normalContent={() => {
return ( return (

View File

@ -27,6 +27,10 @@
} }
} }
.editorContainer {
min-height: 240px;
}
.commentWrap { .commentWrap {
padding: 16px 0; padding: 16px 0;
border-top: 1px solid var(--semi-color-border); border-top: 1px solid var(--semi-color-border);

View File

@ -28,14 +28,13 @@ interface IProps {
export const DocumentReader: React.FC<IProps> = ({ documentId }) => { export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
if (!documentId) return null; if (!documentId) return null;
const { width: windowWidth } = useWindowSize(); const { width: windowWidth } = useWindowSize();
const { width, fontSize } = useDocumentStyle(); const { width, fontSize } = useDocumentStyle();
const editorWrapClassNames = useMemo(() => { const editorWrapClassNames = useMemo(() => {
return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth; return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth;
}, [width]); }, [width]);
const { user } = useUser(); const { user } = useUser();
const { data: documentAndAuth, loading: docAuthLoading, error: docAuthError } = useDocumentDetail(documentId); const { data: documentAndAuth, loading: docAuthLoading, error: docAuthError } = useDocumentDetail(documentId);
const { document, authority } = documentAndAuth || {}; const { document, authority } = documentAndAuth || {};
@ -53,13 +52,7 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
<DataRender <DataRender
loading={docAuthLoading} loading={docAuthLoading}
error={docAuthError} error={docAuthError}
loadingContent={ loadingContent={<Skeleton active placeholder={<Skeleton.Title style={{ width: 80 }} />} loading={true} />}
<Skeleton
active
placeholder={<Skeleton.Title style={{ width: 80, marginBottom: 8 }} />}
loading={true}
/>
}
normalContent={() => ( normalContent={() => (
<Text strong ellipsis={{ showTooltip: true }} style={{ width: ~~(windowWidth / 4) }}> <Text strong ellipsis={{ showTooltip: true }} style={{ width: ~~(windowWidth / 4) }}>
{document.title} {document.title}
@ -101,7 +94,9 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
return ( return (
<> <>
<Seo title={document.title} /> <Seo title={document.title} />
<Editor key={document.id} user={user} documentId={document.id} document={document} /> <div className={styles.editorContainer}>
{user && <Editor key={document.id} user={user} documentId={document.id} document={document} />}
</div>
<div className={styles.commentWrap}> <div className={styles.commentWrap}>
<CommentEditor documentId={document.id} /> <CommentEditor documentId={document.id} />
</div> </div>

View File

@ -23,7 +23,6 @@ import { User } from 'components/user';
import { Theme } from 'components/theme'; import { Theme } from 'components/theme';
import { ImageViewer } from 'components/image-viewer'; import { ImageViewer } from 'components/image-viewer';
import { useDocumentStyle } from 'hooks/use-document-style'; import { useDocumentStyle } from 'hooks/use-document-style';
import { useWindowSize } from 'hooks/use-window-size';
import { usePublicDocument } from 'data/document'; import { usePublicDocument } from 'data/document';
import { DocumentSkeleton } from 'tiptap'; import { DocumentSkeleton } from 'tiptap';
import { DocumentContent } from './content'; import { DocumentContent } from './content';
@ -41,7 +40,6 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
if (!documentId) return null; if (!documentId) return null;
const { data, loading, error, query } = usePublicDocument(documentId); const { data, loading, error, query } = usePublicDocument(documentId);
const { width: windowWidth } = useWindowSize();
const { width, fontSize } = useDocumentStyle(); const { width, fontSize } = useDocumentStyle();
const editorWrapClassNames = useMemo(() => { const editorWrapClassNames = useMemo(() => {
return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth; return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth;
@ -100,9 +98,7 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
<DataRender <DataRender
loading={loading} loading={loading}
error={error} error={error}
loadingContent={ loadingContent={<Skeleton active placeholder={<Skeleton.Title style={{ width: 80 }} />} loading={true} />}
<Skeleton active placeholder={<Skeleton.Title style={{ width: 80, marginBottom: 8 }} />} loading={true} />
}
normalContent={() => ( normalContent={() => (
<Breadcrumb> <Breadcrumb>
<Breadcrumb.Item> <Breadcrumb.Item>

View File

@ -216,23 +216,7 @@ export const WikiTocs: React.FC<IProps> = ({
<div className={styles.treeWrap}> <div className={styles.treeWrap}>
<DataRender <DataRender
loading={tocsLoading} loading={tocsLoading}
loadingContent={ loadingContent={<NavItem icon={null} text={<Skeleton.Title style={{ width: '100%' }} />} />}
<NavItem
icon={
<Skeleton.Avatar
size="small"
style={{
marginRight: 8,
width: 24,
height: 24,
borderRadius: 4,
}}
></Skeleton.Avatar>
}
text={<Skeleton.Title style={{ width: 120 }} />}
rightNode={<IconPlus />}
/>
}
error={tocsError} error={tocsError}
normalContent={() => ( normalContent={() => (
<Tree <Tree

View File

@ -1,8 +1,8 @@
import type { NextPage } from 'next'; import type { NextPage } from 'next';
import type { IDocument } from '@think/domains'; import type { IDocument } from '@think/domains';
import Link from 'next/link'; import Link from 'next/link';
import React from 'react'; import React, { useMemo } from 'react';
import { Typography, Button, Table, Spin, List } from '@douyinfe/semi-ui'; import { Typography, Button, Table, List } from '@douyinfe/semi-ui';
import { useToggle } from 'hooks/use-toggle'; import { useToggle } from 'hooks/use-toggle';
import { Seo } from 'components/seo'; import { Seo } from 'components/seo';
import { DataRender } from 'components/data-render'; import { DataRender } from 'components/data-render';
@ -31,40 +31,27 @@ const grid = {
const RecentDocs = () => { const RecentDocs = () => {
const { data, error, loading, refresh } = useRecentDocuments(); const { data, error, loading, refresh } = useRecentDocuments();
return ( const columns = useMemo(
<> () => [
<Title heading={3} style={{ margin: '24px 0 0' }}>
访
</Title>
<DataRender
loading={loading}
loadingContent={<Spin />}
error={error}
normalContent={() =>
data && data.length ? (
<Table dataSource={data} loading={loading} pagination={false} size="small" style={{ marginTop: 16 }}>
<Column <Column
title="标题" title="标题"
dataIndex="title" dataIndex="title"
key="title" key="title"
render={(_, document: IDocument) => { render={(_, document: IDocument) => {
return ( return (
<Link <Link href={'/wiki/[wikiId]/document/[docId]'} as={`/wiki/${document.wikiId}/document/${document.id}`}>
href={'/wiki/[wikiId]/document/[docId]'}
as={`/wiki/${document.wikiId}/document/${document.id}`}
>
<a style={{ color: 'inherit', textDecoration: 'none' }}>{document.title}</a> <a style={{ color: 'inherit', textDecoration: 'none' }}>{document.title}</a>
</Link> </Link>
); );
}} }}
/> />,
<Column title="阅读量" dataIndex="views" key="views" /> <Column title="阅读量" dataIndex="views" key="views" />,
<Column <Column
title="更新时间" title="更新时间"
dataIndex="updatedAt" dataIndex="updatedAt"
key="updatedAt" key="updatedAt"
render={(date) => <LocaleTime date={date} timeago />} render={(date) => <LocaleTime date={date} timeago />}
/> />,
<Column <Column
title="操作" title="操作"
dataIndex="operate" dataIndex="operate"
@ -78,7 +65,28 @@ const RecentDocs = () => {
showCreateDocument showCreateDocument
/> />
)} )}
/> />,
],
[]
);
return (
<>
<Title heading={3} style={{ margin: '24px 0 0' }}>
访
</Title>
<DataRender
loading={loading}
loadingContent={
<Table dataSource={[]} loading={true} pagination={false} size="small" style={{ marginTop: 16 }}>
{columns}
</Table>
}
error={error}
normalContent={() =>
data && data.length ? (
<Table dataSource={data} loading={loading} pagination={false} size="small" style={{ marginTop: 16 }}>
{columns}
</Table> </Table>
) : ( ) : (
<Empty message="最近访问的文档会出现在此处" /> <Empty message="最近访问的文档会出现在此处" />

View File

@ -4,8 +4,8 @@ import { Skeleton } from '@douyinfe/semi-ui';
export const DocumentSkeleton = () => { export const DocumentSkeleton = () => {
const placeholder = ( const placeholder = (
<> <>
<Skeleton.Title style={{ width: 240, height: '1.8em', marginBottom: 12, marginTop: 12 }} /> <Skeleton.Title style={{ width: 240, height: '2.4em', marginBottom: 12, marginTop: 12 }} />
<Skeleton.Paragraph style={{ width: '100%' }} rows={15} /> <Skeleton.Paragraph style={{ width: '100%', height: 27 }} rows={7} />
</> </>
); );