fix: keep Claw composer cleared while submitting

This commit is contained in:
134 2026-06-24 22:24:59 +08:00
parent 948bed1737
commit 270c9fb61d

View File

@ -364,6 +364,8 @@ function normalizeClawdComposerText(value: string) {
type ClawdComposerSubmissionSnapshot = { type ClawdComposerSubmissionSnapshot = {
chatId: string; chatId: string;
canvasId?: string;
chatScope?: "canvas" | "agent";
expiresAt: number; expiresAt: number;
startedAt: number; startedAt: number;
submittedTexts: string[]; submittedTexts: string[];
@ -387,6 +389,11 @@ function parseClawdComposerSubmissionSnapshot(
if (!value || typeof value !== "object") return null; if (!value || typeof value !== "object") return null;
const snapshot = value as Partial<ClawdComposerSubmissionSnapshot>; const snapshot = value as Partial<ClawdComposerSubmissionSnapshot>;
const chatId = String(snapshot.chatId || "").trim(); const chatId = String(snapshot.chatId || "").trim();
const canvasId = String(snapshot.canvasId || "").trim();
const chatScope =
snapshot.chatScope === "canvas" || snapshot.chatScope === "agent"
? snapshot.chatScope
: undefined;
const startedAt = Number(snapshot.startedAt); const startedAt = Number(snapshot.startedAt);
const expiresAt = Number(snapshot.expiresAt); const expiresAt = Number(snapshot.expiresAt);
const submittedTexts = Array.isArray(snapshot.submittedTexts) const submittedTexts = Array.isArray(snapshot.submittedTexts)
@ -404,6 +411,8 @@ function parseClawdComposerSubmissionSnapshot(
return { return {
chatId, chatId,
canvasId: canvasId || undefined,
chatScope,
expiresAt, expiresAt,
startedAt, startedAt,
submittedTexts, submittedTexts,
@ -2192,6 +2201,7 @@ export function CanvasChatPanel({
}, [input]); }, [input]);
const clearComposerEditor = useCallback(() => { const clearComposerEditor = useCallback(() => {
inputRef.current = "";
setInput(""); setInput("");
const editableDiv = textareaRef.current as HTMLDivElement | null; const editableDiv = textareaRef.current as HTMLDivElement | null;
if (editableDiv) { if (editableDiv) {
@ -2223,11 +2233,27 @@ export function CanvasChatPanel({
return recentSubmission; return recentSubmission;
}, []); }, []);
const isClawdSubmissionForCurrentComposer = useCallback(
(submissionSnapshot: ClawdComposerSubmissionSnapshot) => {
if (submissionSnapshot.chatId === activeChatIdRef.current) return true;
if (submissionSnapshot.canvasId && submissionSnapshot.canvasId !== canvasId) {
return false;
}
if (submissionSnapshot.chatScope && submissionSnapshot.chatScope !== chatScope) {
return false;
}
return Boolean(submissionSnapshot.canvasId || submissionSnapshot.chatScope);
},
[canvasId, chatScope]
);
const clearRestoredClawdComposerText = useCallback(() => { const clearRestoredClawdComposerText = useCallback(() => {
const submissionSnapshot = getActiveClawdSubmissionSnapshot(); const submissionSnapshot = getActiveClawdSubmissionSnapshot();
const editableDiv = textareaRef.current as HTMLDivElement | null; const editableDiv = textareaRef.current as HTMLDivElement | null;
if (!submissionSnapshot || !editableDiv) return; if (!submissionSnapshot || !editableDiv) return;
if (submissionSnapshot.chatId !== activeChatIdRef.current) return; if (!isClawdSubmissionForCurrentComposer(submissionSnapshot)) return;
if (composerUserEditedAtRef.current > submissionSnapshot.startedAt) return; if (composerUserEditedAtRef.current > submissionSnapshot.startedAt) return;
const editorText = normalizeClawdComposerText( const editorText = normalizeClawdComposerText(
@ -2252,7 +2278,11 @@ export function CanvasChatPanel({
if (!editorWasRestored && !stateWasRestored) return; if (!editorWasRestored && !stateWasRestored) return;
clearComposerEditor(); clearComposerEditor();
}, [clearComposerEditor, getActiveClawdSubmissionSnapshot]); }, [
clearComposerEditor,
getActiveClawdSubmissionSnapshot,
isClawdSubmissionForCurrentComposer,
]);
useEffect(() => { useEffect(() => {
if (typeof window === "undefined") return; if (typeof window === "undefined") return;
@ -6157,7 +6187,12 @@ export function CanvasChatPanel({
if (!historyData || !rawChatId) return; if (!historyData || !rawChatId) return;
const shouldForceHydrate = forceHistoryHydrationRef.current === rawChatId; const shouldForceHydrate = forceHistoryHydrationRef.current === rawChatId;
if ((status === "streaming" || status === "submitted") && !shouldForceHydrate) return; if (
(status === "streaming" || status === "submitted" || isClawdSubmitting) &&
!shouldForceHydrate
) {
return;
}
const historyMessages = historyData.messages || []; const historyMessages = historyData.messages || [];
const signature = buildCanvasHistoryMessagesSignature(rawChatId, historyMessages); const signature = buildCanvasHistoryMessagesSignature(rawChatId, historyMessages);
@ -6187,7 +6222,7 @@ export function CanvasChatPanel({
} }
}; };
} }
}, [historyData, rawChatId, setMessages, status]); }, [historyData, isClawdSubmitting, rawChatId, setMessages, status]);
useEffect(() => { useEffect(() => {
const streamState = streamImageGenerationStateByChatId[activeChatId]; const streamState = streamImageGenerationStateByChatId[activeChatId];
@ -9573,6 +9608,8 @@ export function CanvasChatPanel({
const clawdSubmissionStartedAt = Date.now(); const clawdSubmissionStartedAt = Date.now();
const clawdSubmissionSnapshot: ClawdComposerSubmissionSnapshot = { const clawdSubmissionSnapshot: ClawdComposerSubmissionSnapshot = {
chatId: activeChatId, chatId: activeChatId,
canvasId,
chatScope,
expiresAt: expiresAt:
clawdSubmissionStartedAt + CLAWD_SUBMITTED_COMPOSER_RECOVERY_TTL_MS, clawdSubmissionStartedAt + CLAWD_SUBMITTED_COMPOSER_RECOVERY_TTL_MS,
startedAt: clawdSubmissionStartedAt, startedAt: clawdSubmissionStartedAt,
@ -10001,6 +10038,8 @@ export function CanvasChatPanel({
activeComposerMode, activeComposerMode,
agentEntryMode, agentEntryMode,
agentRequiredUploadCount, agentRequiredUploadCount,
canvasId,
chatScope,
rawChatId, rawChatId,
input, input,
attachments, attachments,
@ -13454,7 +13493,7 @@ export function CanvasChatPanel({
getActiveClawdSubmissionSnapshot(); getActiveClawdSubmissionSnapshot();
const isRestoredSubmittedClawdText = const isRestoredSubmittedClawdText =
activeClawdSubmission !== null && activeClawdSubmission !== null &&
activeClawdSubmission.chatId === activeChatIdRef.current && isClawdSubmissionForCurrentComposer(activeClawdSubmission) &&
isClawdSubmittedComposerText( isClawdSubmittedComposerText(
activeClawdSubmission, activeClawdSubmission,
textContent textContent