mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-25 22:38:56 +08:00
refactor(store): extract workspace out of AppState (#1037)
This commit is contained in:
@@ -1,16 +1,8 @@
|
||||
import { createContext, useContext, useEffect, useState, useRef } from 'react';
|
||||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import {
|
||||
AppStateContext,
|
||||
AppStateFunction,
|
||||
AppStateValue,
|
||||
PageMeta,
|
||||
} from './interface';
|
||||
import { useGlobalState, useGlobalStateApi } from '@/store/app';
|
||||
|
||||
export interface Disposable {
|
||||
dispose(): void;
|
||||
}
|
||||
import { AppStateContext } from './interface';
|
||||
import type { Disposable } from '@blocksuite/global/utils';
|
||||
import { useGlobalState } from '@/store/app';
|
||||
|
||||
type AppStateContextProps = PropsWithChildren<Record<string, unknown>>;
|
||||
|
||||
@@ -20,113 +12,14 @@ export const useAppState = () => useContext(AppState);
|
||||
export const AppStateProvider = ({
|
||||
children,
|
||||
}: PropsWithChildren<AppStateContextProps>) => {
|
||||
const globalStateApi = useGlobalStateApi();
|
||||
const [appState, setAppState] = useState<AppStateValue>({} as AppStateValue);
|
||||
const currentDataCenterWorkspace = useGlobalState(
|
||||
store => store.currentDataCenterWorkspace
|
||||
);
|
||||
const [blobState, setBlobState] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!appState?.currentWorkspace?.blocksuiteWorkspace) {
|
||||
return;
|
||||
}
|
||||
const currentWorkspace = appState.currentWorkspace;
|
||||
const dispose = currentWorkspace?.blocksuiteWorkspace?.meta.pagesUpdated.on(
|
||||
() => {
|
||||
setAppState({
|
||||
...appState,
|
||||
pageList: currentWorkspace.blocksuiteWorkspace?.meta
|
||||
.pageMetas as PageMeta[],
|
||||
});
|
||||
}
|
||||
).dispose;
|
||||
return () => {
|
||||
dispose && dispose();
|
||||
};
|
||||
}, [appState]);
|
||||
|
||||
const onceRef = useRef(true);
|
||||
const dataCenter = useGlobalState(store => store.dataCenter);
|
||||
if (onceRef.current && dataCenter) {
|
||||
setAppState({
|
||||
workspaceList: dataCenter.workspaces,
|
||||
currentWorkspace: null,
|
||||
pageList: [],
|
||||
});
|
||||
onceRef.current = false;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// FIXME: onWorkspacesChange should have dispose function
|
||||
return dataCenter?.onWorkspacesChange(
|
||||
() => {
|
||||
setAppState(_appState => ({
|
||||
..._appState,
|
||||
workspaceList: dataCenter.workspaces,
|
||||
}));
|
||||
},
|
||||
{ immediate: false }
|
||||
);
|
||||
}, [dataCenter]);
|
||||
|
||||
const loadWorkspace: AppStateFunction['loadWorkspace'] =
|
||||
useRef() as AppStateFunction['loadWorkspace'];
|
||||
loadWorkspace.current = async (workspaceId, abort) => {
|
||||
const { dataCenter } = globalStateApi.getState();
|
||||
const { workspaceList, currentWorkspace } = appState;
|
||||
if (!workspaceList.find(v => v.id.toString() === workspaceId)) {
|
||||
return null;
|
||||
}
|
||||
if (workspaceId === currentWorkspace?.id) {
|
||||
return currentWorkspace;
|
||||
}
|
||||
|
||||
let aborted = false;
|
||||
|
||||
const onAbort = () => {
|
||||
aborted = true;
|
||||
};
|
||||
|
||||
abort?.addEventListener('abort', onAbort);
|
||||
|
||||
const workspace = (await dataCenter.loadWorkspace(workspaceId)) ?? null;
|
||||
|
||||
if (aborted) {
|
||||
// do not update state if aborted
|
||||
return null;
|
||||
}
|
||||
|
||||
let isOwner;
|
||||
if (workspace?.provider === 'local') {
|
||||
// isOwner is useful only in the cloud
|
||||
isOwner = true;
|
||||
} else {
|
||||
const userInfo = globalStateApi.getState().user;
|
||||
// We must ensure workspace.owner exists, then ensure id same.
|
||||
isOwner = workspace?.owner && userInfo?.id === workspace.owner.id;
|
||||
}
|
||||
|
||||
const pageList =
|
||||
(workspace?.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]) ?? [];
|
||||
if (workspace?.blocksuiteWorkspace) {
|
||||
globalStateApi.getState().setWorkspace(workspace.blocksuiteWorkspace);
|
||||
}
|
||||
globalStateApi.setState({
|
||||
isOwner,
|
||||
});
|
||||
|
||||
setAppState({
|
||||
...appState,
|
||||
currentWorkspace: workspace,
|
||||
pageList: pageList,
|
||||
});
|
||||
|
||||
abort?.removeEventListener('abort', onAbort);
|
||||
|
||||
return workspace;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let syncChangeDisposable: Disposable | undefined;
|
||||
const currentWorkspace = appState.currentWorkspace;
|
||||
const currentWorkspace = currentDataCenterWorkspace;
|
||||
if (!currentWorkspace) {
|
||||
return;
|
||||
}
|
||||
@@ -142,13 +35,11 @@ export const AppStateProvider = ({
|
||||
return () => {
|
||||
syncChangeDisposable?.dispose();
|
||||
};
|
||||
}, [appState.currentWorkspace]);
|
||||
}, [currentDataCenterWorkspace]);
|
||||
|
||||
return (
|
||||
<AppState.Provider
|
||||
value={{
|
||||
...appState,
|
||||
loadWorkspace: loadWorkspace,
|
||||
blobDataSynced: blobState,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { WorkspaceUnit } from '@affine/datacenter';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
|
||||
import type {
|
||||
Page as StorePage,
|
||||
PageMeta as StorePageMeta,
|
||||
} from '@blocksuite/store';
|
||||
import { MutableRefObject } from 'react';
|
||||
|
||||
export interface PageMeta extends StorePageMeta {
|
||||
favorite: boolean;
|
||||
trash: boolean;
|
||||
@@ -15,16 +14,14 @@ export interface PageMeta extends StorePageMeta {
|
||||
}
|
||||
|
||||
export type AppStateValue = {
|
||||
workspaceList: WorkspaceUnit[];
|
||||
currentWorkspace: WorkspaceUnit | null;
|
||||
pageList: PageMeta[];
|
||||
blobDataSynced?: boolean;
|
||||
blobDataSynced: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export type AppStateFunction = {
|
||||
loadWorkspace: MutableRefObject<
|
||||
(workspaceId: string, abort?: AbortSignal) => Promise<WorkspaceUnit | null>
|
||||
>;
|
||||
// todo: remove this in the future
|
||||
};
|
||||
|
||||
export type AppStateContext = AppStateValue & AppStateFunction;
|
||||
|
||||
Reference in New Issue
Block a user