From 01bca1d082c98410bda02733db03b69a840a0877 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Wed, 30 Nov 2022 20:16:34 +0800 Subject: [PATCH] feat: refactor provider --- packages/app/src/components/Header/index.tsx | 4 +- .../src/components/edgeless-toolbar/index.tsx | 2 +- .../components/editor-mode-switch/index.tsx | 4 +- packages/app/src/components/editor.tsx | 90 +++---------------- packages/app/src/components/faq/index.tsx | 6 +- .../components/theme-mode-switch/index.tsx | 2 +- packages/app/src/pages/_app.tsx | 7 +- packages/app/src/pages/index.tsx | 33 +------ .../editor-provider}/editor-provider.tsx | 14 +-- .../editor-provider}/example-markdown.ts | 2 +- .../src/providers/editor-provider/index.ts | 3 + .../editor-provider/initial-editor.tsx | 51 +++++++++++ .../src/providers/editor-provider/loading.tsx | 30 +++++++ .../src/providers/editor-provider/utils.ts | 13 +++ .../global-modal-provider.tsx | 2 +- .../{styles => providers}/themeProvider.tsx | 16 ++-- packages/app/src/styles/hooks.ts | 4 - packages/app/src/styles/index.ts | 2 - 18 files changed, 148 insertions(+), 137 deletions(-) rename packages/app/src/{components => providers/editor-provider}/editor-provider.tsx (77%) rename packages/app/src/{components => providers/editor-provider}/example-markdown.ts (94%) create mode 100644 packages/app/src/providers/editor-provider/index.ts create mode 100644 packages/app/src/providers/editor-provider/initial-editor.tsx create mode 100644 packages/app/src/providers/editor-provider/loading.tsx create mode 100644 packages/app/src/providers/editor-provider/utils.ts rename packages/app/src/{components => providers}/global-modal-provider.tsx (96%) rename packages/app/src/{styles => providers}/themeProvider.tsx (87%) delete mode 100644 packages/app/src/styles/hooks.ts diff --git a/packages/app/src/components/Header/index.tsx b/packages/app/src/components/Header/index.tsx index c18c802c9c..33c9d0495c 100644 --- a/packages/app/src/components/Header/index.tsx +++ b/packages/app/src/components/Header/index.tsx @@ -19,11 +19,11 @@ import { StyledCloseButton, StyledMenuItemWrapper, } from './styles'; -import { useEditor } from '@/components/editor-provider'; +import { useEditor } from '@/providers/editor-provider'; import EditorModeSwitch from '@/components/editor-mode-switch'; import { EdgelessIcon, PaperIcon } from '../editor-mode-switch/icons'; import ThemeModeSwitch from '@/components/theme-mode-switch'; -import { useModal } from '@/components/global-modal-provider'; +import { useModal } from '@/providers/global-modal-provider'; import CloseIcon from '@mui/icons-material/Close'; import { getWarningMessage, shouldShowWarning } from './utils'; import { Menu, MenuItem } from '@/ui/menu'; diff --git a/packages/app/src/components/edgeless-toolbar/index.tsx b/packages/app/src/components/edgeless-toolbar/index.tsx index 58a93e83d4..1625f44398 100644 --- a/packages/app/src/components/edgeless-toolbar/index.tsx +++ b/packages/app/src/components/edgeless-toolbar/index.tsx @@ -16,7 +16,7 @@ import { } from './icons'; import { Tooltip } from '@/ui/tooltip'; import Slide from '@mui/material/Slide'; -import { useEditor } from '@/components/editor-provider'; +import { useEditor } from '@/providers/editor-provider'; const toolbarList1 = [ { diff --git a/packages/app/src/components/editor-mode-switch/index.tsx b/packages/app/src/components/editor-mode-switch/index.tsx index d3d6777c9f..2d807ad857 100644 --- a/packages/app/src/components/editor-mode-switch/index.tsx +++ b/packages/app/src/components/editor-mode-switch/index.tsx @@ -11,9 +11,9 @@ import type { AnimateRadioProps, AnimateRadioItemProps, } from './type'; -import { useTheme } from '@/styles'; +import { useTheme } from '@/providers/themeProvider'; import { EdgelessIcon, PaperIcon } from './icons'; -import { useEditor } from '@/components/editor-provider'; +import { useEditor } from '@/providers/editor-provider'; const PaperItem = ({ active }: { active?: boolean }) => { const { diff --git a/packages/app/src/components/editor.tsx b/packages/app/src/components/editor.tsx index 02e56ecf0c..a8b1885526 100644 --- a/packages/app/src/components/editor.tsx +++ b/packages/app/src/components/editor.tsx @@ -1,83 +1,21 @@ -import { useEditor } from '@/components/editor-provider'; -import '@blocksuite/blocks'; -import '@blocksuite/blocks/style'; -import type { EditorContainer } from '@blocksuite/editor'; -import { BlockSchema, createEditor } from '@blocksuite/editor'; -import { forwardRef, Suspense, useEffect, useRef } from 'react'; -import pkg from '../../package.json'; -import exampleMarkdown from './example-markdown'; -import { Store } from '@blocksuite/store'; - -// eslint-disable-next-line react/display-name -const BlockSuiteEditor = forwardRef(({}, ref) => { - const containerElement = useRef(null); - useEffect(() => { - if (!containerElement.current) { - return; - } - - const store = new Store({ - // ...getEditorParams(), - }); - const space = store.createSpace('page0').register(BlockSchema); - const editor = createEditor(space); - - containerElement.current.appendChild(editor); - if (ref) { - if ('current' in ref) { - ref.current = editor; - } else { - ref(editor); - } - } - return () => { - editor.remove(); - }; - }, [ref]); - return
; -}); +import React, { useEffect, useRef } from 'react'; +import { useEditor, initDefaultContent } from '@/providers/editor-provider'; export const Editor = () => { - const editorRef = useRef(null); - const { setEditor } = useEditor(); + const editorContainer = useRef(null); + const { editor } = useEditor(); + const ref = useRef(); useEffect(() => { - if (!editorRef.current) { - return; + if (editor && ref.current?.space.id !== editor?.space.id) { + ref.current?.remove(); + ref.current = editor; + + editorContainer.current?.appendChild(editor); + + initDefaultContent(editor); } - setEditor(editorRef.current); - const { space } = editorRef.current as EditorContainer; - const pageId = space.addBlock({ - flavour: 'affine:page', - title: 'Welcome to the AFFiNE Alpha', - }); - const groupId = space.addBlock({ flavour: 'affine:group' }, pageId); - editorRef.current.clipboard.importMarkdown(exampleMarkdown, `${groupId}`); - space.resetHistory(); - }, [setEditor]); - - useEffect(() => { - const version = pkg.dependencies['@blocksuite/editor'].substring(1); - console.log(`BlockSuite live demo ${version}`); - }, []); - - return ( - Error!
}> - - - ); + }, [editor]); + return
; }; -declare global { - interface HTMLElementTagNameMap { - 'editor-container': EditorContainer; - } - - namespace JSX { - interface IntrinsicElements { - // TODO fix types on react - 'editor-container': EditorContainer; - } - } -} - export default Editor; diff --git a/packages/app/src/components/faq/index.tsx b/packages/app/src/components/faq/index.tsx index ad356ff380..23b474d52b 100644 --- a/packages/app/src/components/faq/index.tsx +++ b/packages/app/src/components/faq/index.tsx @@ -8,9 +8,9 @@ import { import { CloseIcon, ContactIcon, HelpIcon, KeyboardIcon } from './icons'; import Grow from '@mui/material/Grow'; import { Tooltip } from '@/ui/tooltip'; -import { useEditor } from '@/components/editor-provider'; -import { useModal } from '@/components/global-modal-provider'; -import { useTheme } from '@/styles'; +import { useEditor } from '@/providers/editor-provider'; +import { useModal } from '@/providers/global-modal-provider'; +import { useTheme } from '@/providers/themeProvider'; export const FAQ = () => { const [showContent, setShowContent] = useState(false); diff --git a/packages/app/src/components/theme-mode-switch/index.tsx b/packages/app/src/components/theme-mode-switch/index.tsx index ad3c32dd3f..20f6c86bdb 100644 --- a/packages/app/src/components/theme-mode-switch/index.tsx +++ b/packages/app/src/components/theme-mode-switch/index.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { useTheme } from '@/styles'; +import { useTheme } from '@/providers/themeProvider'; import { MoonIcon, SunIcon } from './icons'; import { StyledThemeModeSwitch, StyledSwitchItem } from './style'; diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index f05b941463..9b15465982 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -3,8 +3,8 @@ import dynamic from 'next/dynamic'; import '../../public/globals.css'; import '../../public/variable.css'; import './temporary.css'; -import { EditorProvider } from '@/components/editor-provider'; -import { ModalProvider } from '@/components/global-modal-provider'; +import { EditorProvider } from '@/providers/editor-provider'; +import { ModalProvider } from '@/providers/global-modal-provider'; import { Logger } from '@toeverything/pathfinder-logger'; import { WorkSpaceSliderBar } from '@/components/workspace-slider-bar'; import '@fontsource/space-mono'; @@ -14,7 +14,7 @@ import { styled } from '@/styles'; import type { ReactNode, PropsWithChildren, FC } from 'react'; import { cloneElement } from 'react'; -const ThemeProvider = dynamic(() => import('@/styles/themeProvider'), { +const ThemeProvider = dynamic(() => import('@/providers/themeProvider'), { ssr: false, }); @@ -52,7 +52,6 @@ function MyApp({ Component, pageProps }: AppProps) { ]} > - {/**/} diff --git a/packages/app/src/pages/index.tsx b/packages/app/src/pages/index.tsx index 9a73856adf..2ceee74813 100644 --- a/packages/app/src/pages/index.tsx +++ b/packages/app/src/pages/index.tsx @@ -1,11 +1,11 @@ import type { NextPage } from 'next'; -import dynamic from 'next/dynamic'; import { styled } from '@/styles'; import { Header } from '@/components/Header'; import { FAQ } from '@/components/faq'; -import Loading from '@/components/loading'; 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 }) => { @@ -23,40 +23,13 @@ const StyledWrapper = styled('div')(({ theme }) => { }; }); -const StyledLoadingContainer = styled('div')(({ theme }) => { - return { - height: '100vh', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - color: theme.colors.primaryColor, - h1: { - fontSize: '2em', - marginTop: '150px', - fontWeight: '600', - }, - }; -}); - -const DynamicEditor = dynamic(() => import('../components/editor'), { - loading: () => ( - -
- -

Loading...

-
-
- ), - ssr: false, -}); - const Home: NextPage = () => { return (
- + diff --git a/packages/app/src/components/editor-provider.tsx b/packages/app/src/providers/editor-provider/editor-provider.tsx similarity index 77% rename from packages/app/src/components/editor-provider.tsx rename to packages/app/src/providers/editor-provider/editor-provider.tsx index 52f04ceb3d..7618079e22 100644 --- a/packages/app/src/components/editor-provider.tsx +++ b/packages/app/src/providers/editor-provider/editor-provider.tsx @@ -1,12 +1,16 @@ import type { EditorContainer } from '@blocksuite/editor'; - import { createContext, useContext, useEffect, useState } from 'react'; import type { PropsWithChildren } from 'react'; +import dynamic from 'next/dynamic'; +import Loading from './loading'; + +const DynamicEditor = dynamic(() => import('./initial-editor'), { + ssr: false, +}); type EditorContextValue = { editor: EditorContainer | null; mode: EditorContainer['mode']; - setEditor: (editor: EditorContainer) => void; setMode: (mode: EditorContainer['mode']) => void; }; @@ -15,7 +19,6 @@ type EditorContextProps = PropsWithChildren<{}>; export const EditorContext = createContext({ editor: null, mode: 'page', - setEditor: () => {}, setMode: () => {}, }); @@ -33,8 +36,9 @@ export const EditorProvider = ({ }, [mode]); return ( - - {children} + + + {editor ? children : } ); }; diff --git a/packages/app/src/components/example-markdown.ts b/packages/app/src/providers/editor-provider/example-markdown.ts similarity index 94% rename from packages/app/src/components/example-markdown.ts rename to packages/app/src/providers/editor-provider/example-markdown.ts index c41368cc3c..30210ed2c3 100644 --- a/packages/app/src/components/example-markdown.ts +++ b/packages/app/src/providers/editor-provider/example-markdown.ts @@ -1,4 +1,4 @@ -const exampleMarkdown = `The AFFiNE Alpha is here! You can also view our [Official Website](https://affine.pro/)! +export const exampleMarkdown = `The AFFiNE Alpha is here! You can also view our [Official Website](https://affine.pro/)! **What's different in AFFiNE Alpha?** diff --git a/packages/app/src/providers/editor-provider/index.ts b/packages/app/src/providers/editor-provider/index.ts new file mode 100644 index 0000000000..420a6063b6 --- /dev/null +++ b/packages/app/src/providers/editor-provider/index.ts @@ -0,0 +1,3 @@ +export * from './editor-provider'; +export * from './example-markdown'; +export * from './utils'; diff --git a/packages/app/src/providers/editor-provider/initial-editor.tsx b/packages/app/src/providers/editor-provider/initial-editor.tsx new file mode 100644 index 0000000000..48c4d190b5 --- /dev/null +++ b/packages/app/src/providers/editor-provider/initial-editor.tsx @@ -0,0 +1,51 @@ +import '@blocksuite/blocks'; +import '@blocksuite/blocks/style'; +import type { EditorContainer } from '@blocksuite/editor'; +import { BlockSchema, createEditor } from '@blocksuite/editor'; +import { useEffect } from 'react'; +import pkg from '../../../package.json'; +import { createWebsocketDocProvider, Store } from '@blocksuite/store'; + +const getEditorParams = () => { + const providers = []; + const params = new URLSearchParams(location.search); + if (params.get('syncModes') === 'websocket') { + const WebsocketDocProvider = createWebsocketDocProvider( + 'ws://127.0.0.1:3000/collaboration/AFFiNE' + ); + providers.push(WebsocketDocProvider); + } + + return { + providers, + }; +}; + +const InitialEditor = ({ + setEditor, +}: { + setEditor: (editor: EditorContainer) => void; +}) => { + useEffect(() => { + const store = new Store({ + ...getEditorParams(), + }); + const space = store.createSpace('page0').register(BlockSchema); + const editor = createEditor(space); + + setEditor(editor); + + return () => { + editor.remove(); + }; + }, [setEditor]); + + useEffect(() => { + const version = pkg.dependencies['@blocksuite/editor'].substring(1); + console.log(`BlockSuite live demo ${version}`); + }, []); + + return
; +}; + +export default InitialEditor; diff --git a/packages/app/src/providers/editor-provider/loading.tsx b/packages/app/src/providers/editor-provider/loading.tsx new file mode 100644 index 0000000000..8f1383b18e --- /dev/null +++ b/packages/app/src/providers/editor-provider/loading.tsx @@ -0,0 +1,30 @@ +import { styled } from '@/styles'; +import CommonLoading from '@/components/loading'; + +const StyledLoadingContainer = styled('div')(({ theme }) => { + return { + height: '100vh', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + color: '#6880FF', + h1: { + fontSize: '2em', + marginTop: '150px', + fontWeight: '600', + }, + }; +}); + +export const Loading = () => { + return ( + +
+ +

Loading...

+
+
+ ); +}; + +export default Loading; diff --git a/packages/app/src/providers/editor-provider/utils.ts b/packages/app/src/providers/editor-provider/utils.ts new file mode 100644 index 0000000000..c2885d4880 --- /dev/null +++ b/packages/app/src/providers/editor-provider/utils.ts @@ -0,0 +1,13 @@ +import { EditorContainer } from '@blocksuite/editor'; +import exampleMarkdown from '@/providers/editor-provider/example-markdown'; + +export const initDefaultContent = (editor: EditorContainer) => { + const { space } = editor; + const pageId = space.addBlock({ + flavour: 'affine:page', + title: 'Welcome to the AFFiNE Alpha', + }); + const groupId = space.addBlock({ flavour: 'affine:group' }, pageId); + editor.clipboard.importMarkdown(exampleMarkdown, `${groupId}`); + space.resetHistory(); +}; diff --git a/packages/app/src/components/global-modal-provider.tsx b/packages/app/src/providers/global-modal-provider.tsx similarity index 96% rename from packages/app/src/components/global-modal-provider.tsx rename to packages/app/src/providers/global-modal-provider.tsx index fe4851f197..599a3171f8 100644 --- a/packages/app/src/components/global-modal-provider.tsx +++ b/packages/app/src/providers/global-modal-provider.tsx @@ -1,6 +1,6 @@ import { createContext, useContext, useState } from 'react'; import type { PropsWithChildren } from 'react'; -import ShortcutsModal from './shortcuts-modal'; +import ShortcutsModal from '@/components/shortcuts-modal'; import ContactModal from '@/components/contact-modal'; type ModalContextValue = { diff --git a/packages/app/src/styles/themeProvider.tsx b/packages/app/src/providers/themeProvider.tsx similarity index 87% rename from packages/app/src/styles/themeProvider.tsx rename to packages/app/src/providers/themeProvider.tsx index 806a52ffe8..ce397182ba 100644 --- a/packages/app/src/styles/themeProvider.tsx +++ b/packages/app/src/providers/themeProvider.tsx @@ -3,17 +3,21 @@ import { Global, css, } from '@emotion/react'; -import { createContext, useEffect, useState } from 'react'; +import { createContext, useContext, useEffect, useState } from 'react'; import type { PropsWithChildren } from 'react'; import { Theme, ThemeMode, ThemeProviderProps, ThemeProviderValue, -} from './types'; -import { getLightTheme, getDarkTheme, globalThemeVariables } from './theme'; -import { SystemThemeHelper, localStorageThemeHelper } from './utils'; -import { useEditor } from '@/components/editor-provider'; +} from '@/styles/types'; +import { + getLightTheme, + getDarkTheme, + globalThemeVariables, +} from '@/styles/theme'; +import { SystemThemeHelper, localStorageThemeHelper } from '@/styles/utils'; +import { useEditor } from '@/providers/editor-provider'; export const ThemeContext = createContext({ mode: 'light', @@ -21,6 +25,8 @@ export const ThemeContext = createContext({ theme: getLightTheme('page'), }); +export const useTheme = () => useContext(ThemeContext); + export const ThemeProvider = ({ defaultTheme = 'light', children, diff --git a/packages/app/src/styles/hooks.ts b/packages/app/src/styles/hooks.ts deleted file mode 100644 index 94398c7f36..0000000000 --- a/packages/app/src/styles/hooks.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { useContext } from 'react'; -import { ThemeContext } from './themeProvider'; - -export const useTheme = () => useContext(ThemeContext); diff --git a/packages/app/src/styles/index.ts b/packages/app/src/styles/index.ts index d65281b881..18a47af965 100644 --- a/packages/app/src/styles/index.ts +++ b/packages/app/src/styles/index.ts @@ -1,7 +1,5 @@ export type { ThemeMode, ThemeProviderProps, AffineTheme } from './types'; export * from './styled'; -export { ThemeProvider } from './themeProvider'; export * from './theme'; -export { useTheme } from './hooks'; export * from './helper';