mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
feat: init support for multiple tiles (#2585)
This commit is contained in:
5
apps/web/src/components/page-detail-editor.css.ts
Normal file
5
apps/web/src/components/page-detail-editor.css.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { globalStyle } from '@vanilla-extract/css';
|
||||
|
||||
globalStyle('.mosaic.mosaic-blueprint-theme', {
|
||||
backgroundColor: 'var(--background-color)',
|
||||
});
|
||||
@@ -1,4 +1,6 @@
|
||||
import { PageNotFoundError } from '@affine/env/constant';
|
||||
import './page-detail-editor.css';
|
||||
|
||||
import { PageNotFoundError, Unreachable } from '@affine/env/constant';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
@@ -8,12 +10,18 @@ import { useBlockSuiteWorkspacePageTitle } from '@toeverything/hooks/use-block-s
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import Head from 'next/head';
|
||||
import type React from 'react';
|
||||
import { startTransition, useCallback } from 'react';
|
||||
import { lazy, memo, startTransition, useCallback } from 'react';
|
||||
|
||||
import { currentEditorAtom, workspacePreferredModeAtom } from '../atoms';
|
||||
import type { AffineOfficialWorkspace } from '../shared';
|
||||
import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor';
|
||||
|
||||
const Mosaic = lazy(() =>
|
||||
import('react-mosaic-component').then(({ Mosaic }) => ({
|
||||
default: Mosaic,
|
||||
}))
|
||||
);
|
||||
|
||||
export type PageDetailEditorProps = {
|
||||
isPublic?: boolean;
|
||||
workspace: AffineOfficialWorkspace;
|
||||
@@ -22,19 +30,18 @@ export type PageDetailEditorProps = {
|
||||
onLoad?: (page: Page, editor: EditorContainer) => () => void;
|
||||
};
|
||||
|
||||
export const PageDetailEditor: React.FC<PageDetailEditorProps> = ({
|
||||
const EditorWrapper = memo(function EditorWrapper({
|
||||
workspace,
|
||||
pageId,
|
||||
onInit,
|
||||
onLoad,
|
||||
isPublic,
|
||||
}) => {
|
||||
}: PageDetailEditorProps) {
|
||||
const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
|
||||
const page = useBlockSuiteWorkspacePage(blockSuiteWorkspace, pageId);
|
||||
if (!page) {
|
||||
throw new PageNotFoundError(blockSuiteWorkspace, pageId);
|
||||
}
|
||||
const title = useBlockSuiteWorkspacePageTitle(blockSuiteWorkspace, pageId);
|
||||
const meta = useBlockSuitePageMeta(blockSuiteWorkspace).find(
|
||||
meta => meta.id === pageId
|
||||
);
|
||||
@@ -42,43 +49,67 @@ export const PageDetailEditor: React.FC<PageDetailEditorProps> = ({
|
||||
useAtomValue(workspacePreferredModeAtom)[pageId] ?? 'page';
|
||||
const setEditor = useSetAtom(currentEditorAtom);
|
||||
assertExists(meta);
|
||||
return (
|
||||
<Editor
|
||||
style={{
|
||||
height: 'calc(100% - 52px)',
|
||||
}}
|
||||
key={`${workspace.flavour}-${workspace.id}-${pageId}`}
|
||||
mode={isPublic ? 'page' : currentMode}
|
||||
page={page}
|
||||
onInit={useCallback(
|
||||
(page: Page, editor: Readonly<EditorContainer>) => {
|
||||
startTransition(() => {
|
||||
setEditor(editor);
|
||||
});
|
||||
onInit(page, editor);
|
||||
},
|
||||
[onInit, setEditor]
|
||||
)}
|
||||
onLoad={useCallback(
|
||||
(page: Page, editor: EditorContainer) => {
|
||||
startTransition(() => {
|
||||
setEditor(editor);
|
||||
});
|
||||
page.workspace.setPageMeta(page.id, {
|
||||
updatedDate: Date.now(),
|
||||
});
|
||||
localStorage.setItem('last_page_id', page.id);
|
||||
if (onLoad) {
|
||||
return onLoad(page, editor);
|
||||
}
|
||||
return () => {};
|
||||
},
|
||||
[onLoad, setEditor]
|
||||
)}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export const PageDetailEditor: React.FC<PageDetailEditorProps> = props => {
|
||||
const { workspace, pageId } = props;
|
||||
const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
|
||||
const page = useBlockSuiteWorkspacePage(blockSuiteWorkspace, pageId);
|
||||
if (!page) {
|
||||
throw new PageNotFoundError(blockSuiteWorkspace, pageId);
|
||||
}
|
||||
const title = useBlockSuiteWorkspacePageTitle(blockSuiteWorkspace, pageId);
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
</Head>
|
||||
<Editor
|
||||
style={{
|
||||
height: 'calc(100% - 52px)',
|
||||
<Mosaic
|
||||
onChange={useCallback(() => {}, [])}
|
||||
renderTile={id => {
|
||||
if (id === 'editor') {
|
||||
return <EditorWrapper {...props} />;
|
||||
} else {
|
||||
// @affine/copilot and other plugins will be added in the future
|
||||
throw new Unreachable();
|
||||
}
|
||||
}}
|
||||
key={`${workspace.flavour}-${workspace.id}-${pageId}`}
|
||||
mode={isPublic ? 'page' : currentMode}
|
||||
page={page}
|
||||
onInit={useCallback(
|
||||
(page: Page, editor: Readonly<EditorContainer>) => {
|
||||
startTransition(() => {
|
||||
setEditor(editor);
|
||||
});
|
||||
onInit(page, editor);
|
||||
},
|
||||
[onInit, setEditor]
|
||||
)}
|
||||
onLoad={useCallback(
|
||||
(page: Page, editor: EditorContainer) => {
|
||||
startTransition(() => {
|
||||
setEditor(editor);
|
||||
});
|
||||
page.workspace.setPageMeta(page.id, {
|
||||
updatedDate: Date.now(),
|
||||
});
|
||||
localStorage.setItem('last_page_id', page.id);
|
||||
if (onLoad) {
|
||||
return onLoad(page, editor);
|
||||
}
|
||||
return () => {};
|
||||
},
|
||||
[onLoad, setEditor]
|
||||
)}
|
||||
value="editor"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import '@affine/component/theme/global.css';
|
||||
import '@affine/component/theme/theme.css';
|
||||
import 'react-mosaic-component/react-mosaic-component.css';
|
||||
|
||||
import { WorkspaceFallback } from '@affine/component/workspace';
|
||||
import { config, setupGlobal } from '@affine/env';
|
||||
|
||||
Reference in New Issue
Block a user