fix(frontend): block duplicate sends during uploads (#1165)

* fix(frontend): block duplicate sends during uploads

Expose pre-submit upload work as a busy state so the chat input does not allow a second send while the first attachment is still uploading.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs(frontend): document upload and stream ownership

Record that thread hooks own upload-before-submit state while the chat page owns composer busy wiring, so future changes do not reintroduce duplicate socket or upload state handling.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix(frontend): separate upload busy state from streaming

Keep uploads from reusing the streaming stop state so duplicate submits are blocked without turning the composer into a stop button during file uploads.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
Ryanba
2026-03-18 15:10:27 +08:00
committed by GitHub
parent beb0eab711
commit f737fbeae8
3 changed files with 22 additions and 3 deletions

View File

@@ -32,7 +32,7 @@ export default function ChatPage() {
const { showNotification } = useNotification();
const [thread, sendMessage] = useThreadStream({
const [thread, sendMessage, isUploading] = useThreadStream({
threadId: isNewThread ? undefined : threadId,
context: settings.context,
isMock,
@@ -127,7 +127,7 @@ export default function ChatPage() {
extraHeader={
isNewThread && <Welcome mode={settings.context.mode} />
}
disabled={env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true"}
disabled={env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true" || isUploading}
onContextChange={(context) => setSettings("context", context)}
onSubmit={handleSubmit}
onStop={handleStop}