refactor: remove null type in hooks (#1955)

This commit is contained in:
Himself65
2023-04-16 21:36:32 -05:00
committed by GitHub
parent 9c517907eb
commit 3d70a36dd3
48 changed files with 149 additions and 181 deletions
+3 -3
View File
@@ -8,12 +8,12 @@ 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 { useBlockSuiteWorkspacePageIsPublic } from '@toeverything/hooks/use-blocksuite-workspace-page-is-public';
import { useBlockSuiteWorkspacePageTitle } from '@toeverything/hooks/use-blocksuite-workspace-page-title';
import { useBlockSuiteWorkspacePageIsPublic } from '@toeverything/hooks/use-block-suite-workspace-page-is-public';
import { useBlockSuiteWorkspacePageTitle } from '@toeverything/hooks/use-block-suite-workspace-page-title';
import { describe, expect, test } from 'vitest';
import { beforeEach } from 'vitest';
import { useBlockSuiteWorkspaceName } from '../use-blocksuite-workspace-name';
import { useBlockSuiteWorkspaceName } from '../use-block-suite-workspace-name';
let blockSuiteWorkspace: BlockSuiteWorkspace;
@@ -0,0 +1,60 @@
/**
* @vitest-environment happy-dom
*/
import 'fake-indexeddb/auto';
import { initPage } from '@affine/env/blocksuite';
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
import { Workspace } from '@blocksuite/store';
import { renderHook } from '@testing-library/react';
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
import { beforeEach, describe, expect, test } from 'vitest';
let blockSuiteWorkspace: Workspace;
beforeEach(() => {
blockSuiteWorkspace = new Workspace({
id: 'test',
})
.register(AffineSchemas)
.register(__unstableSchemas);
initPage(blockSuiteWorkspace.createPage('page0'));
initPage(blockSuiteWorkspace.createPage('page1'));
initPage(blockSuiteWorkspace.createPage('page2'));
});
describe('useBlockSuiteWorkspaceHelper', () => {
test('should create page', () => {
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
const helperHook = renderHook(() =>
useBlockSuiteWorkspaceHelper(blockSuiteWorkspace)
);
const pageMetaHook = renderHook(() =>
useBlockSuitePageMeta(blockSuiteWorkspace)
);
expect(pageMetaHook.result.current.length).toBe(3);
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
const page = helperHook.result.current.createPage('page4');
expect(page.id).toBe('page4');
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(4);
pageMetaHook.rerender();
expect(pageMetaHook.result.current.length).toBe(4);
});
test('milestone', async () => {
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
const helperHook = renderHook(() =>
useBlockSuiteWorkspaceHelper(blockSuiteWorkspace)
);
await helperHook.result.current.markMilestone('test');
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
initPage(helperHook.result.current.createPage('page4'));
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(4);
expect(await helperHook.result.current.listMilestone()).toHaveProperty(
'test'
);
await helperHook.result.current.revertMilestone('test');
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
});
});
@@ -0,0 +1,81 @@
import type { PageBlockModel } from '@blocksuite/blocks';
import type { PageMeta, Workspace } from '@blocksuite/store';
import { assertExists } from '@blocksuite/store';
import { useEffect, useMemo, useState } from 'react';
declare module '@blocksuite/store' {
interface PageMeta {
favorite?: boolean;
subpageIds: string[];
// If a page remove to trash, and it is a subpage, it will remove from its parent `subpageIds`, 'trashRelate' is use for save it parent
trashRelate?: string;
trash?: boolean;
trashDate?: number;
// whether to create the page with the default template
init?: boolean;
// todo: support `number` in the future
isPublic?: boolean;
isRootPinboard?: boolean;
}
}
export function useBlockSuitePageMeta(
blockSuiteWorkspace: Workspace
): PageMeta[] {
const [pageMeta, setPageMeta] = useState<PageMeta[]>(
() => blockSuiteWorkspace?.meta.pageMetas ?? []
);
const [prev, setPrev] = useState(() => blockSuiteWorkspace);
if (prev !== blockSuiteWorkspace) {
setPrev(blockSuiteWorkspace);
if (blockSuiteWorkspace) {
setPageMeta(blockSuiteWorkspace.meta.pageMetas);
}
}
useEffect(() => {
if (blockSuiteWorkspace) {
const dispose = blockSuiteWorkspace.meta.pageMetasUpdated.on(() => {
setPageMeta(blockSuiteWorkspace.meta.pageMetas);
});
return () => {
dispose.dispose();
};
}
}, [blockSuiteWorkspace]);
return pageMeta;
}
export function usePageMetaHelper(blockSuiteWorkspace: Workspace) {
return useMemo(
() => ({
setPageTitle: (pageId: string, newTitle: string) => {
assertExists(blockSuiteWorkspace);
const page = blockSuiteWorkspace.getPage(pageId);
assertExists(page);
const pageBlock = page
.getBlockByFlavour('affine:page')
.at(0) as PageBlockModel;
assertExists(pageBlock);
page.transact(() => {
pageBlock.title.delete(0, pageBlock.title.length);
pageBlock.title.insert(newTitle, 0);
});
assertExists(blockSuiteWorkspace);
blockSuiteWorkspace.meta.setPageMeta(pageId, { title: newTitle });
},
setPageMeta: (pageId: string, pageMeta: Partial<PageMeta>) => {
assertExists(blockSuiteWorkspace);
blockSuiteWorkspace.meta.setPageMeta(pageId, pageMeta);
},
getPageMeta: (pageId: string) => {
assertExists(blockSuiteWorkspace);
return blockSuiteWorkspace.meta.getPageMeta(pageId);
},
shiftPageMeta: (pageId: string, index: number) => {
assertExists(blockSuiteWorkspace);
return blockSuiteWorkspace.meta.shiftPageMeta(pageId, index);
},
}),
[blockSuiteWorkspace]
);
}
@@ -0,0 +1,41 @@
import type { Page, Workspace } from '@blocksuite/store';
import { assertExists } from '@blocksuite/store';
import {
getMilestones,
markMilestone,
revertUpdate,
} from '@toeverything/y-indexeddb';
import { useMemo } from 'react';
export function useBlockSuiteWorkspaceHelper(blockSuiteWorkspace: Workspace) {
return useMemo(
() => ({
createPage: (pageId: string, parentId?: string): Page => {
assertExists(blockSuiteWorkspace);
return blockSuiteWorkspace.createPage(pageId, parentId);
},
markMilestone: async (name: string) => {
assertExists(blockSuiteWorkspace);
const doc = blockSuiteWorkspace.doc;
await markMilestone(blockSuiteWorkspace.id, doc, name);
},
revertMilestone: async (name: string) => {
assertExists(blockSuiteWorkspace);
const doc = blockSuiteWorkspace.doc;
const list = await getMilestones(blockSuiteWorkspace.id);
if (!list) {
throw new Error('no milestone');
}
const milestone = list[name];
if (milestone) {
revertUpdate(doc, milestone, () => 'Map');
}
},
listMilestone: async () => {
assertExists(blockSuiteWorkspace);
return await getMilestones(blockSuiteWorkspace.id);
},
}),
[blockSuiteWorkspace]
);
}
@@ -1,12 +1,6 @@
import type { Page } from '@blocksuite/store';
import { useCallback, useEffect, useState } from 'react';
declare module '@blocksuite/store' {
interface PageMeta {
isPublic?: boolean;
}
}
export function useBlockSuiteWorkspacePageIsPublic(page: Page) {
const [isPublic, set] = useState<boolean>(() => page.meta.isPublic ?? false);
useEffect(() => {