mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-16 17:46:18 +08:00
feat: update editor provider
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import Router from 'next/router';
|
||||
import { useRouter } from 'next/router';
|
||||
import {
|
||||
StyledArrowButton,
|
||||
StyledListItem,
|
||||
@@ -8,18 +8,31 @@ import {
|
||||
StyledSubListItem,
|
||||
} from './style';
|
||||
import { Arrow } from './icons';
|
||||
import Link from 'next/link';
|
||||
export const WorkSpaceSliderBar = () => {
|
||||
const [show, setShow] = useState(false);
|
||||
const router = useRouter();
|
||||
return (
|
||||
<>
|
||||
<StyledSliderBar show={show}>
|
||||
<StyledListItem>Quick search</StyledListItem>
|
||||
|
||||
<StyledListItem
|
||||
onClick={() => {
|
||||
Router.push('/all-page');
|
||||
router.push({
|
||||
pathname: '/',
|
||||
query: {
|
||||
pageId: new Date().getTime().toString(),
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
All pages
|
||||
Back to Doc
|
||||
</StyledListItem>
|
||||
<StyledListItem>
|
||||
<Link href={{ pathname: '/all-page', query: { name: 'test' } }}>
|
||||
All pages
|
||||
</Link>
|
||||
</StyledListItem>
|
||||
<StyledListItem>Favourites</StyledListItem>
|
||||
<StyledSubListItem>
|
||||
|
||||
@@ -6,8 +6,6 @@ import EdgelessToolbar from '@/components/edgeless-toolbar';
|
||||
import MobileModal from '@/components/mobile-modal';
|
||||
import Editor from '@/components/editor';
|
||||
|
||||
import '@/components/simple-counter';
|
||||
|
||||
const StyledEditorContainer = styled('div')(({ theme }) => {
|
||||
return {
|
||||
height: 'calc(100vh - 60px)',
|
||||
|
||||
@@ -1,25 +1,39 @@
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { createContext, useContext, useEffect, useRef, useState } from 'react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Loading from './loading';
|
||||
import { Page, Workspace } from '@blocksuite/store';
|
||||
import { BlockSchema } from '@blocksuite/editor/dist/block-loader';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
// Blocksuite has to be imported dynamically since it has a lot of effects
|
||||
const DynamicEditor = dynamic(() => import('./initial-editor'), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
type EditorContextValue = {
|
||||
editor: EditorContainer | null;
|
||||
mode: EditorContainer['mode'];
|
||||
setMode: (mode: EditorContainer['mode']) => void;
|
||||
currentPage: Page | null;
|
||||
editor: EditorContainer | null;
|
||||
};
|
||||
|
||||
// type EditorHandlers = {
|
||||
// createPage: (props: { pageId?: string; title?: '' }) => void;
|
||||
// openPage: (props: {
|
||||
// pageId: string;
|
||||
// query?: { [key: string]: string };
|
||||
// }) => Promise<boolean>;
|
||||
// };
|
||||
|
||||
type EditorContextProps = PropsWithChildren<{}>;
|
||||
|
||||
export const EditorContext = createContext<EditorContextValue>({
|
||||
editor: null,
|
||||
mode: 'page',
|
||||
setMode: () => {},
|
||||
currentPage: null,
|
||||
editor: null,
|
||||
});
|
||||
|
||||
export const useEditor = () => useContext(EditorContext);
|
||||
@@ -27,6 +41,10 @@ export const useEditor = () => useContext(EditorContext);
|
||||
export const EditorProvider = ({
|
||||
children,
|
||||
}: PropsWithChildren<EditorContextProps>) => {
|
||||
const router = useRouter();
|
||||
const blockSchemaRef = useRef<typeof BlockSchema | null>(null);
|
||||
const [workspace, setWorkspace] = useState<Workspace | null>(null);
|
||||
const [currentPage, setCurrentPage] = useState<Page | null>(null);
|
||||
const [editor, setEditor] = useState<EditorContainer | null>(null);
|
||||
const [mode, setMode] = useState<EditorContainer['mode']>('page');
|
||||
|
||||
@@ -35,10 +53,58 @@ export const EditorProvider = ({
|
||||
window.dispatchEvent(event);
|
||||
}, [mode]);
|
||||
|
||||
const editorHandler = {
|
||||
createPage: ({
|
||||
pageId = new Date().getTime().toString(),
|
||||
title,
|
||||
}: {
|
||||
pageId?: string;
|
||||
title?: '';
|
||||
}) => {
|
||||
blockSchemaRef.current &&
|
||||
workspace?.createPage(pageId, title).register(blockSchemaRef.current);
|
||||
},
|
||||
openPage: (pageId: string, query: { [key: string]: string } = {}) => {
|
||||
return router.push({
|
||||
pathname: '/',
|
||||
query: {
|
||||
pageId,
|
||||
...query,
|
||||
},
|
||||
});
|
||||
},
|
||||
getPageList: () => {
|
||||
return workspace?.meta.pages;
|
||||
},
|
||||
deletePage: (pageId: string) => {
|
||||
workspace?.setPage(pageId, { trash: true });
|
||||
},
|
||||
recyclePage: (pageId: string) => {
|
||||
workspace?.setPage(pageId, { trash: false });
|
||||
},
|
||||
favoritePage: (pageId: string) => {
|
||||
workspace?.setPage(pageId, { favorite: true });
|
||||
},
|
||||
unFavoritePage: (pageId: string) => {
|
||||
workspace?.setPage(pageId, { favorite: true });
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<EditorContext.Provider value={{ editor, mode, setMode }}>
|
||||
<DynamicEditor setEditor={setEditor} />
|
||||
{editor ? children : <Loading />}
|
||||
<EditorContext.Provider value={{ editor, currentPage, mode, setMode }}>
|
||||
<DynamicEditor
|
||||
workspace={workspace}
|
||||
currentPage={currentPage}
|
||||
setBlockSchema={blockSchema => {
|
||||
if (!blockSchemaRef.current) {
|
||||
blockSchemaRef.current = blockSchema;
|
||||
}
|
||||
}}
|
||||
setEditor={setEditor}
|
||||
setWorkspace={setWorkspace}
|
||||
setCurrentPage={setCurrentPage}
|
||||
/>
|
||||
{workspace && currentPage && editor ? children : <Loading />}
|
||||
</EditorContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,45 +4,96 @@ import type { EditorContainer } from '@blocksuite/editor';
|
||||
import { BlockSchema, createEditor } from '@blocksuite/editor';
|
||||
import { useEffect } from 'react';
|
||||
import pkg from '../../../package.json';
|
||||
import { createWebsocketDocProvider, Workspace } from '@blocksuite/store';
|
||||
import {
|
||||
createWebsocketDocProvider,
|
||||
Workspace,
|
||||
IndexedDBDocProvider,
|
||||
Page,
|
||||
} from '@blocksuite/store';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
const getEditorParams = () => {
|
||||
const providers = [];
|
||||
const params = new URLSearchParams(location.search);
|
||||
if (params.get('syncModes') === 'websocket') {
|
||||
const room = params.get('room') ?? 'AFFINE-pathfinder';
|
||||
if (params.get('syncMode') === 'websocket') {
|
||||
const WebsocketDocProvider = createWebsocketDocProvider(
|
||||
'ws://127.0.0.1:3000/collaboration/AFFiNE'
|
||||
);
|
||||
providers.push(WebsocketDocProvider);
|
||||
}
|
||||
if (params.get('syncMode') === 'indexeddb') {
|
||||
providers.push(IndexedDBDocProvider);
|
||||
}
|
||||
|
||||
return {
|
||||
room,
|
||||
providers,
|
||||
};
|
||||
};
|
||||
|
||||
const InitialEditor = ({
|
||||
workspace,
|
||||
currentPage,
|
||||
setBlockSchema,
|
||||
setEditor,
|
||||
setWorkspace,
|
||||
setCurrentPage,
|
||||
}: {
|
||||
workspace: Workspace | null;
|
||||
currentPage: Page | null;
|
||||
setBlockSchema: (blockSchema: typeof BlockSchema) => void;
|
||||
setEditor: (editor: EditorContainer) => void;
|
||||
setWorkspace: (workspace: Workspace) => void;
|
||||
setCurrentPage: (Page: Page) => void;
|
||||
}) => {
|
||||
setBlockSchema(BlockSchema);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const store = new Workspace({
|
||||
const workspace = new Workspace({
|
||||
...getEditorParams(),
|
||||
});
|
||||
const page = store.createPage('page0').register(BlockSchema);
|
||||
const editor = createEditor(page);
|
||||
//@ts-ignore
|
||||
window.workspace = workspace;
|
||||
const indexDBProvider = workspace.providers.find(
|
||||
p => p instanceof IndexedDBDocProvider
|
||||
);
|
||||
if (indexDBProvider) {
|
||||
(indexDBProvider as IndexedDBDocProvider)?.on('synced', () => {
|
||||
setWorkspace(workspace);
|
||||
});
|
||||
} else {
|
||||
setWorkspace(workspace);
|
||||
}
|
||||
}, [setWorkspace]);
|
||||
|
||||
setEditor(editor);
|
||||
useEffect(() => {
|
||||
if (!workspace) {
|
||||
return;
|
||||
}
|
||||
let initialPage =
|
||||
workspace.pages.get(`space:${router.query.pageId}`) ??
|
||||
[...workspace.pages.values()][0];
|
||||
|
||||
return () => {
|
||||
editor.remove();
|
||||
};
|
||||
}, [setEditor]);
|
||||
if (!initialPage) {
|
||||
const pageId = `${router.query.pageId}` ?? 'page0';
|
||||
initialPage = workspace.createPage(pageId).register(BlockSchema);
|
||||
}
|
||||
setCurrentPage(initialPage);
|
||||
}, [workspace, router.query.pageId, setCurrentPage]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentPage) {
|
||||
return;
|
||||
}
|
||||
setEditor(createEditor(currentPage));
|
||||
}, [currentPage, setEditor]);
|
||||
|
||||
useEffect(() => {
|
||||
const version = pkg.dependencies['@blocksuite/editor'].substring(1);
|
||||
console.log(`BlockSuite live demo ${version}`);
|
||||
console.log(`BlockSuite version: ${version}`);
|
||||
}, []);
|
||||
|
||||
return <div />;
|
||||
|
||||
Reference in New Issue
Block a user