Skip to content

Commit 447f16f

Browse files
authored
Studio: fix composer reset after failed send (#7377)
* fix composer reset * Studio: clear composer draft on send * Studio: cancel the pending draft save when clearing on send
1 parent a266926 commit 447f16f

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

  • studio/frontend/src/components/assistant-ui

studio/frontend/src/components/assistant-ui/thread.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,7 @@ const Composer: FC<{
15561556
const draftThreadId = referenceThreadId;
15571557
const draftKey = draftThreadId ? composerDraftKey(draftThreadId) : null;
15581558
const lastDraftKeyRef = useRef(draftKey);
1559+
const draftSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
15591560
useEffect(() => {
15601561
const draft = draftKey ? (readComposerDraft(draftKey) ?? "") : "";
15611562
const composer = aui.composer();
@@ -1574,8 +1575,25 @@ const Composer: FC<{
15741575
return;
15751576
}
15761577
const t = setTimeout(() => writeComposerDraft(draftKey, composerText), 300);
1578+
draftSaveTimerRef.current = t;
15771579
return () => clearTimeout(t);
15781580
}, [composerText, draftKey]);
1581+
// Without this the restore effect above puts the sent text back when the
1582+
// runtime rebinds on the first message.
1583+
const draftKeyRef = useRef(draftKey);
1584+
useEffect(() => {
1585+
draftKeyRef.current = draftKey;
1586+
}, [draftKey]);
1587+
const clearStoredDraft = useCallback(() => {
1588+
if (draftSaveTimerRef.current !== null) {
1589+
clearTimeout(draftSaveTimerRef.current);
1590+
draftSaveTimerRef.current = null;
1591+
}
1592+
const key = draftKeyRef.current;
1593+
if (key) {
1594+
writeComposerDraft(key, "");
1595+
}
1596+
}, []);
15791597
// react-textarea-autosize re-measures only on value change or window resize,
15801598
// not on the width swap from expanding, so it keeps the taller height and
15811599
// leaves a stray blank row. Nudge a resize whenever input width changes.
@@ -1726,9 +1744,10 @@ const Composer: FC<{
17261744
setPendingSend(false);
17271745
dismissWaitToast();
17281746
if (text.trim().length > 0 || attachments.length > 0) {
1747+
clearStoredDraft();
17291748
aui.composer().send();
17301749
}
1731-
}, [pendingSend, indexingActive, aui, dismissWaitToast]);
1750+
}, [pendingSend, indexingActive, aui, clearStoredDraft, dismissWaitToast]);
17321751

17331752
// Drop any queued send + toast on unmount (e.g. thread switch).
17341753
useEffect(
@@ -1771,6 +1790,7 @@ const Composer: FC<{
17711790
flushResourcesSync(() => {
17721791
aui.composer().setText("");
17731792
});
1793+
clearStoredDraft();
17741794
startPromptQueue(
17751795
[queuedPrompt],
17761796
createPromptQueueTarget(),
@@ -1804,6 +1824,7 @@ const Composer: FC<{
18041824
closeOverlay();
18051825
return;
18061826
}
1827+
clearStoredDraft();
18071828
setImageToolsEnabled(true);
18081829
setPendingImageEditReference({
18091830
threadId: overlay.threadId ?? referenceThreadId,
@@ -1821,11 +1842,15 @@ const Composer: FC<{
18211842
);
18221843
});
18231844
closeOverlay();
1845+
return;
18241846
}
1847+
1848+
clearStoredDraft();
18251849
},
18261850
[
18271851
aui,
18281852
canQueueCurrentPrompt,
1853+
clearStoredDraft,
18291854
closeOverlay,
18301855
composerText,
18311856
createPromptQueueTarget,
@@ -1947,6 +1972,7 @@ const Composer: FC<{
19471972
flushResourcesSync(() => {
19481973
aui.composer().setText("");
19491974
});
1975+
clearStoredDraft();
19501976
startPromptQueue([queuedPrompt], createPromptQueueTarget(), true);
19511977
}}
19521978
onSendClick={interceptSend}

0 commit comments

Comments
 (0)