From 91166dab8693a2cafe624a887e0a0ad67442228d Mon Sep 17 00:00:00 2001 From: Patrick Roza Date: Fri, 24 Jul 2026 22:03:02 +0200 Subject: [PATCH] Fix immediate mobile image submits --- .github/workflows/ci.yml | 3 ++ apps/web/src/components/chat/ChatComposer.tsx | 38 +++++++++++-------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3095b259a46..809d5f06e8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,6 +102,9 @@ jobs: cache: true run-install: true + - name: Ensure Electron runtime is installed + run: vp run --filter @t3tools/desktop ensure:electron + - name: Test macOS Open With integration run: vp test run apps/desktop/src/shell/DesktopOpenWith.test.ts diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index 9fd41dc112f..66bd82f9b86 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -2347,25 +2347,33 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) composerEditorRef.current?.focusAt(nextCollapsedCursor); }); }, - getSendContext: () => ({ - prompt: promptRef.current, - images: composerImagesRef.current, - terminalContexts: composerTerminalContextsRef.current, - elementContexts: composerElementContextsRef.current, - previewAnnotations: composerPreviewAnnotations, - reviewComments: composerReviewComments, - selectedPromptEffort, - selectedModelOptionsForDispatch, - selectedModelSelection, - providerAvailable: !noProviderAvailable, - selectedProvider, - selectedModel, - selectedProviderModels, - }), + getSendContext: () => { + // Store writes from the native file picker are synchronous, while the + // effect that mirrors them into refs runs after React commits. Read the + // store at submit time so a quick tap after closing iOS' picker cannot + // send the previous attachment list. + const latestDraft = getComposerDraft(composerDraftTarget); + return { + prompt: promptRef.current, + images: latestDraft?.images ?? composerImagesRef.current, + terminalContexts: latestDraft?.terminalContexts ?? composerTerminalContextsRef.current, + elementContexts: latestDraft?.elementContexts ?? composerElementContextsRef.current, + previewAnnotations: latestDraft?.previewAnnotations ?? composerPreviewAnnotations, + reviewComments: latestDraft?.reviewComments ?? composerReviewComments, + selectedPromptEffort, + selectedModelOptionsForDispatch, + selectedModelSelection, + providerAvailable: !noProviderAvailable, + selectedProvider, + selectedModel, + selectedProviderModels, + }; + }, }), [ activeThread, composerDraftTarget, + getComposerDraft, composerCursor, composerTerminalContexts, insertComposerDraftTerminalContext,