Skip to content

Commit a9def8c

Browse files
committed
♻️(frontend) create useHeadings hook
- We create the useHeadings hook to manage the headings of the document and staty DRY. - We use the headings store in IconOpenPanelEditor and TableContent, to avoid prop drilling. - We add a debounce on the onEditorContentChange to improve a bit the performance.
1 parent 69186e9 commit a9def8c

File tree

5 files changed

+42
-48
lines changed

5 files changed

+42
-48
lines changed

src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ import { useAuthStore } from '@/core/auth';
1313
import { Doc } from '@/features/docs/doc-management';
1414

1515
import { useUploadFile } from '../hook';
16+
import { useHeadings } from '../hook/useHeadings';
1617
import useSaveDoc from '../hook/useSaveDoc';
17-
import { useEditorStore, useHeadingStore } from '../stores';
18+
import { useEditorStore } from '../stores';
1819
import { randomColor } from '../utils';
1920

2021
import { BlockNoteToolbar } from './BlockNoteToolbar';
@@ -75,7 +76,6 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
7576

7677
const readOnly = !doc.abilities.partial_update;
7778
useSaveDoc(doc.id, provider.document, !readOnly);
78-
const { setHeadings, resetHeadings } = useHeadingStore();
7979
const { i18n } = useTranslation();
8080
const lang = i18n.language;
8181

@@ -126,6 +126,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
126126
},
127127
[collabName, lang, provider, uploadFile],
128128
);
129+
useHeadings(editor);
129130

130131
useEffect(() => {
131132
setEditor(editor);
@@ -135,18 +136,6 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
135136
};
136137
}, [setEditor, editor]);
137138

