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
@@ -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>
@@ -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>
);
};
@@ -1 +1 @@
export { TOC } from './TOC';
export { Toc } from './Toc';
@@ -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 };
@@ -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',
@@ -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<ReturnUnobserve> {
// 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();
};
}
}