mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-10 18:36:45 +08:00
The live timeline was rendered in a separate <div> from the persisted messages list. When the streamed task finished and its ChatMessage landed, the live <div> unmounted and a new <MessageBubble> mounted — two different DOM elements showing the same content. useAutoScroll's ResizeObserver + MutationObserver fired on both the unmount and the mount, causing the visible jump-then-re-render. Merge the two paths: inject a synthetic assistant message with the pending task_id while streaming, and key every assistant bubble by task_id. When the real message arrives (same task_id), React preserves the DOM element across the invalidate → refetch window — no remount, no double scroll, no flicker. Co-authored-by: Lambda <[email protected]>