mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +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 { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
||||
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 { useBlockSuiteWorkspacePageTitle } from '@toeverything/hooks/use-block-suite-workspace-page-title';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { describe, expect, test, vitest } from 'vitest';
|
||||
import { beforeEach } from 'vitest';
|
||||
|
||||
@@ -86,3 +88,24 @@ describe('useBlockSuiteWorkspacePageIsPublic', () => {
|
||||
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