diff --git a/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx b/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx index 6d9d2fac9..0bbcfb5d7 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx +++ b/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx @@ -23,7 +23,7 @@ import { useFlag } from '@toeverything/datasource/feature-flags'; import { CollapsiblePageTree } from './collapsible-page-tree'; import { Tabs } from './components/tabs'; import { TabMap, TAB_TITLE } from './components/tabs/Tabs'; -import { TOC } from './components/toc'; +import { Toc } from './components/toc'; import { WorkspaceName } from './workspace-name'; type PageProps = { @@ -92,7 +92,7 @@ export function Page(props: PageProps) { )} {activeTab === TabMap.get(TAB_TITLE.TOC).value && ( - TOC + TOC )} diff --git a/apps/ligo-virgo/src/pages/workspace/docs/components/toc/TOC.tsx b/apps/ligo-virgo/src/pages/workspace/docs/components/toc/TOC.tsx index b2c0aa693..513e2913a 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/components/toc/TOC.tsx +++ b/apps/ligo-virgo/src/pages/workspace/docs/components/toc/TOC.tsx @@ -1,6 +1,5 @@ import { BlockEditor } from '@toeverything/components/editor-core'; import { styled } from '@toeverything/components/ui'; -import { services } from '@toeverything/datasource/db-service'; import type { ReactNode } from 'react'; import { createContext, @@ -12,12 +11,9 @@ import { import { useParams } from 'react-router'; import { BLOCK_TYPES, - getPageContentById, -} from '../../utils/getPageContentById'; - -const StyledTOC = styled('div')(() => { - return {}; -}); + getContentByAsyncBlocks, + getPageTOC, +} from '../../utils/toc'; const StyledTOCItem = styled('a')<{ type?: string; isActive?: boolean }>( ({ type, isActive }) => { @@ -120,49 +116,42 @@ const renderTOCContent = tocDataSource => { ); }; -export const TOC = (props: Props) => { +export const Toc = (props: Props) => { const { editor } = props; - const { workspace_id, page_id } = useParams(); + const { page_id } = useParams(); const [tocDataSource, setTocDataSource] = useState([]); const [activeBlockId, setActiveBlockId] = useState('blockId'); const updateTocDataSource = useCallback(async () => { - const tocDataSource = await getPageContentById(editor, page_id); + const { children = [] } = + (await editor.queryByPageId(page_id))?.[0] || {}; + const asyncBlocks = (await editor.getBlockByIds(children)) || []; + const tocDataSource = getPageTOC( + asyncBlocks, + await getContentByAsyncBlocks(asyncBlocks, updateTocDataSource) + ); + setTocDataSource(tocDataSource); }, [editor, page_id]); useEffect(() => { - (async () => await updateTocDataSource())(); + (async () => { + await updateTocDataSource(); + })(); }, [updateTocDataSource]); - useEffect(() => { - let unobserve: () => void; - const observe = async () => { - unobserve = await services.api.tocService.observe( - { workspace: workspace_id, pageId: page_id }, - updateTocDataSource - ); - }; - void observe(); - - return () => { - unobserve?.(); - }; - }, [updateTocDataSource, workspace_id]); - const onClick = async (blockId?: string) => { if (blockId === activeBlockId) { return; } - console.log(blockId); setActiveBlockId(blockId); await editor.scrollManager.scrollIntoViewByBlockId(blockId); }; return ( - {renderTOCContent(tocDataSource)} +
{renderTOCContent(tocDataSource)}
); }; diff --git a/apps/ligo-virgo/src/pages/workspace/docs/components/toc/index.ts b/apps/ligo-virgo/src/pages/workspace/docs/components/toc/index.ts index e603af824..1e45e9bd0 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/components/toc/index.ts +++ b/apps/ligo-virgo/src/pages/workspace/docs/components/toc/index.ts @@ -1 +1 @@ -export { TOC } from './TOC'; +export { Toc } from './Toc'; diff --git a/apps/ligo-virgo/src/pages/workspace/docs/utils/getPageContentById.ts b/apps/ligo-virgo/src/pages/workspace/docs/utils/toc.ts similarity index 67% rename from apps/ligo-virgo/src/pages/workspace/docs/utils/getPageContentById.ts rename to apps/ligo-virgo/src/pages/workspace/docs/utils/toc.ts index b1d16cb9d..8331b0726 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/utils/getPageContentById.ts +++ b/apps/ligo-virgo/src/pages/workspace/docs/utils/toc.ts @@ -1,4 +1,4 @@ -import type { BlockEditor } from '@toeverything/components/editor-core'; +import { AsyncBlock } from '@toeverything/components/editor-core'; export const BLOCK_TYPES = { GROUP: 'group', @@ -7,23 +7,29 @@ export const BLOCK_TYPES = { HEADING3: 'heading3', }; -const getContentByAsyncBlocks = async (asyncBlocks = []) => { +/* 😞😞sorry, I don't know how to define unlimited dimensions array */ +const getContentByAsyncBlocks = async ( + asyncBlocks: AsyncBlock[] = [], + callback: () => void +): Promise => { /* maybe should recast it to tail recursion */ return await Promise.all( - asyncBlocks.map(async asyncBlock => { + asyncBlocks.map(async (asyncBlock: AsyncBlock) => { const asyncBlocks = await asyncBlock.children(); if (asyncBlocks?.length) { - return getContentByAsyncBlocks(asyncBlocks); + return getContentByAsyncBlocks(asyncBlocks, callback); } - const { id, type } = asyncBlock; + /* get update notice */ + asyncBlock.onUpdate(callback); + const { id, type } = asyncBlock; if (Object.values(BLOCK_TYPES).includes(type)) { const properties = await asyncBlock.getProperties(); return { - id: id, + id, type, text: properties?.text?.value?.[0]?.text || '', }; @@ -34,12 +40,7 @@ const getContentByAsyncBlocks = async (asyncBlocks = []) => { ); }; -const getPageContentById = async (editor: BlockEditor, pageId: string) => { - const { children = [] } = (await editor.queryByPageId(pageId))?.[0] || {}; - const asyncBlocks = (await editor.getBlockByIds(children)) || []; - - const tocContents = await getContentByAsyncBlocks(asyncBlocks); - +const getPageTOC = (asyncBlocks: AsyncBlock[], tocContents) => { return tocContents .reduce((tocGroupContent, tocContent, index) => { const { id, type } = asyncBlocks[index]; @@ -61,4 +62,4 @@ const getPageContentById = async (editor: BlockEditor, pageId: string) => { .filter(Boolean); }; -export { getPageContentById }; +export { getPageTOC, getContentByAsyncBlocks }; diff --git a/libs/datasource/db-service/src/services/index.ts b/libs/datasource/db-service/src/services/index.ts index c39119fe6..315ee8449 100644 --- a/libs/datasource/db-service/src/services/index.ts +++ b/libs/datasource/db-service/src/services/index.ts @@ -5,7 +5,6 @@ import { Database } from './database'; import { EditorBlock } from './editor-block'; import { FileService } from './file'; import { PageTree } from './workspace/page-tree'; -import { TOC } from './workspace/toc'; import { UserConfig } from './workspace/user-config'; export { @@ -49,7 +48,6 @@ export interface DbServicesMap { userConfig: UserConfig; file: FileService; commentService: CommentService; - tocService: TOC; } interface RegisterDependencyConfigWithName extends RegisterDependencyConfig { @@ -78,13 +76,6 @@ const dbServiceConfig: RegisterDependencyConfigWithName[] = [ value: PageTree, dependencies: [{ token: Database }], }, - { - type: 'class', - callName: 'tocService', - token: TOC, - value: TOC, - dependencies: [{ token: Database }], - }, { type: 'class', callName: 'userConfig', diff --git a/libs/datasource/db-service/src/services/workspace/toc.ts b/libs/datasource/db-service/src/services/workspace/toc.ts deleted file mode 100644 index 16bec3da1..000000000 --- a/libs/datasource/db-service/src/services/workspace/toc.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ServiceBaseClass } from '../base'; -import { ReturnUnobserve } from '../database/observer'; -import { ObserveCallback } from './page-tree'; - -export class TOC extends ServiceBaseClass { - private onActivePageChange?: () => void; - - async observe( - { workspace, pageId }: { workspace: string; pageId: string }, - callback: ObserveCallback - ): Promise { - // not only use observe, but also addChildrenListener is OK πŸŽ‰πŸŽ‰πŸŽ‰ - // const pageBlock = await this.getBlock(workspace, pageId); - // - // this.onActivePageChange?.(); - // pageBlock?.addChildrenListener('onPageChildrenChange', () => { - // callback(); - // }); - // - // this.onActivePageChange = () => pageBlock?.removeChildrenListener('onPageChildrenChange'); - - const unobserve = await this._observe(workspace, pageId, callback); - - return () => { - unobserve(); - }; - } -}