mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-19 19:16:29 +08:00
opti: 1.adjust eventlistener;
This commit is contained in:
@@ -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';
|
||||
|
||||
+14
-13
@@ -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();
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user