opti: 1.adjust eventlistener;

This commit is contained in:
mitsuha
2022-08-23 20:07:35 +08:00
parent ab070daa7e
commit b96d6c37f7
6 changed files with 34 additions and 81 deletions

View File

@@ -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 editor={editorRef.current}>TOC</TOC>
<Toc editor={editorRef.current}>TOC</Toc>
)}
</WorkspaceSidebarContent>
</WorkspaceSidebar>

View File

@@ -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 (
<TOCContext.Provider value={{ activeBlockId, onClick }}>
<StyledTOC>{renderTOCContent(tocDataSource)}</StyledTOC>
<div>{renderTOCContent(tocDataSource)}</div>
</TOCContext.Provider>
);
};

View File

@@ -1 +1 @@
export { TOC } from './TOC';
export { Toc } from './Toc';

View File

@@ -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<any[]> => {
/* 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 };