mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
feat: add hook useBlockSuitePagePreview (#2603)
This commit is contained in:
@@ -9,8 +9,10 @@ import type { Page } from '@blocksuite/store';
|
|||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
|
import { useBlockSuitePagePreview } from '@toeverything/hooks/use-block-suite-page-preview';
|
||||||
import { useBlockSuiteWorkspacePageIsPublic } from '@toeverything/hooks/use-block-suite-workspace-page-is-public';
|
import { useBlockSuiteWorkspacePageIsPublic } from '@toeverything/hooks/use-block-suite-workspace-page-is-public';
|
||||||
import { useBlockSuiteWorkspacePageTitle } from '@toeverything/hooks/use-block-suite-workspace-page-title';
|
import { useBlockSuiteWorkspacePageTitle } from '@toeverything/hooks/use-block-suite-workspace-page-title';
|
||||||
|
import { useAtomValue } from 'jotai';
|
||||||
import { describe, expect, test, vitest } from 'vitest';
|
import { describe, expect, test, vitest } from 'vitest';
|
||||||
import { beforeEach } from 'vitest';
|
import { beforeEach } from 'vitest';
|
||||||
|
|
||||||
@@ -86,3 +88,24 @@ describe('useBlockSuiteWorkspacePageIsPublic', () => {
|
|||||||
expect(hook.result.current[0]).toBe(true);
|
expect(hook.result.current[0]).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('useBlockSuitePagePreview', () => {
|
||||||
|
test('basic', async () => {
|
||||||
|
const page = blockSuiteWorkspace.getPage('page0') as Page;
|
||||||
|
const id = page.addBlock(
|
||||||
|
'affine:paragraph',
|
||||||
|
{
|
||||||
|
text: new page.Text('Hello, world!'),
|
||||||
|
},
|
||||||
|
page.getBlockByFlavour('affine:frame')[0].id
|
||||||
|
);
|
||||||
|
const hook = renderHook(() => useAtomValue(useBlockSuitePagePreview(page)));
|
||||||
|
expect(hook.result.current).toBe('\nHello, world!');
|
||||||
|
page.transact(() => {
|
||||||
|
page.getBlockById(id)!.text!.insert('Test', 0);
|
||||||
|
});
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
hook.rerender();
|
||||||
|
expect(hook.result.current).toBe('\nTestHello, world!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
32
packages/hooks/src/use-block-suite-page-preview.ts
Normal file
32
packages/hooks/src/use-block-suite-page-preview.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import type { ParagraphBlockModel } from '@blocksuite/blocks/models';
|
||||||
|
import type { Page } from '@blocksuite/store';
|
||||||
|
import type { Atom } from 'jotai';
|
||||||
|
import { atom } from 'jotai';
|
||||||
|
|
||||||
|
const weakMap = new WeakMap<Page, Atom<string>>();
|
||||||
|
|
||||||
|
const getPagePreviewText = (page: Page) => {
|
||||||
|
const paragraphBlocks = page.getBlockByFlavour(
|
||||||
|
'affine:paragraph'
|
||||||
|
) as ParagraphBlockModel[];
|
||||||
|
const text = paragraphBlocks.map(block => block.text.toString()).join('\n');
|
||||||
|
return text.slice(0, 30);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useBlockSuitePagePreview(page: Page): Atom<string> {
|
||||||
|
if (weakMap.has(page)) {
|
||||||
|
return weakMap.get(page) as Atom<string>;
|
||||||
|
} else {
|
||||||
|
const baseAtom = atom<string>(getPagePreviewText(page));
|
||||||
|
baseAtom.onMount = set => {
|
||||||
|
const disposable = page.slots.yUpdated.on(() => {
|
||||||
|
set(getPagePreviewText(page));
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
disposable.dispose();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
weakMap.set(page, baseAtom);
|
||||||
|
return baseAtom;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user