From 99131dc9175269c6b49a2f15d75363f7bc414edc Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Wed, 10 Dec 2025 10:09:20 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(frontend)=20check=20tiptap=20edito?= =?UTF-8?q?r=20in=20dom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When zooming in and out quickly, the editor instance may not be fully mounted, leading to errors when accessing its document. This commit adds checks to ensure the editor and its view are mounted before attempting to access the document, preventing potential runtime errors. --- .../docs/doc-editor/components/BlockNoteEditor.tsx | 8 +++++--- .../src/features/docs/doc-editor/hook/useHeadings.tsx | 5 +++++ .../src/features/docs/doc-editor/hook/useShortcuts.tsx | 9 +++++---- .../features/docs/doc-editor/hook/useUploadFile.tsx | 10 ++++++++++ .../docs/doc-editor/stores/useHeadingStore.tsx | 5 +++++ 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx index 1c8b2701..83a3d913 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx @@ -87,7 +87,9 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => { const { isDesktop } = useResponsiveStore(); const { isSynced: isConnectedToCollabServer } = useProviderStore(); const refEditorContainer = useRef(null); - const canSeeComment = doc.abilities.comment && isDesktop; + const canSeeComment = doc.abilities.comment; + // Determine if comments should be visible in the UI + const showComments = canSeeComment && isDesktop; useSaveDoc(doc.id, provider.document, isConnectedToCollabServer); const { i18n } = useTranslation(); @@ -207,7 +209,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => { ref={refEditorContainer} $css={css` ${cssEditor}; - ${cssComments(canSeeComment, currentUserAvatarUrl)} + ${cssComments(showComments, currentUserAvatarUrl)} `} > {errorAttachment && ( @@ -225,7 +227,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => { formattingToolbar={false} slashMenu={false} theme="light" - comments={canSeeComment} + comments={showComments} aria-label={t('Document editor')} > diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useHeadings.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useHeadings.tsx index a84626c3..6a0e11f7 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useHeadings.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useHeadings.tsx @@ -7,6 +7,11 @@ export const useHeadings = (editor: DocsBlockNoteEditor) => { const { setHeadings, resetHeadings } = useHeadingStore(); useEffect(() => { + // Check if editor and its view are mounted before accessing document + if (!editor || !editor._tiptapEditor?.view?.dom) { + return; + } + setHeadings(editor); let timeoutId: NodeJS.Timeout; diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useShortcuts.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useShortcuts.tsx index 6a03bddc..54f95c7c 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useShortcuts.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useShortcuts.tsx @@ -7,6 +7,11 @@ export const useShortcuts = ( el: HTMLDivElement | null, ) => { useEffect(() => { + // Check if editor and its view are mounted + if (!editor || !editor._tiptapEditor?.view?.dom || !el) { + return; + } + const handleKeyDown = (event: KeyboardEvent) => { if (event.key === '@' && editor?.isFocused()) { const selection = window.getSelection(); @@ -32,10 +37,6 @@ export const useShortcuts = ( } }; - if (!el) { - return; - } - el.addEventListener('keydown', handleKeyDown); return () => { diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useUploadFile.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useUploadFile.tsx index 5bea3435..4487aa8d 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useUploadFile.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useUploadFile.tsx @@ -95,6 +95,11 @@ export const useUploadStatus = (editor: DocsBlockNoteEditor) => { ); useEffect(() => { + // Check if editor and its view are mounted before accessing document + if (!editor || !editor._tiptapEditor?.view?.dom) { + return; + } + const imagesBlocks = editor?.document.filter( (block) => block.type === 'image' && block.props.url.includes(ANALYZE_URL), @@ -110,6 +115,11 @@ export const useUploadStatus = (editor: DocsBlockNoteEditor) => { * block to show analyzing status */ useEffect(() => { + // Check if editor and its view are mounted before setting up handlers + if (!editor || !editor._tiptapEditor?.view?.dom) { + return; + } + editor.onUploadEnd((blockId) => { if (!blockId) { return; diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useHeadingStore.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useHeadingStore.tsx index 17e90e3c..a403c984 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useHeadingStore.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/stores/useHeadingStore.tsx @@ -28,6 +28,11 @@ export interface UseHeadingStore { export const useHeadingStore = create((set, get) => ({ headings: [], setHeadings: (editor) => { + // Check if editor and its view are mounted before accessing document + if (!editor || !editor._tiptapEditor?.view?.dom) { + return; + } + const headingBlocks = editor?.document .filter( (block) =>