From 2b3dd004d411e803f485ededc197139cb4a3e3ef Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Sun, 5 Apr 2026 05:07:43 -0300 Subject: [PATCH] fix: multi-image drag-and-drop only showing last image insertTextAtCursor read input and cursorOffset from the React closure, which is stale when called in a synchronous loop (e.g. onImagePaste for multiple dragged images). Now uses refs so each insertion chains on the previous one. --- src/components/PromptInput/PromptInput.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/components/PromptInput/PromptInput.tsx b/src/components/PromptInput/PromptInput.tsx index 37cbec82..73bfd31d 100644 --- a/src/components/PromptInput/PromptInput.tsx +++ b/src/components/PromptInput/PromptInput.tsx @@ -1262,12 +1262,23 @@ function PromptInput({ if (isNonSpacePrintable(input, key)) return ' ' + input; return input; }, []); + // Ref mirrors cursorOffset for use in synchronous loops (e.g. multi-image + // paste) where React batches state updates and the closure value is stale. + const cursorOffsetRef = useRef(cursorOffset); + cursorOffsetRef.current = cursorOffset; + function insertTextAtCursor(text: string) { - // Push current state to buffer before inserting - pushToBuffer(input, cursorOffset, pastedContents); - const newInput = input.slice(0, cursorOffset) + text + input.slice(cursorOffset); + // Use refs for input/cursor so back-to-back calls in the same event + // (e.g. onImagePaste loop for multiple dragged images) chain correctly + // instead of each reading the same stale closure values. + const currentInput = lastInternalInputRef.current; + const currentOffset = cursorOffsetRef.current; + pushToBuffer(currentInput, currentOffset, pastedContents); + const newInput = currentInput.slice(0, currentOffset) + text + currentInput.slice(currentOffset); trackAndSetInput(newInput); - setCursorOffset(cursorOffset + text.length); + const newOffset = currentOffset + text.length; + cursorOffsetRef.current = newOffset; + setCursorOffset(newOffset); } const doublePressEscFromEmpty = useDoublePress(() => {}, () => onShowMessageSelector());