mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-02 18:09:58 +08:00
fix(infra): memory leak (#9013)
This commit is contained in:
+29
-26
@@ -12,9 +12,8 @@ import {
|
||||
import { DisposableGroup } from '@blocksuite/affine/global/utils';
|
||||
import type { AffineEditorContainer } from '@blocksuite/affine/presets';
|
||||
import type { Doc } from '@blocksuite/affine/store';
|
||||
import { use } from 'foxact/use';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { Suspense, useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import type { DefaultOpenProperty } from '../../doc-properties';
|
||||
import { BlocksuiteEditorContainer } from './blocksuite-editor-container';
|
||||
@@ -31,24 +30,6 @@ export type EditorProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
function usePageRoot(page: Doc) {
|
||||
if (!page.root) {
|
||||
use(
|
||||
new Promise<void>((resolve, reject) => {
|
||||
const disposable = page.slots.rootAdded.once(() => {
|
||||
resolve();
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
disposable.dispose();
|
||||
reject(new NoPageRootError(page));
|
||||
}, 20 * 1000);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return page.root;
|
||||
}
|
||||
|
||||
const BlockSuiteEditorImpl = ({
|
||||
mode,
|
||||
page,
|
||||
@@ -58,8 +39,6 @@ const BlockSuiteEditorImpl = ({
|
||||
onEditorReady,
|
||||
defaultOpenProperty,
|
||||
}: EditorProps) => {
|
||||
usePageRoot(page);
|
||||
|
||||
useEffect(() => {
|
||||
const disposable = page.slots.blockUpdated.once(() => {
|
||||
page.collection.setDocMeta(page.id, {
|
||||
@@ -142,9 +121,33 @@ const BlockSuiteEditorImpl = ({
|
||||
};
|
||||
|
||||
export const BlockSuiteEditor = (props: EditorProps) => {
|
||||
return (
|
||||
<Suspense fallback={<EditorLoading />}>
|
||||
<BlockSuiteEditorImpl key={props.page.id} {...props} />
|
||||
</Suspense>
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.page.root) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
const disposable = props.page.slots.rootAdded.once(() => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
disposable.dispose();
|
||||
setError(new NoPageRootError(props.page));
|
||||
}, 20 * 1000);
|
||||
return () => {
|
||||
disposable.dispose();
|
||||
};
|
||||
}, [props.page]);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return isLoading ? (
|
||||
<EditorLoading />
|
||||
) : (
|
||||
<BlockSuiteEditorImpl key={props.page.id} {...props} />
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,32 +1,31 @@
|
||||
import type { DocCollection } from '@blocksuite/affine/store';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { type ReactNode, Suspense } from 'react';
|
||||
|
||||
import { useBlockSuitePagePreview } from './use-block-suite-page-preview';
|
||||
import { useDocCollectionPage } from './use-block-suite-workspace-page';
|
||||
import { DocsSearchService } from '@affine/core/modules/docs-search';
|
||||
import { LiveData, useLiveData, useService } from '@toeverything/infra';
|
||||
import { type ReactNode, useMemo } from 'react';
|
||||
|
||||
interface PagePreviewProps {
|
||||
docCollection: DocCollection;
|
||||
pageId: string;
|
||||
emptyFallback?: ReactNode;
|
||||
fallback?: ReactNode;
|
||||
}
|
||||
|
||||
const PagePreviewInner = ({
|
||||
docCollection: workspace,
|
||||
pageId,
|
||||
emptyFallback,
|
||||
fallback,
|
||||
}: PagePreviewProps) => {
|
||||
const page = useDocCollectionPage(workspace, pageId);
|
||||
const previewAtom = useBlockSuitePagePreview(page);
|
||||
const preview = useAtomValue(previewAtom);
|
||||
const res = preview ? preview : null;
|
||||
return res || emptyFallback;
|
||||
const docSummary = useService(DocsSearchService);
|
||||
const summary = useLiveData(
|
||||
useMemo(
|
||||
() => LiveData.from(docSummary.watchDocSummary(pageId), null),
|
||||
[docSummary, pageId]
|
||||
)
|
||||
);
|
||||
|
||||
const res =
|
||||
summary === null ? fallback : summary === '' ? emptyFallback : summary;
|
||||
return res;
|
||||
};
|
||||
|
||||
export const PagePreview = (props: PagePreviewProps) => {
|
||||
return (
|
||||
<Suspense>
|
||||
<PagePreviewInner {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
return <PagePreviewInner {...props} />;
|
||||
};
|
||||
|
||||
@@ -317,9 +317,7 @@ function pageMetaToListItemProp(
|
||||
pageId: item.id,
|
||||
pageIds,
|
||||
title: <PageTitle id={item.id} />,
|
||||
preview: (
|
||||
<PagePreview docCollection={props.docCollection} pageId={item.id} />
|
||||
),
|
||||
preview: <PagePreview pageId={item.id} />,
|
||||
createDate: new Date(item.createDate),
|
||||
updatedDate: item.updatedDate ? new Date(item.updatedDate) : undefined,
|
||||
to: props.rowAsLink && !props.selectable ? `/${item.id}` : undefined,
|
||||
|
||||
Reference in New Issue
Block a user