mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-26 18:55:57 +08:00
fix(infra): memory leak (#9013)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { IconButton } from '@affine/component';
|
||||
import { IconButton, observeIntersection, Skeleton } from '@affine/component';
|
||||
import { useCatchEventCallback } from '@affine/core/components/hooks/use-catch-event-hook';
|
||||
import { PagePreview } from '@affine/core/components/page-list/page-content-preview';
|
||||
import { IsFavoriteIcon } from '@affine/core/components/pure/icons';
|
||||
@@ -10,9 +10,16 @@ import {
|
||||
} from '@affine/core/modules/workbench';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import type { DocMeta } from '@blocksuite/affine/store';
|
||||
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import clsx from 'clsx';
|
||||
import { forwardRef, type ReactNode, useMemo } from 'react';
|
||||
import {
|
||||
forwardRef,
|
||||
type ReactNode,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import * as styles from './styles.css';
|
||||
import { DocCardTags } from './tag';
|
||||
@@ -38,11 +45,11 @@ export interface DocCardProps extends Omit<WorkbenchLinkProps, 'to'> {
|
||||
export const DocCard = forwardRef<HTMLAnchorElement, DocCardProps>(
|
||||
function DocCard(
|
||||
{ showTags = true, meta, className, autoHeightById, ...attrs },
|
||||
ref
|
||||
outerRef
|
||||
) {
|
||||
const containerRef = useRef<HTMLAnchorElement | null>(null);
|
||||
const t = useI18n();
|
||||
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
|
||||
const workspace = useService(WorkspaceService).workspace;
|
||||
const docDisplayService = useService(DocDisplayMetaService);
|
||||
const titleInfo = useLiveData(docDisplayService.title$(meta.id));
|
||||
const title =
|
||||
@@ -64,13 +71,35 @@ export const DocCard = forwardRef<HTMLAnchorElement, DocCardProps>(
|
||||
return { height: `${rows * 18}px` };
|
||||
}, [autoHeightById, meta.id]);
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerRef.current) return;
|
||||
|
||||
const dispose = observeIntersection(containerRef.current, entry => {
|
||||
setVisible(entry.isIntersecting);
|
||||
});
|
||||
|
||||
return () => {
|
||||
dispose();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<WorkbenchLink
|
||||
to={`/${meta.id}`}
|
||||
ref={ref}
|
||||
ref={ref => {
|
||||
containerRef.current = ref;
|
||||
if (typeof outerRef === 'function') {
|
||||
outerRef(ref);
|
||||
} else if (outerRef) {
|
||||
outerRef.current = ref;
|
||||
}
|
||||
}}
|
||||
className={clsx(styles.card, className)}
|
||||
data-testid="doc-card"
|
||||
data-doc-id={meta.id}
|
||||
data-visible={visible}
|
||||
{...attrs}
|
||||
>
|
||||
<header className={styles.head} data-testid="doc-card-header">
|
||||
@@ -83,11 +112,18 @@ export const DocCard = forwardRef<HTMLAnchorElement, DocCardProps>(
|
||||
/>
|
||||
</header>
|
||||
<main className={styles.content} style={contentStyle}>
|
||||
<PagePreview
|
||||
docCollection={workspace.docCollection}
|
||||
pageId={meta.id}
|
||||
emptyFallback={<div className={styles.contentEmpty}>Empty</div>}
|
||||
/>
|
||||
{visible && (
|
||||
<PagePreview
|
||||
fallback={
|
||||
<>
|
||||
<Skeleton />
|
||||
<Skeleton width={'60%'} />
|
||||
</>
|
||||
}
|
||||
pageId={meta.id}
|
||||
emptyFallback={<div className={styles.contentEmpty}>Empty</div>}
|
||||
/>
|
||||
)}
|
||||
</main>
|
||||
{showTags ? <DocCardTags docId={meta.id} rows={2} /> : null}
|
||||
</WorkbenchLink>
|
||||
|
||||
Reference in New Issue
Block a user