refactor: use jotai-effect (#4641)

This commit is contained in:
Alex Yang
2023-10-17 16:09:37 -05:00
committed by GitHub
parent 62d2b09e3c
commit a430266389
16 changed files with 79 additions and 206 deletions
+4 -2
View File
@@ -19,10 +19,11 @@ import {
globalBlockSuiteSchema,
} from '@affine/workspace/manager';
import { createIndexedDBDownloadProvider } from '@affine/workspace/providers';
import { useStaticBlockSuiteWorkspace } from '@toeverything/infra/__internal__/react';
import { getBlockSuiteWorkspaceAtom } from '@toeverything/infra/__internal__/workspace';
import { getCurrentStore } from '@toeverything/infra/atom';
import { initEmptyPage } from '@toeverything/infra/blocksuite';
import { buildShowcaseWorkspace } from '@toeverything/infra/blocksuite';
import { useAtomValue } from 'jotai';
import { nanoid } from 'nanoid';
import { useCallback } from 'react';
@@ -87,7 +88,8 @@ export const LocalAdapter: WorkspaceAdapter<WorkspaceFlavour.LOCAL> = {
Header: WorkspaceHeader,
Provider,
PageDetail: ({ currentWorkspaceId, currentPageId, onLoadEditor }) => {
const workspace = useStaticBlockSuiteWorkspace(currentWorkspaceId);
const [workspaceAtom] = getBlockSuiteWorkspaceAtom(currentWorkspaceId);
const workspace = useAtomValue(workspaceAtom);
const page = workspace.getPage(currentPageId);
if (!page) {
throw new PageNotFoundError(workspace, currentPageId);
@@ -11,7 +11,7 @@ import { Avatar } from '@toeverything/components/avatar';
import { Tooltip } from '@toeverything/components/tooltip';
import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-block-suite-workspace-avatar-url';
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
import { useStaticBlockSuiteWorkspace } from '@toeverything/infra/__internal__/react';
import { getBlockSuiteWorkspaceAtom } from '@toeverything/infra/__internal__/workspace';
import clsx from 'clsx';
import { useAtom, useAtomValue } from 'jotai/react';
import { type ReactElement, Suspense, useCallback, useMemo } from 'react';
@@ -209,7 +209,8 @@ const WorkspaceListItem = ({
isCurrent: boolean;
isActive: boolean;
}) => {
const workspace = useStaticBlockSuiteWorkspace(meta.id);
const [workspaceAtom] = getBlockSuiteWorkspaceAtom(meta.id);
const workspace = useAtomValue(workspaceAtom);
const [workspaceAvatar] = useBlockSuiteWorkspaceAvatarUrl(workspace);
const [workspaceName] = useBlockSuiteWorkspaceName(workspace);
@@ -3,7 +3,6 @@ import { WorkspaceSubPath } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
import { usePassiveWorkspaceEffect } from '@toeverything/infra/__internal__/react';
import { useSetAtom } from 'jotai';
import { useAtomValue } from 'jotai';
import { useCallback } from 'react';
@@ -34,7 +33,6 @@ export const WorkspaceSetting = ({ workspaceId }: { workspaceId: string }) => {
const pushNotification = useSetAtom(pushNotificationAtom);
const leaveWorkspace = useLeaveWorkspace();
usePassiveWorkspaceEffect(workspace.blockSuiteWorkspace);
const setSettingModal = useSetAtom(openSettingModalAtom);
const { deleteWorkspace } = useAppHelper();
@@ -7,7 +7,7 @@ import { useAtom, useSetAtom } from 'jotai';
import { useCallback, useEffect } from 'react';
import type { AllWorkspace } from '../../shared';
import { useWorkspace } from '../use-workspace';
import { useWorkspace, useWorkspaceEffect } from '../use-workspace';
declare global {
/**
@@ -27,6 +27,8 @@ export function useCurrentWorkspace(): [
const [id, setId] = useAtom(currentWorkspaceIdAtom);
assertExists(id);
const currentWorkspace = useWorkspace(id);
// when you call current workspace, effect is always called
useWorkspaceEffect(currentWorkspace.id);
useEffect(() => {
globalThis.currentWorkspace = currentWorkspace;
globalThis.dispatchEvent(
+15 -8
View File
@@ -2,7 +2,7 @@ import type { AffineOfficialWorkspace } from '@affine/env/workspace';
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
import { assertExists } from '@blocksuite/global/utils';
import type { Workspace } from '@blocksuite/store';
import { useStaticBlockSuiteWorkspace } from '@toeverything/infra/__internal__/react';
import { getBlockSuiteWorkspaceAtom } from '@toeverything/infra/__internal__/workspace';
import type { Atom } from 'jotai';
import { atom, useAtomValue } from 'jotai';
@@ -11,9 +11,18 @@ const workspaceWeakMap = new WeakMap<
Atom<Promise<AffineOfficialWorkspace>>
>();
// workspace effect is the side effect like connect to the server/indexeddb,
// this will save the workspace updates permanently.
export function useWorkspaceEffect(workspaceId: string): void {
const [, effectAtom] = getBlockSuiteWorkspaceAtom(workspaceId);
useAtomValue(effectAtom);
}
// todo(himself65): remove this hook
export function useWorkspace(workspaceId: string): AffineOfficialWorkspace {
const blockSuiteWorkspace = useStaticBlockSuiteWorkspace(workspaceId);
if (!workspaceWeakMap.has(blockSuiteWorkspace)) {
const [workspaceAtom] = getBlockSuiteWorkspaceAtom(workspaceId);
const workspace = useAtomValue(workspaceAtom);
if (!workspaceWeakMap.has(workspace)) {
const baseAtom = atom(async get => {
const metadata = await get(rootWorkspacesMetadataAtom);
const flavour = metadata.find(({ id }) => id === workspaceId)?.flavour;
@@ -21,15 +30,13 @@ export function useWorkspace(workspaceId: string): AffineOfficialWorkspace {
return {
id: workspaceId,
flavour,
blockSuiteWorkspace,
blockSuiteWorkspace: workspace,
};
});
workspaceWeakMap.set(blockSuiteWorkspace, baseAtom);
workspaceWeakMap.set(workspace, baseAtom);
}
return useAtomValue(
workspaceWeakMap.get(blockSuiteWorkspace) as Atom<
Promise<AffineOfficialWorkspace>
>
workspaceWeakMap.get(workspace) as Atom<Promise<AffineOfficialWorkspace>>
);
}
@@ -28,7 +28,6 @@ import {
useSensors,
} from '@dnd-kit/core';
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
import { usePassiveWorkspaceEffect } from '@toeverything/infra/__internal__/react';
import { currentWorkspaceIdAtom } from '@toeverything/infra/atom';
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import { nanoid } from 'nanoid';
@@ -172,8 +171,6 @@ export const WorkspaceLayoutInner = ({
}
}, [currentWorkspace.blockSuiteWorkspace.doc]);
usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace);
const handleCreatePage = useCallback(() => {
const id = nanoid();
pageHelper.createPage(id);
+2 -2
View File
@@ -1,7 +1,7 @@
import { useCollectionManager } from '@affine/component/page-list';
import { WorkspaceSubPath } from '@affine/env/workspace';
import { assertExists } from '@blocksuite/global/utils';
import { getActiveBlockSuiteWorkspaceAtom } from '@toeverything/infra/__internal__/workspace';
import { getBlockSuiteWorkspaceAtom } from '@toeverything/infra/__internal__/workspace';
import { getCurrentStore } from '@toeverything/infra/atom';
import { useCallback } from 'react';
import type { LoaderFunction } from 'react-router-dom';
@@ -16,7 +16,7 @@ export const loader: LoaderFunction = async args => {
const rootStore = getCurrentStore();
const workspaceId = args.params.workspaceId;
assertExists(workspaceId);
const workspaceAtom = getActiveBlockSuiteWorkspaceAtom(workspaceId);
const [workspaceAtom] = getBlockSuiteWorkspaceAtom(workspaceId);
const workspace = await rootStore.get(workspaceAtom);
for (const pageId of workspace.pages.keys()) {
const page = workspace.getPage(pageId);
+2 -2
View File
@@ -1,6 +1,6 @@
import { WorkspaceFlavour } from '@affine/env/workspace';
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
import { getActiveBlockSuiteWorkspaceAtom } from '@toeverything/infra/__internal__/workspace';
import { getBlockSuiteWorkspaceAtom } from '@toeverything/infra/__internal__/workspace';
import {
currentPageIdAtom,
currentWorkspaceIdAtom,
@@ -31,7 +31,7 @@ export const loader: LoaderFunction = async args => {
rootStore.set(currentPageIdAtom, null);
}
if (currentMetadata.flavour === WorkspaceFlavour.AFFINE_CLOUD) {
const workspaceAtom = getActiveBlockSuiteWorkspaceAtom(currentMetadata.id);
const [workspaceAtom] = getBlockSuiteWorkspaceAtom(currentMetadata.id);
const workspace = await rootStore.get(workspaceAtom);
return (() => {
const blockVersions = workspace.meta.blockVersions;