refactor: lazy load workspaces (#3091)

This commit is contained in:
Alex Yang
2023-07-07 22:15:27 +08:00
committed by GitHub
parent 66152401be
commit 283f0cd263
45 changed files with 446 additions and 750 deletions

View File

@@ -1,26 +1,47 @@
import { isBrowser } from '@affine/env/constant';
import {
rootCurrentPageIdAtom,
rootCurrentWorkspaceIdAtom,
} from '@affine/workspace/atom';
import { useAtom, useAtomValue } from 'jotai';
import { useCallback } from 'react';
import { assertExists } from '@blocksuite/global/utils';
import type { PassiveDocProvider, Workspace } from '@blocksuite/store';
import { useAtom, useSetAtom } from 'jotai';
import { useCallback, useEffect } from 'react';
import { rootCurrentWorkspaceAtom } from '../../atoms/root';
import type { AllWorkspace } from '../../shared';
import { useWorkspace } from '../use-workspace';
declare global {
/**
* @internal debug only
*/
// eslint-disable-next-line no-var
var currentWorkspace: AllWorkspace | undefined;
interface WindowEventMap {
'affine:workspace:change': CustomEvent<{ id: string }>;
}
}
export function useCurrentWorkspace(): [
AllWorkspace,
(id: string | null) => void,
] {
const currentWorkspace = useAtomValue(rootCurrentWorkspaceAtom);
const [, setId] = useAtom(rootCurrentWorkspaceIdAtom);
const [, setPageId] = useAtom(rootCurrentPageIdAtom);
const [id, setId] = useAtom(rootCurrentWorkspaceIdAtom);
assertExists(id);
const currentWorkspace = useWorkspace(id);
useEffect(() => {
globalThis.currentWorkspace = currentWorkspace;
globalThis.dispatchEvent(
new CustomEvent('affine:workspace:change', {
detail: { id: currentWorkspace.id },
})
);
}, [currentWorkspace]);
const setPageId = useSetAtom(rootCurrentPageIdAtom);
return [
currentWorkspace,
useCallback(
(id: string | null) => {
if (isBrowser && id) {
if (environment.isBrowser && id) {
localStorage.setItem('last_workspace_id', id);
}
setPageId(null);
@@ -30,3 +51,27 @@ export function useCurrentWorkspace(): [
),
];
}
const activeWorkspaceWeakMap = new WeakMap<Workspace, boolean>();
export function usePassiveWorkspaceEffect(workspace: Workspace) {
useEffect(() => {
if (activeWorkspaceWeakMap.get(workspace) === true) {
return;
}
const providers = workspace.providers.filter(
(provider): provider is PassiveDocProvider =>
'passive' in provider && provider.passive === true
);
providers.forEach(provider => {
provider.connect();
});
activeWorkspaceWeakMap.set(workspace, true);
return () => {
providers.forEach(provider => {
provider.disconnect();
});
activeWorkspaceWeakMap.delete(workspace);
};
}, [workspace]);
}