mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-23 04:51:49 +08:00
feat(core): add new loading doc component (#11737)
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
fontStyleOptions,
|
||||
} from '@affine/core/modules/editor-setting';
|
||||
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import track from '@affine/track';
|
||||
import {
|
||||
customImageProxyMiddleware,
|
||||
ImageProxyService,
|
||||
@@ -31,7 +32,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import type { DefaultOpenProperty } from '../../components/doc-properties';
|
||||
import { BlocksuiteDocEditor, BlocksuiteEdgelessEditor } from './lit-adaper';
|
||||
import { NoPageRootError } from './no-page-error';
|
||||
import * as styles from './styles.css';
|
||||
|
||||
export interface AffineEditorContainer extends HTMLElement {
|
||||
@@ -289,7 +289,8 @@ const BlockSuiteEditorImpl = ({
|
||||
|
||||
export const BlockSuiteEditor = (props: EditorProps) => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
const [longerLoading, setLongerLoading] = useState(false);
|
||||
const [loadStartTime] = useState(Date.now());
|
||||
|
||||
const editorSetting = useService(EditorSettingService).editorSetting;
|
||||
const settings = useLiveData(
|
||||
@@ -319,28 +320,41 @@ export const BlockSuiteEditor = (props: EditorProps) => {
|
||||
return;
|
||||
}
|
||||
const timer = setTimeout(() => {
|
||||
disposable.unsubscribe();
|
||||
setError(new NoPageRootError(props.page));
|
||||
setLongerLoading(true);
|
||||
}, 20 * 1000);
|
||||
const reportErrorTimer = setTimeout(() => {
|
||||
if (isLoading) {
|
||||
track.doc.$.$.loadDoc({
|
||||
workspaceId: props.page.workspace.id,
|
||||
docId: props.page.id,
|
||||
// time cost in ms
|
||||
time: Date.now() - loadStartTime,
|
||||
success: false,
|
||||
});
|
||||
}
|
||||
}, 60 * 1000);
|
||||
const disposable = props.page.slots.rootAdded.subscribe(() => {
|
||||
disposable.unsubscribe();
|
||||
track.doc.$.$.loadDoc({
|
||||
workspaceId: props.page.workspace.id,
|
||||
docId: props.page.id,
|
||||
time: Date.now() - loadStartTime,
|
||||
success: true,
|
||||
});
|
||||
setIsLoading(false);
|
||||
clearTimeout(timer);
|
||||
setLongerLoading(false);
|
||||
});
|
||||
return () => {
|
||||
disposable.unsubscribe();
|
||||
clearTimeout(timer);
|
||||
clearTimeout(reportErrorTimer);
|
||||
};
|
||||
}, [props.page]);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
}, [isLoading, loadStartTime, props.page]);
|
||||
|
||||
return (
|
||||
<Slot style={{ '--affine-font-family': fontFamily } as CSSProperties}>
|
||||
{isLoading ? (
|
||||
<EditorLoading />
|
||||
<EditorLoading longerLoading={longerLoading} />
|
||||
) : (
|
||||
<BlockSuiteEditorImpl key={props.page.id} {...props} />
|
||||
)}
|
||||
|
||||
+13
-12
@@ -75,8 +75,7 @@ export const ErrorDetail: FC<ErrorDetailProps> = props => {
|
||||
}, [onButtonClick, resetError]);
|
||||
|
||||
const desc = descriptions.map((item, i) => (
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<p key={i} className={styles.text}>
|
||||
<p key={`error-desc-${i}`} className={styles.text}>
|
||||
{item}
|
||||
</p>
|
||||
));
|
||||
@@ -137,15 +136,17 @@ export const ErrorDetail: FC<ErrorDetailProps> = props => {
|
||||
|
||||
export function ContactUS() {
|
||||
return (
|
||||
<Trans>
|
||||
If you are still experiencing this issue, please{' '}
|
||||
<a
|
||||
style={{ color: 'var(--affine-primary-color)' }}
|
||||
href="https://community.affine.pro"
|
||||
target="__blank"
|
||||
>
|
||||
contact us through the community.
|
||||
</a>
|
||||
</Trans>
|
||||
<Trans
|
||||
i18nKey="com.affine.error.contact-us"
|
||||
components={{
|
||||
1: (
|
||||
<a
|
||||
style={{ color: 'var(--affine-primary-color)' }}
|
||||
href="https://community.affine.pro"
|
||||
target="__blank"
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,34 @@
|
||||
import { Scrollable } from '@affine/component';
|
||||
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
||||
import { PageDetailLoading } from '@affine/component/page-detail-skeleton';
|
||||
import type { ChatPanel } from '@affine/core/blocksuite/ai';
|
||||
import { AIProvider } from '@affine/core/blocksuite/ai';
|
||||
import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-editor';
|
||||
import { EditorOutlineViewer } from '@affine/core/blocksuite/outline-viewer';
|
||||
import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary';
|
||||
import { PageAIOnboarding } from '@affine/core/components/affine/ai-onboarding';
|
||||
import { GlobalPageHistoryModal } from '@affine/core/components/affine/page-history-modal';
|
||||
import { DocPropertySidebar } from '@affine/core/components/doc-properties/sidebar';
|
||||
import { useGuard } from '@affine/core/components/guard';
|
||||
import { useAppSettingHelper } from '@affine/core/components/hooks/affine/use-app-setting-helper';
|
||||
import { useEnableAI } from '@affine/core/components/hooks/affine/use-enable-ai';
|
||||
import { useRegisterBlocksuiteEditorCommands } from '@affine/core/components/hooks/affine/use-register-blocksuite-editor-commands';
|
||||
import { useActiveBlocksuiteEditor } from '@affine/core/components/hooks/use-block-suite-editor';
|
||||
import { PageDetailEditor } from '@affine/core/components/page-detail-editor';
|
||||
import { TrashPageFooter } from '@affine/core/components/pure/trash-page-footer';
|
||||
import { TopTip } from '@affine/core/components/top-tip';
|
||||
import { DocService } from '@affine/core/modules/doc';
|
||||
import { EditorService } from '@affine/core/modules/editor';
|
||||
import { GlobalContextService } from '@affine/core/modules/global-context';
|
||||
import { PeekViewService } from '@affine/core/modules/peek-view';
|
||||
import { RecentDocsService } from '@affine/core/modules/quicksearch';
|
||||
import { ViewService } from '@affine/core/modules/workbench';
|
||||
import {
|
||||
useIsActiveView,
|
||||
ViewBody,
|
||||
ViewHeader,
|
||||
ViewService,
|
||||
ViewSidebarTab,
|
||||
WorkbenchService,
|
||||
} from '@affine/core/modules/workbench';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import track from '@affine/track';
|
||||
@@ -39,20 +53,6 @@ import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import type { Subscription } from 'rxjs';
|
||||
|
||||
import { AffineErrorBoundary } from '../../../../components/affine/affine-error-boundary';
|
||||
import { GlobalPageHistoryModal } from '../../../../components/affine/page-history-modal';
|
||||
import { useRegisterBlocksuiteEditorCommands } from '../../../../components/hooks/affine/use-register-blocksuite-editor-commands';
|
||||
import { useActiveBlocksuiteEditor } from '../../../../components/hooks/use-block-suite-editor';
|
||||
import { PageDetailEditor } from '../../../../components/page-detail-editor';
|
||||
import { TrashPageFooter } from '../../../../components/pure/trash-page-footer';
|
||||
import { TopTip } from '../../../../components/top-tip';
|
||||
import {
|
||||
useIsActiveView,
|
||||
ViewBody,
|
||||
ViewHeader,
|
||||
ViewSidebarTab,
|
||||
WorkbenchService,
|
||||
} from '../../../../modules/workbench';
|
||||
import { PageNotFound } from '../../404';
|
||||
import * as styles from './detail-page.css';
|
||||
import { DetailPageHeader } from './detail-page-header';
|
||||
@@ -386,7 +386,7 @@ export const Component = () => {
|
||||
<DetailPageWrapper
|
||||
pageId={pageId}
|
||||
canAccess={canAccess}
|
||||
skeleton={<PageDetailSkeleton />}
|
||||
skeleton={<PageDetailLoading />}
|
||||
notFound={<PageNotFound noPermission />}
|
||||
>
|
||||
<DetailPageImpl />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useThemeColorV2 } from '@affine/component';
|
||||
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
||||
import { PageDetailLoading } from '@affine/component/page-detail-skeleton';
|
||||
import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-editor';
|
||||
import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary';
|
||||
import { useGuard } from '@affine/core/components/guard';
|
||||
@@ -223,7 +223,7 @@ const DetailPageImpl = () => {
|
||||
const getSkeleton = (back: boolean) => (
|
||||
<>
|
||||
<PageHeader back={back} className={styles.header} />
|
||||
<PageDetailSkeleton />
|
||||
<PageDetailLoading />
|
||||
</>
|
||||
);
|
||||
const getNotFound = (back: boolean) => (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Scrollable } from '@affine/component';
|
||||
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
||||
import { PageDetailLoading } from '@affine/component/page-detail-skeleton';
|
||||
import { AIProvider } from '@affine/core/blocksuite/ai';
|
||||
import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-editor';
|
||||
import { EditorOutlineViewer } from '@affine/core/blocksuite/outline-viewer';
|
||||
@@ -160,7 +160,7 @@ function DocPeekPreviewEditor({
|
||||
<Scrollable.Viewport
|
||||
className={clsx('affine-page-viewport', styles.affineDocViewport)}
|
||||
>
|
||||
<Suspense fallback={<PageDetailSkeleton />}>
|
||||
<Suspense fallback={<PageDetailLoading />}>
|
||||
<BlockSuiteEditor
|
||||
className={styles.editor}
|
||||
mode={mode}
|
||||
@@ -224,7 +224,7 @@ export function DocPeekPreview({
|
||||
// if sync engine has been synced and the page is null, show 404 page.
|
||||
if (!doc || !editor || !canAccess) {
|
||||
return loading || canAccess === undefined ? (
|
||||
<PageDetailSkeleton key="current-page-is-null" />
|
||||
<PageDetailLoading key="current-page-is-null" />
|
||||
) : (
|
||||
<PageNotFound noPermission />
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user