refactor(hooks): reduce null types (#3111)

This commit is contained in:
Alex Yang
2023-07-09 13:01:09 +08:00
committed by GitHub
parent 33644a68b2
commit 8b5d997322
8 changed files with 31 additions and 58 deletions

View File

@@ -30,7 +30,7 @@ export const WorkspaceDeleteModal = ({
onDeleteWorkspace, onDeleteWorkspace,
}: WorkspaceDeleteProps) => { }: WorkspaceDeleteProps) => {
const [workspaceName] = useBlockSuiteWorkspaceName( const [workspaceName] = useBlockSuiteWorkspaceName(
workspace.blockSuiteWorkspace ?? null workspace.blockSuiteWorkspace
); );
const [deleteStr, setDeleteStr] = useState<string>(''); const [deleteStr, setDeleteStr] = useState<string>('');
const allowDelete = deleteStr === workspaceName; const allowDelete = deleteStr === workspaceName;

View File

@@ -15,7 +15,7 @@ import {
} from './styles'; } from './styles';
export type WorkspaceSelectorProps = { export type WorkspaceSelectorProps = {
currentWorkspace: AllWorkspace | null; currentWorkspace: AllWorkspace;
onClick: () => void; onClick: () => void;
}; };
@@ -28,7 +28,7 @@ export const WorkspaceSelector: React.FC<WorkspaceSelectorProps> = ({
onClick, onClick,
}) => { }) => {
const [name] = useBlockSuiteWorkspaceName( const [name] = useBlockSuiteWorkspaceName(
currentWorkspace?.blockSuiteWorkspace ?? null currentWorkspace?.blockSuiteWorkspace
); );
const [workspace] = useCurrentWorkspace(); const [workspace] = useCurrentWorkspace();

View File

@@ -37,7 +37,7 @@ export type RootAppSidebarProps = {
onOpenQuickSearchModal: () => void; onOpenQuickSearchModal: () => void;
onOpenSettingModal: () => void; onOpenSettingModal: () => void;
onOpenWorkspaceListModal: () => void; onOpenWorkspaceListModal: () => void;
currentWorkspace: AllWorkspace | null; currentWorkspace: AllWorkspace;
openPage: (pageId: string) => void; openPage: (pageId: string) => void;
createPage: () => Page; createPage: () => Page;
currentPath: string; currentPath: string;

View File

@@ -3,14 +3,13 @@
*/ */
import 'fake-indexeddb/auto'; import 'fake-indexeddb/auto';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models'; import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import type { Page } from '@blocksuite/store'; import type { Page } 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 { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
import { describe, expect, test, vitest } from 'vitest'; import { describe, expect, test } from 'vitest';
import { beforeEach } from 'vitest'; import { beforeEach } from 'vitest';
import { useBlockSuitePagePreview } from '../use-block-suite-page-preview'; import { useBlockSuitePagePreview } from '../use-block-suite-page-preview';
@@ -52,17 +51,6 @@ describe('useBlockSuiteWorkspaceName', () => {
workspaceNameHook.result.current[1]('test 3'); workspaceNameHook.result.current[1]('test 3');
expect(blockSuiteWorkspace.meta.name).toBe('test 3'); expect(blockSuiteWorkspace.meta.name).toBe('test 3');
}); });
test('null', () => {
const workspaceNameHook = renderHook(() =>
useBlockSuiteWorkspaceName(null)
);
vitest.spyOn(globalThis.console, 'warn');
expect(workspaceNameHook.result.current[0]).toBe(UNTITLED_WORKSPACE_NAME);
workspaceNameHook.result.current[1]('test');
expect(globalThis.console.warn).toHaveBeenCalledTimes(2);
expect(workspaceNameHook.result.current[0]).toBe(UNTITLED_WORKSPACE_NAME);
});
}); });
describe('useBlockSuiteWorkspacePageTitle', () => { describe('useBlockSuiteWorkspacePageTitle', () => {

View File

@@ -1,9 +1,10 @@
import { assertExists } from '@blocksuite/global/utils';
import type { Page, Workspace } from '@blocksuite/store'; import type { Page, Workspace } from '@blocksuite/store';
import { atom, useAtomValue } from 'jotai'; import { type Atom, atom, useAtomValue } from 'jotai';
import { atomFamily } from 'jotai/utils';
import { useBlockSuiteWorkspacePage } from './use-block-suite-workspace-page'; import { useBlockSuiteWorkspacePage } from './use-block-suite-workspace-page';
const weakMap = new WeakMap<Page, Atom<string[]>>();
function getPageReferences(page: Page): string[] { function getPageReferences(page: Page): string[] {
// todo: is there a way to use page indexer to get all references? // todo: is there a way to use page indexer to get all references?
return page return page
@@ -13,26 +14,27 @@ function getPageReferences(page: Page): string[] {
.filter(Boolean); .filter(Boolean);
} }
const pageReferencesAtomFamily = atomFamily((page: Page | null) => { const getPageReferencesAtom = (page: Page) => {
if (page === null) { if (!weakMap.has(page)) {
return atom([]); const baseAtom = atom<string[]>(getPageReferences(page));
} baseAtom.onMount = set => {
const baseAtom = atom<string[]>(getPageReferences(page)); const dispose = page.slots.yUpdated.on(() => {
baseAtom.onMount = set => { set(getPageReferences(page));
const dispose = page.slots.yUpdated.on(() => { });
set(getPageReferences(page)); return () => {
}); dispose.dispose();
return () => { };
dispose.dispose();
}; };
}; weakMap.set(page, baseAtom);
return baseAtom; }
}); return weakMap.get(page) as Atom<string[]>;
};
export function useBlockSuitePageReferences( export function useBlockSuitePageReferences(
blockSuiteWorkspace: Workspace, blockSuiteWorkspace: Workspace,
pageId: string pageId: string
): string[] { ): string[] {
const page = useBlockSuiteWorkspacePage(blockSuiteWorkspace, pageId); const page = useBlockSuiteWorkspacePage(blockSuiteWorkspace, pageId);
return useAtomValue(pageReferencesAtomFamily(page)); assertExists(page);
return useAtomValue(getPageReferencesAtom(page));
} }

View File

@@ -1,4 +1,3 @@
import { assertExists } from '@blocksuite/global/utils';
import type { Page, Workspace } from '@blocksuite/store'; import type { Page, Workspace } from '@blocksuite/store';
import { useMemo } from 'react'; import { useMemo } from 'react';
@@ -6,7 +5,6 @@ export function useBlockSuiteWorkspaceHelper(blockSuiteWorkspace: Workspace) {
return useMemo( return useMemo(
() => ({ () => ({
createPage: (pageId?: string): Page => { createPage: (pageId?: string): Page => {
assertExists(blockSuiteWorkspace);
return blockSuiteWorkspace.createPage({ id: pageId }); return blockSuiteWorkspace.createPage({ id: pageId });
}, },
}), }),

View File

@@ -1,28 +1,15 @@
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant'; import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { assertExists } from '@blocksuite/global/utils';
import type { Workspace } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
import type { Atom, WritableAtom } from 'jotai'; import type { Atom, WritableAtom } from 'jotai';
import { atom, useAtom } from 'jotai'; import { atom, useAtom } from 'jotai';
const weakMap = new WeakMap< type StringAtom = WritableAtom<string, [string], void> & Atom<string>;
Workspace,
WritableAtom<string, [string], void> & Atom<string>
>();
const emptyWorkspaceNameAtom = atom(UNTITLED_WORKSPACE_NAME, () => { const weakMap = new WeakMap<Workspace, StringAtom>();
console.warn('you cannot set the name of an null workspace.');
console.warn('this is a bug in the code.');
});
export function useBlockSuiteWorkspaceName( export function useBlockSuiteWorkspaceName(blockSuiteWorkspace: Workspace) {
blockSuiteWorkspace: Workspace | null let nameAtom: StringAtom;
) { if (!weakMap.has(blockSuiteWorkspace)) {
let nameAtom:
| (WritableAtom<string, [string], void> & Atom<string>)
| undefined;
if (!blockSuiteWorkspace) {
nameAtom = emptyWorkspaceNameAtom;
} else if (!weakMap.has(blockSuiteWorkspace)) {
const baseAtom = atom<string>( const baseAtom = atom<string>(
blockSuiteWorkspace.meta.name ?? UNTITLED_WORKSPACE_NAME blockSuiteWorkspace.meta.name ?? UNTITLED_WORKSPACE_NAME
); );
@@ -44,8 +31,7 @@ export function useBlockSuiteWorkspaceName(
weakMap.set(blockSuiteWorkspace, writableAtom); weakMap.set(blockSuiteWorkspace, writableAtom);
nameAtom = writableAtom; nameAtom = writableAtom;
} else { } else {
nameAtom = weakMap.get(blockSuiteWorkspace); nameAtom = weakMap.get(blockSuiteWorkspace) as StringAtom;
assertExists(nameAtom);
} }
return useAtom(nameAtom); return useAtom(nameAtom);
} }

View File

@@ -51,6 +51,5 @@ export function useBlockSuiteWorkspacePage(
): Page | null { ): Page | null {
const pageAtom = getAtom(blockSuiteWorkspace, pageId); const pageAtom = getAtom(blockSuiteWorkspace, pageId);
assertExists(pageAtom); assertExists(pageAtom);
const page = useAtomValue(pageAtom); return useAtomValue(pageAtom);
return page;
} }