From 85838c77a101cad77941ba2c4f3b3f13ff462ca0 Mon Sep 17 00:00:00 2001 From: mitsuha Date: Tue, 23 Aug 2022 21:25:38 +0800 Subject: [PATCH] opti: 1.adjust eventlistener; --- .../workspace/docs/components/toc/TOC.tsx | 15 +++- .../src/pages/workspace/docs/utils/toc.ts | 79 +++++++++++++------ 2 files changed, 66 insertions(+), 28 deletions(-) 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 513e2913a6..be567780f7 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 @@ -11,8 +11,10 @@ import { import { useParams } from 'react-router'; import { BLOCK_TYPES, + destroyEventList, getContentByAsyncBlocks, getPageTOC, + type TocType, } from '../../utils/toc'; const StyledTOCItem = styled('a')<{ type?: string; isActive?: boolean }>( @@ -119,19 +121,24 @@ const renderTOCContent = tocDataSource => { export const Toc = (props: Props) => { const { editor } = props; const { page_id } = useParams(); - const [tocDataSource, setTocDataSource] = useState([]); - const [activeBlockId, setActiveBlockId] = useState('blockId'); + const [tocDataSource, setTocDataSource] = useState([]); + const [activeBlockId, setActiveBlockId] = useState(''); + const [blockEventListeners, setBlockEventListeners] = useState([]); const updateTocDataSource = useCallback(async () => { + destroyEventList(blockEventListeners); + const { children = [] } = (await editor.queryByPageId(page_id))?.[0] || {}; const asyncBlocks = (await editor.getBlockByIds(children)) || []; - const tocDataSource = getPageTOC( + const { tocContents, eventListeners } = await getContentByAsyncBlocks( asyncBlocks, - await getContentByAsyncBlocks(asyncBlocks, updateTocDataSource) + updateTocDataSource ); + const tocDataSource = getPageTOC(asyncBlocks, tocContents); setTocDataSource(tocDataSource); + setBlockEventListeners(eventListeners); }, [editor, page_id]); useEffect(() => { diff --git a/apps/ligo-virgo/src/pages/workspace/docs/utils/toc.ts b/apps/ligo-virgo/src/pages/workspace/docs/utils/toc.ts index 8331b0726d..2ef9a39032 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/utils/toc.ts +++ b/apps/ligo-virgo/src/pages/workspace/docs/utils/toc.ts @@ -1,5 +1,11 @@ import { AsyncBlock } from '@toeverything/components/editor-core'; +export type TocType = { + id: string; + type: string; + text: string; +}; + export const BLOCK_TYPES = { GROUP: 'group', HEADING1: 'heading1', @@ -11,36 +17,51 @@ export const BLOCK_TYPES = { const getContentByAsyncBlocks = async ( asyncBlocks: AsyncBlock[] = [], callback: () => void -): Promise => { - /* maybe should recast it to tail recursion */ - return await Promise.all( - asyncBlocks.map(async (asyncBlock: AsyncBlock) => { - const asyncBlocks = await asyncBlock.children(); +): Promise<{ + tocContents: any[]; + eventListeners: (() => void | undefined)[]; +}> => { + const eventListeners = []; - if (asyncBlocks?.length) { - return getContentByAsyncBlocks(asyncBlocks, callback); - } + const collect = async (asyncBlocks): Promise => { + /* maybe should recast it to tail recursion */ + return await Promise.all( + asyncBlocks.map(async (asyncBlock: AsyncBlock) => { + const asyncBlocks = await asyncBlock.children(); - /* get update notice */ - asyncBlock.onUpdate(callback); + if (asyncBlocks?.length) { + return collect(asyncBlocks); + } - const { id, type } = asyncBlock; - if (Object.values(BLOCK_TYPES).includes(type)) { - const properties = await asyncBlock.getProperties(); + /* get update notice */ + const destroyHandler = asyncBlock.onUpdate(callback); - return { - id, - type, - text: properties?.text?.value?.[0]?.text || '', - }; - } + /* collect destroy handlers */ + eventListeners.push(destroyHandler); - return null; - }) - ); + const { id, type } = asyncBlock; + if (Object.values(BLOCK_TYPES).includes(type)) { + const properties = await asyncBlock.getProperties(); + + return { + id, + type, + text: properties?.text?.value?.[0]?.text || '', + }; + } + + return null; + }) + ); + }; + + return { + tocContents: await collect(asyncBlocks), + eventListeners, + }; }; -const getPageTOC = (asyncBlocks: AsyncBlock[], tocContents) => { +const getPageTOC = (asyncBlocks: AsyncBlock[], tocContents): TocType[] => { return tocContents .reduce((tocGroupContent, tocContent, index) => { const { id, type } = asyncBlocks[index]; @@ -62,4 +83,14 @@ const getPageTOC = (asyncBlocks: AsyncBlock[], tocContents) => { .filter(Boolean); }; -export { getPageTOC, getContentByAsyncBlocks }; +const destroyEventList = ( + eventListeners: (() => void | undefined)[] = [] +): boolean => { + for (const eventListener of eventListeners) { + eventListener?.(); + } + + return true; +}; + +export { getPageTOC, getContentByAsyncBlocks, destroyEventList };