feat: workspace setting

This commit is contained in:
DiamondThree
2023-01-09 21:19:02 +08:00
11 changed files with 128 additions and 405 deletions

View File

@@ -1,25 +0,0 @@
import { useEffect } from 'react';
import type { Page } from '@blocksuite/store';
import '@blocksuite/blocks';
import { EditorContainer } from '@blocksuite/editor';
import { CreateEditorHandler } from './interface';
type Props = {
setCreateEditorHandler: (handler: CreateEditorHandler) => void;
};
const DynamicBlocksuite = ({ setCreateEditorHandler }: Props) => {
useEffect(() => {
const createEditorHandler: CreateEditorHandler = (page: Page) => {
const editor = new EditorContainer();
editor.page = page;
return editor;
};
setCreateEditorHandler(createEditorHandler);
}, [setCreateEditorHandler]);
return <></>;
};
export default DynamicBlocksuite;

View File

@@ -1,22 +1,16 @@
import {
createContext,
useCallback,
useContext,
useEffect,
useState,
} from 'react';
import { createContext, useContext, useEffect, useState, useRef } from 'react';
import type { PropsWithChildren } from 'react';
import { getDataCenter } from '@affine/datacenter';
import { AppStateContext, AppStateValue } from './interface';
import {
AppStateContext,
AppStateFunction,
AppStateValue,
PageMeta,
} from './interface';
import { createDefaultWorkspace } from './utils';
type AppStateContextProps = PropsWithChildren<Record<string, unknown>>;
import dynamic from 'next/dynamic';
import { CreateEditorHandler } from '@/providers/app-state-provider3';
const DynamicBlocksuite = dynamic(() => import('./DynamicBlocksuite'), {
ssr: false,
});
export const AppState = createContext<AppStateContext>({} as AppStateContext);
export const useAppState = () => useContext(AppState);
@@ -26,16 +20,6 @@ export const AppStateProvider = ({
}: PropsWithChildren<AppStateContextProps>) => {
const [appState, setAppState] = useState<AppStateValue>({} as AppStateValue);
const [createEditorHandler, _setCreateEditorHandler] =
useState<CreateEditorHandler>();
const setCreateEditorHandler = useCallback(
(handler: CreateEditorHandler) => {
_setCreateEditorHandler(() => handler);
},
[_setCreateEditorHandler]
);
useEffect(() => {
const init = async () => {
const dataCenter = await getDataCenter();
@@ -55,11 +39,11 @@ export const AppStateProvider = ({
setAppState({
dataCenter,
user: await dataCenter.getUserInfo(),
user: (await dataCenter.getUserInfo()) || null,
workspaceList: dataCenter.workspaces,
currentWorkspaceId: dataCenter.workspaces[0].id,
currentWorkspace,
pageList: currentWorkspace.meta.pageMetas,
pageList: currentWorkspace.meta.pageMetas as PageMeta[],
currentPage: null,
editor: null,
synced: true,
@@ -78,7 +62,7 @@ export const AppStateProvider = ({
const dispose = currentWorkspace.meta.pagesUpdated.on(() => {
setAppState({
...appState,
pageList: currentWorkspace.meta.pageMetas,
pageList: currentWorkspace.meta.pageMetas as PageMeta[],
});
}).dispose;
return () => {
@@ -97,7 +81,8 @@ export const AppStateProvider = ({
});
}, [appState]);
const loadPage = (pageId: string) => {
const loadPage = useRef<AppStateFunction['loadPage']>();
loadPage.current = (pageId: string) => {
const { currentWorkspace, currentPage } = appState;
if (pageId === currentPage?.id) {
return;
@@ -109,13 +94,15 @@ export const AppStateProvider = ({
});
};
const loadWorkspace = async (workspaceId: string) => {
const { dataCenter, workspaceList, currentWorkspaceId } = appState;
const loadWorkspace = useRef<AppStateFunction['loadWorkspace']>();
loadWorkspace.current = async (workspaceId: string) => {
const { dataCenter, workspaceList, currentWorkspaceId, currentWorkspace } =
appState;
if (!workspaceList.find(v => v.id === workspaceId)) {
return;
return null;
}
if (workspaceId === currentWorkspaceId) {
return;
return currentWorkspace;
}
const workspace = await dataCenter.loadWorkspace(workspaceId);
const currentMetaWorkSpace = dataCenter.workspaces.find(item => {
@@ -127,32 +114,13 @@ export const AppStateProvider = ({
currentWorkspaceId: workspaceId,
currentMetaWorkSpace: currentMetaWorkSpace ?? null,
});
return workspace;
};
const createEditor = () => {
const { currentPage, currentWorkspace } = appState;
if (!currentPage || !currentWorkspace) {
return null;
}
const editor = createEditorHandler?.(currentPage) || null;
if (editor) {
const pageMeta = currentWorkspace.meta.pageMetas.find(
p => p.id === currentPage.id
);
if (pageMeta?.mode) {
editor.mode = pageMeta.mode as 'page' | 'edgeless' | undefined;
}
if (pageMeta?.trash) {
editor.readonly = true;
}
}
return editor;
};
const setEditor = (editor: AppStateValue['editor']) => {
const setEditor: AppStateFunction['setEditor'] =
useRef() as AppStateFunction['setEditor'];
setEditor.current = editor => {
setAppState({
...appState,
editor,
@@ -164,16 +132,11 @@ export const AppStateProvider = ({
value={{
...appState,
setEditor,
loadPage,
loadWorkspace,
createEditor,
loadPage: loadPage.current,
loadWorkspace: loadWorkspace.current,
}}
>
<DynamicBlocksuite setCreateEditorHandler={setCreateEditorHandler} />
{children}
</AppState.Provider>
);
};
export default AppStateProvider;

View File

@@ -1 +1,2 @@
export * from './Provider';
export * from './interface';

View File

@@ -4,12 +4,20 @@ import type { EditorContainer } from '@blocksuite/editor';
import type {
Page as StorePage,
Workspace as StoreWorkspace,
PageMeta,
PageMeta as StorePageMeta,
} from '@blocksuite/store';
import { MutableRefObject } from 'react';
export interface PageMeta extends StorePageMeta {
favorite: boolean;
trash: boolean;
trashDate: number;
updatedDate: number;
mode: 'edgeless' | 'page';
}
export type AppStateValue = {
dataCenter: DataCenter;
user: User | undefined;
user: User | null;
workspaceList: Workspace[];
currentWorkspace: StoreWorkspace;
currentMetaWorkSpace: Workspace | null;
@@ -21,9 +29,9 @@ export type AppStateValue = {
};
export type AppStateFunction = {
createEditor: (page: StorePage) => EditorContainer | null;
setEditor: (page: EditorContainer) => void;
loadWorkspace: (workspaceId: string) => Promise<void>;
setEditor: MutableRefObject<(page: EditorContainer) => void>;
loadWorkspace: (workspaceId: string) => Promise<StoreWorkspace | null>;
loadPage: (pageId: string) => void;
};