From 36e6da52a506e02a302f76939444bc5a9fa07d6f Mon Sep 17 00:00:00 2001 From: Qi <474021214@qq.com> Date: Tue, 14 Feb 2023 11:22:39 +0800 Subject: [PATCH] feat: modify blockhub & help island interation (#960) Co-authored-by: JimmFly --- apps/web/src/components/editor/index.tsx | 13 +----- apps/web/src/components/help-island/index.tsx | 19 +++++++- .../workspace/[workspaceId]/[pageId].tsx | 43 ++++++++++++++++--- .../providers/app-state-provider/Provider.tsx | 11 +++++ .../providers/app-state-provider/interface.ts | 3 ++ packages/i18n/src/resources/ru.json | 1 + 6 files changed, 72 insertions(+), 18 deletions(-) diff --git a/apps/web/src/components/editor/index.tsx b/apps/web/src/components/editor/index.tsx index 706fe0e9bb..35afd53e4d 100644 --- a/apps/web/src/components/editor/index.tsx +++ b/apps/web/src/components/editor/index.tsx @@ -22,27 +22,16 @@ export const Editor = ({ page, workspace, setEditor }: Props) => { const editorContainer = useRef(null); // const { currentWorkspace, currentPage, setEditor } = useAppState(); useEffect(() => { - let blockHubElement: HTMLElement | null = null; const ret = () => { const node = editorContainer.current; while (node?.firstChild) { node.removeChild(node.firstChild); } - - blockHubElement?.remove(); }; const editor = new EditorContainer(); editor.page = page; - editor.createBlockHub().then(blockHub => { - const toolWrapper = document.querySelector('#toolWrapper'); - if (!toolWrapper) { - // In an invitation page there is no toolWrapper, which contains helper icon and blockHub icon - return; - } - blockHubElement = blockHub; - toolWrapper.appendChild(blockHub); - }); + editorContainer.current?.appendChild(editor); if (page.isEmpty) { const isFirstPage = workspace?.meta.pageMetas.length === 1; diff --git a/apps/web/src/components/help-island/index.tsx b/apps/web/src/components/help-island/index.tsx index 5db1ddad0a..57cb13142f 100644 --- a/apps/web/src/components/help-island/index.tsx +++ b/apps/web/src/components/help-island/index.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { StyledIsland, StyledIconWrapper, @@ -11,6 +11,7 @@ import { Tooltip } from '@affine/component'; import { useTranslation } from '@affine/i18n'; import { useModal } from '@/store/globalModal'; import { MuiFade } from '@affine/component'; +import { useAppState } from '@/providers/app-state-provider'; export type IslandItemNames = 'contact' | 'shortcuts'; export const HelpIsland = ({ showList = ['contact', 'shortcuts'], @@ -19,7 +20,23 @@ export const HelpIsland = ({ }) => { const [spread, setShowSpread] = useState(false); const { triggerShortcutsModal, triggerContactModal } = useModal(); + const { blockHub } = useAppState(); const { t } = useTranslation(); + + useEffect(() => { + blockHub?.blockHubStatusUpdated.on(status => { + if (status) { + setShowSpread(false); + } + }); + return () => { + blockHub?.blockHubStatusUpdated.dispose(); + }; + }, [blockHub]); + + useEffect(() => { + spread && blockHub?.toggleMenu(false); + }, [blockHub, spread]); return ( import('@/components/editor'), { ssr: false, }); + +const BlockHubAppender = () => { + const { setBlockHub, editor } = useAppState(); + const setBlockHubHandler = useCallback( + (blockHub: BlockHub) => setBlockHub.current(blockHub), + [setBlockHub] + ); + useEffect(() => { + let blockHubElement: HTMLElement | null = null; + + editor?.createBlockHub().then(blockHub => { + const toolWrapper = document.querySelector('#toolWrapper'); + if (!toolWrapper) { + // In an invitation page there is no toolWrapper, which contains helper icon and blockHub icon + return; + } + blockHubElement = blockHub; + // setBlockHubHandler(blockHub); + toolWrapper.appendChild(blockHub); + }); + return () => { + blockHubElement?.remove(); + }; + }, [editor, setBlockHubHandler]); + return null; +}; + const Page: NextPageWithLayout = () => { const { currentPage, currentWorkspace, setEditor } = useAppState(); @@ -26,7 +54,9 @@ const Page: NextPageWithLayout = () => { (editor: EditorContainer) => setEditor.current(editor), [setEditor] ); + const { t } = useTranslation(); + return ( <> @@ -36,11 +66,14 @@ const Page: NextPageWithLayout = () => { {currentPage && currentWorkspace?.blocksuiteWorkspace && ( - + <> + + + )} ); diff --git a/apps/web/src/providers/app-state-provider/Provider.tsx b/apps/web/src/providers/app-state-provider/Provider.tsx index ee24b29de5..9efe1a8486 100644 --- a/apps/web/src/providers/app-state-provider/Provider.tsx +++ b/apps/web/src/providers/app-state-provider/Provider.tsx @@ -44,6 +44,7 @@ export const AppStateProvider = ({ pageList: [], currentPage: null, editor: null, + blockHub: null, synced: true, isOwner: false, }); @@ -127,6 +128,7 @@ export const AppStateProvider = ({ pageList: pageList, currentPage: null, editor: null, + blockHub: null, isOwner, }); @@ -161,6 +163,14 @@ export const AppStateProvider = ({ editor, }); }; + const setBlockHub: AppStateFunction['setBlockHub'] = + useRef() as AppStateFunction['setBlockHub']; + setBlockHub.current = blockHub => { + setAppState({ + ...appState, + blockHub, + }); + }; const login = async () => { const { dataCenter } = appState; @@ -184,6 +194,7 @@ export const AppStateProvider = ({ value={{ ...appState, setEditor, + setBlockHub, loadPage: loadPage.current, loadWorkspace: loadWorkspace, login, diff --git a/apps/web/src/providers/app-state-provider/interface.ts b/apps/web/src/providers/app-state-provider/interface.ts index ee960a0a9e..a62c8b2afd 100644 --- a/apps/web/src/providers/app-state-provider/interface.ts +++ b/apps/web/src/providers/app-state-provider/interface.ts @@ -1,5 +1,6 @@ import { DataCenter, User, WorkspaceUnit } from '@affine/datacenter'; import type { EditorContainer } from '@blocksuite/editor'; +import { BlockHub } from '@blocksuite/blocks'; import type { Page as StorePage, @@ -22,6 +23,7 @@ export type AppStateValue = { pageList: PageMeta[]; currentPage: StorePage | null; editor?: EditorContainer | null; + blockHub?: BlockHub | null; synced: boolean; isOwner?: boolean; blobDataSynced?: boolean; @@ -29,6 +31,7 @@ export type AppStateValue = { export type AppStateFunction = { setEditor: MutableRefObject<(page: EditorContainer) => void>; + setBlockHub: MutableRefObject<(BlockHub: BlockHub) => void>; loadWorkspace: MutableRefObject< (workspaceId: string) => Promise diff --git a/packages/i18n/src/resources/ru.json b/packages/i18n/src/resources/ru.json index 1f1850ec9a..adc17a05aa 100644 --- a/packages/i18n/src/resources/ru.json +++ b/packages/i18n/src/resources/ru.json @@ -167,6 +167,7 @@ "Shortcuts": "Ярлыки", "Share with link": "Поделиться ссылкой", "Set up an AFFiNE account to sync data": "Настройте учетную запись AFFiNE для синхронизации данных", + "Restore it": "Восстановить", "Reduce indent": "Уменьшить отступ", "Got it": "Понятно", "Get in touch!": "Связаться!",