From 900a6d6dbdbf4ae88a6995bb0d1eaba174e067f4 Mon Sep 17 00:00:00 2001 From: guantw Date: Sat, 12 Sep 2026 15:05:27 +0800 Subject: [PATCH] fix(input): preserve image previews after session switches Read the latest composer layout callback from delayed DOM measurements and collapse confirmations so restored image attachments keep the input expanded. Coalesce pending DOM measurement frames and track the observer's stable dependency. --- src/web-ui/src/flow_chat/components/ChatInput.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/web-ui/src/flow_chat/components/ChatInput.tsx b/src/web-ui/src/flow_chat/components/ChatInput.tsx index 9b6bf20153..ebcc1b0e81 100644 --- a/src/web-ui/src/flow_chat/components/ChatInput.tsx +++ b/src/web-ui/src/flow_chat/components/ChatInput.tsx @@ -935,7 +935,7 @@ export const ChatInput: React.FC = ({ } collapseVerificationRafRef.current = requestAnimationFrame(() => { collapseVerificationRafRef.current = null; - measureIsMultiLine('collapse-confirmation'); + measureIsMultiLineRef.current?.('collapse-confirmation'); }); return; } @@ -962,8 +962,10 @@ export const ChatInput: React.FC = ({ if (!el) return; let rafId: number; const observer = new MutationObserver(() => { + cancelAnimationFrame(rafId); rafId = requestAnimationFrame(() => { - measureIsMultiLine('mutation-observer'); + // Session restoration can change attachments after this observer mounts. + measureIsMultiLineRef.current?.('mutation-observer'); checkDomEmpty(); }); }); @@ -972,9 +974,7 @@ export const ChatInput: React.FC = ({ observer.disconnect(); cancelAnimationFrame(rafId); }; - // measureIsMultiLine / checkDomEmpty capture latest closure values - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [checkDomEmpty]); useEffect(() => { const containerEl = containerRef.current;