138-
useEffect(() => {
139-
setHeadings(editor);
140-
141-
editor?.onEditorContentChange(() => {
142-
setHeadings(editor);
143-
});
144-
145-
return () => {
146-
resetHeadings();
147-
};
148-
}, [editor, resetHeadings, setHeadings]);
149-
150139
return (
151140
<Box $css={cssEditor(readOnly)}>
152141
{errorAttachment && (
@@ -179,8 +168,7 @@ export const BlockNoteEditorVersion = ({
179168
initialContent,
180169
}: BlockNoteEditorVersionProps) => {
181170
const readOnly = true;
182-
const { setHeadings, resetHeadings } = useHeadingStore();
183-
171+
const { setEditor } = useEditorStore();
184172
const editor = useCreateBlockNote(
185173
{
186174
collaboration: {
@@ -194,18 +182,15 @@ export const BlockNoteEditorVersion = ({
194182
},
195183
[initialContent],
196184
);
185+
useHeadings(editor);
197186

198187
useEffect(() => {
199-
setHeadings(editor);
200-
201-
editor?.onEditorContentChange(() => {
202-
setHeadings(editor);
203-
});
188+
setEditor(editor);
204189

205190
return () => {
206-
resetHeadings();
191+
setEditor(undefined);
207192
};
208-
}, [editor, resetHeadings, setHeadings]);
193+
}, [setEditor, editor]);
209194

210195
return (
211196
<Box $css={cssEditor(readOnly)}>

src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import {
1515
import { Versions, useDocVersion } from '@/features/docs/doc-versioning/';
1616
import { useResponsiveStore } from '@/stores';
1717

18-
import { useHeadingStore } from '../stores';
19-
2018
import { BlockNoteEditor, BlockNoteEditorVersion } from './BlockNoteEditor';
2119
import { IconOpenPanelEditor, PanelEditor } from './PanelEditor';
2220

@@ -29,7 +27,6 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
2927
query: { versionId },
3028
} = useRouter();
3129
const { t } = useTranslation();
32-
const { headings } = useHeadingStore();
3330
const { isMobile } = useResponsiveStore();
3431

3532
const isVersion = versionId && typeof versionId === 'string';
@@ -79,9 +76,9 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
7976
) : (
8077
<BlockNoteEditor doc={doc} provider={provider} />
8178
)}
82-
{!isMobile && <IconOpenPanelEditor headings={headings} />}
79+
{!isMobile && <IconOpenPanelEditor />}
8380
</Card>
84-
<PanelEditor doc={doc} headings={headings} />
81+
<PanelEditor doc={doc} />
8582
</Box>
8683
</>
8784
);

src/frontend/apps/impress/src/features/docs/doc-editor/components/PanelEditor.tsx

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,13 @@ import { TableContent } from '@/features/docs/doc-table-content';
88
import { VersionList } from '@/features/docs/doc-versioning';
99
import { useResponsiveStore } from '@/stores';
1010

11-
import { usePanelEditorStore } from '../stores';
12-
import { HeadingBlock } from '../types';
11+
import { useHeadingStore, usePanelEditorStore } from '../stores';
1312

1413
interface PanelProps {
1514
doc: Doc;
16-
headings: HeadingBlock[];
1715
}
1816

19-
export const PanelEditor = ({
20-
doc,
21-
headings,
22-
}: PropsWithChildren<PanelProps>) => {
17+
export const PanelEditor = ({ doc }: PropsWithChildren<PanelProps>) => {
2318
const { t } = useTranslation();
2419
const { colorsTokens } = useCunninghamTheme();
2520
const { isMobile } = useResponsiveStore();
@@ -63,7 +58,7 @@ export const PanelEditor = ({
6358
`}
6459
$maxHeight="99vh"
6560
>
66-
{isMobile && <IconOpenPanelEditor headings={headings} />}
61+
{isMobile && <IconOpenPanelEditor />}
6762
<Box
6863
$direction="row"
6964
$justify="space-between"
@@ -127,7 +122,7 @@ export const PanelEditor = ({
127122
</BoxButton>
128123
)}
129124
</Box>
130-
{isPanelTableContentOpen && <TableContent headings={headings} />}
125+
{isPanelTableContentOpen && <TableContent />}
131126
{!isPanelTableContentOpen && doc.abilities.versions_list && (
132127
<VersionList doc={doc} />
133128
)}
@@ -136,11 +131,8 @@ export const PanelEditor = ({
136131
);
137132
};
138133

139-
interface IconOpenPanelEditorProps {
140-
headings: HeadingBlock[];
141-
}
142-
143-
export const IconOpenPanelEditor = ({ headings }: IconOpenPanelEditorProps) => {
134+
export const IconOpenPanelEditor = () => {
135+
const { headings } = useHeadingStore();
144136
const { t } = useTranslation();
145137
const { setIsPanelOpen, isPanelOpen, setIsPanelTableContentOpen } =
146138
usePanelEditorStore();
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { BlockNoteEditor } from '@blocknote/core';
2+
import { useEffect } from 'react';
3+
4+
import { useHeadingStore } from '../stores';
5+
6+
export const useHeadings = (editor: BlockNoteEditor) => {
7+
const { setHeadings, resetHeadings } = useHeadingStore();
8+
9+
useEffect(() => {
10+
setHeadings(editor);
11+
12+
let timeout: NodeJS.Timeout;
13+
editor?.onEditorContentChange(() => {
14+
clearTimeout(timeout);
15+
timeout = setTimeout(() => setHeadings(editor), 200);
16+
});
17+
18+
return () => {
19+
clearTimeout(timeout);
20+
resetHeadings();
21+
};
22+
}, [editor, resetHeadings, setHeadings]);
23+
};

src/frontend/apps/impress/src/features/docs/doc-table-content/components/TableContent.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@ import React, { useEffect, useState } from 'react';
22
import { useTranslation } from 'react-i18next';
33

44
import { Box, BoxButton, Text } from '@/components';
5-
import { HeadingBlock, useEditorStore } from '@/features/docs/doc-editor';
5+
import { useEditorStore, useHeadingStore } from '@/features/docs/doc-editor';
66
import { useResponsiveStore } from '@/stores';
77

88
import { Heading } from './Heading';
99

10-
interface TableContentProps {
11-
headings: HeadingBlock[];
12-
}
13-
14-
export const TableContent = ({ headings }: TableContentProps) => {
10+
export const TableContent = () => {
11+
const { headings } = useHeadingStore();
1512
const { editor } = useEditorStore();
1613
const { isMobile } = useResponsiveStore();
1714
const { t } = useTranslation();

0 commit comments

Comments
 (0)