mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(rich-md-editor): stop the editor flashing during an agent rewrite (#5160)
* fix(rich-md-editor): stop the editor flashing during an agent rewrite Only reveal streamed chunks that extend what's already shown. A divergent chunk (an agent rewrite/edit, e.g. removing appended text) would collapse the document to the partial result and flash on every chunk; now the current content is held in place and the final result is applied once on settle. Fresh writes still reveal live. * fix(rich-markdown-editor): seed shown-body on settled mount and track local edits Seed lastSyncedBodyRef from a settled (non-streaming) mount and update it on local edits via onUpdate, so the streaming hold engages on the very first agent rewrite chunk (no collapse/flash) and the settle still applies the rewrite that removes a local edit.
This commit is contained in:
+16
-3
@@ -158,6 +158,14 @@ export function LoadedRichMarkdownEditor({
|
||||
const [initialContent] = useState<JSONContent | string>(() =>
|
||||
streamingAtMountRef.current ? '' : parseMarkdownToDoc(splitFrontmatter(content).body)
|
||||
)
|
||||
/**
|
||||
* The body currently shown in the editor: seeded from a settled mount, updated on local edits (via
|
||||
* onUpdate) and on each streamed sync. The streaming tick reveals a chunk only when it extends this,
|
||||
* so an agent rewrite holds the current content instead of collapsing to a partial result.
|
||||
*/
|
||||
const lastSyncedBodyRef = useRef<string | null>(
|
||||
streamingAtMountRef.current ? null : splitFrontmatter(content).body
|
||||
)
|
||||
const onChangeRef = useRef(onChange)
|
||||
onChangeRef.current = onChange
|
||||
const onSaveShortcutRef = useRef(onSaveShortcut)
|
||||
@@ -263,13 +271,12 @@ export function LoadedRichMarkdownEditor({
|
||||
},
|
||||
onUpdate: ({ editor }) => {
|
||||
const md = postProcessSerializedMarkdown(editor.getMarkdown())
|
||||
lastSyncedBodyRef.current = md
|
||||
onChangeRef.current(applyFrontmatter(settledRef.current?.frontmatter ?? '', md))
|
||||
},
|
||||
})
|
||||
editorInstanceRef.current = editor
|
||||
|
||||
const lastSyncedBodyRef = useRef<string | null>(null)
|
||||
|
||||
const wasStreamingRef = useRef(streamingAtMountRef.current)
|
||||
|
||||
const pendingStreamBodyRef = useRef<string | null>(null)
|
||||
@@ -291,6 +298,12 @@ export function LoadedRichMarkdownEditor({
|
||||
streamRafRef.current = null
|
||||
return
|
||||
}
|
||||
const shownBody = lastSyncedBodyRef.current
|
||||
const extendsShown = shownBody === null || pending.startsWith(shownBody)
|
||||
if (!extendsShown) {
|
||||
streamRafRef.current = null
|
||||
return
|
||||
}
|
||||
if (
|
||||
pending.length > STREAM_REPARSE_THROTTLE_THRESHOLD &&
|
||||
performance.now() - lastStreamParseAtRef.current < STREAM_REPARSE_THROTTLE_MS
|
||||
@@ -303,7 +316,7 @@ export function LoadedRichMarkdownEditor({
|
||||
lastStreamParseAtRef.current = performance.now()
|
||||
const el = containerRef.current
|
||||
const pinnedToBottom = el ? el.scrollHeight - el.scrollTop - el.clientHeight < 80 : false
|
||||
editor.setEditable(false)
|
||||
if (editor.isEditable) editor.setEditable(false)
|
||||
editor.commands.setContent(parseMarkdownToDoc(pending), {
|
||||
contentType: 'json',
|
||||
emitUpdate: false,
|
||||
|
||||
Reference in New Issue
Block a user