From 252a98309138360c7e62b61eb2c3a2d256092a46 Mon Sep 17 00:00:00 2001 From: G30 <50341825+silentoplayz@users.noreply.github.com> Date: Wed, 31 Dec 2025 08:40:35 -0500 Subject: [PATCH] fix: cross-chat data corruption and tiptap editor access errors (#20266) * fix: prevent cross-chat corruption and editor access errors * fix: safety check in Messages.svelte and cleanup in RichTextInput --- src/lib/components/chat/Messages.svelte | 4 ++ .../components/common/RichTextInput.svelte | 37 +++++++++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index 784514679..a019648a2 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -346,6 +346,10 @@ }; const saveMessage = async (messageId, message) => { + if (!history.messages?.[messageId]) { + return; + } + history.messages[messageId] = message; await updateChat(); }; diff --git a/src/lib/components/common/RichTextInput.svelte b/src/lib/components/common/RichTextInput.svelte index e4d6ddde7..688eb289e 100644 --- a/src/lib/components/common/RichTextInput.svelte +++ b/src/lib/components/common/RichTextInput.svelte @@ -416,7 +416,7 @@ }; export const setText = (text: string) => { - if (!editor) return; + if (!editor || !editor.view) return; text = text.replaceAll('\n\n', '\n'); // reset the editor content @@ -448,11 +448,13 @@ } selectNextTemplate(editor.view.state, editor.view.dispatch); + + // Ensure the editor is still valid before trying to focus focus(); }; export const insertContent = (content) => { - if (!editor) return; + if (!editor || !editor.view) return; const { state, view } = editor; const { schema, tr } = state; @@ -466,7 +468,7 @@ }; export const replaceVariables = (variables) => { - if (!editor) return; + if (!editor || !editor.view) return; const { state, view } = editor; const { doc } = state; @@ -509,11 +511,16 @@ }; export const focus = () => { - if (editor) { + if (editor && editor.view) { + // Check if the editor is destroyed + if (editor.isDestroyed) { + return; + } + try { - editor.view?.focus(); + editor.view.focus(); // Scroll to the current selection - editor.view?.dispatch(editor.view.state.tr.scrollIntoView()); + editor.view.dispatch(editor.view.state.tr.scrollIntoView()); } catch (e) { // sometimes focusing throws an error, ignore console.warn('Error focusing editor', e); @@ -743,7 +750,7 @@ }) ] : []), - ...(richText && showFormattingToolbar + ...(richText && showFormattingToolbar ? [ BubbleMenu.configure({ element: bubbleMenuElement, @@ -753,6 +760,14 @@ placement: 'top', theme: 'transparent', offset: [0, 2] + }, + shouldShow: ({ editor, view, state, oldState, from, to }) => { + // safety check + if (!editor || !editor.view || editor.isDestroyed) { + return false; + } + // default logic + return from !== to; } }), FloatingMenu.configure({ @@ -763,6 +778,14 @@ placement: floatingMenuPlacement, theme: 'transparent', offset: [-12, 4] + }, + shouldShow: ({ editor, view, state, oldState }) => { + // safety check + if (!editor || !editor.view || editor.isDestroyed) { + return false; + } + // default logic + return editor.isActive('paragraph'); } }) ]