fix: clear restored Claw composer text

This commit is contained in:
134 2026-06-24 21:18:39 +08:00
parent 6f8c939be2
commit 754209ee53

View File

@ -352,6 +352,13 @@ function isClawdTableFile(file: File) {
);
}
function normalizeClawdComposerText(value: string) {
return String(value || "")
.replace(/\u200b/g, " ")
.replace(/\s+/g, " ")
.trim();
}
function shouldShowClawdProcessingHint(
message: string,
hasTableFiles: boolean,
@ -361,10 +368,7 @@ function shouldShowClawdProcessingHint(
return true;
}
const normalizedMessage = String(message || "")
.replace(/\u200b/g, " ")
.replace(/\s+/g, " ")
.trim();
const normalizedMessage = normalizeClawdComposerText(message);
if (!normalizedMessage) {
return false;
@ -1758,6 +1762,11 @@ export function CanvasChatPanel({
const historyScrollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const forceHistoryHydrationRef = useRef<string | null>(null);
const copiedUserMessageRef = useRef<CopiedUserMessagePayload | null>(null);
const pendingClawdSubmissionRef = useRef<{
chatId: string;
submittedTexts: string[];
startedAt: number;
} | null>(null);
const replaceChatSessionQuery = useCallback(
(sessionId: string) => {
@ -2095,6 +2104,63 @@ export function CanvasChatPanel({
setSelectedSkillTagId(null);
}, [activeChatId]);
const clearComposerEditor = useCallback(() => {
setInput("");
const editableDiv = textareaRef.current as HTMLDivElement | null;
if (editableDiv) {
editableDiv.innerHTML = "";
}
}, []);
const clearRestoredClawdComposerText = useCallback(() => {
const pendingSubmission = pendingClawdSubmissionRef.current;
const editableDiv = textareaRef.current as HTMLDivElement | null;
if (!pendingSubmission || !editableDiv) return;
if (pendingSubmission.chatId !== activeChatIdRef.current) return;
const editorText = normalizeClawdComposerText(
getComposerPlainTextFromElement(editableDiv)
);
if (!editorText) {
if (editableDiv.childNodes.length > 0) {
clearComposerEditor();
}
return;
}
const submittedTextSet = new Set(
pendingSubmission.submittedTexts
.map((text) => normalizeClawdComposerText(text))
.filter(Boolean)
);
if (!submittedTextSet.has(editorText)) return;
clearComposerEditor();
}, [clearComposerEditor]);
useEffect(() => {
if (typeof window === "undefined") return;
const clearAfterRestore = () => {
window.setTimeout(clearRestoredClawdComposerText, 0);
};
const handleVisibilityChange = () => {
if (document.visibilityState === "visible") {
clearAfterRestore();
}
};
document.addEventListener("visibilitychange", handleVisibilityChange);
window.addEventListener("focus", clearAfterRestore);
window.addEventListener("pageshow", clearAfterRestore);
return () => {
document.removeEventListener("visibilitychange", handleVisibilityChange);
window.removeEventListener("focus", clearAfterRestore);
window.removeEventListener("pageshow", clearAfterRestore);
};
}, [clearRestoredClawdComposerText]);
useEffect(() => {
const now = Date.now();
let rootChatId = chatId;
@ -9313,10 +9379,7 @@ export function CanvasChatPanel({
}
if (isClawdMode) {
const textContent = input
.replace(/\u200b/g, " ")
.replace(/\s+/g, " ")
.trim();
const textContent = normalizeClawdComposerText(input);
const tableFilesSnapshot = [...clawdTableFiles];
const hasTableFiles = tableFilesSnapshot.length > 0;
const attachmentsSnapshot = [...attachments];
@ -9389,6 +9452,16 @@ export function CanvasChatPanel({
signature: sendSignature,
timestamp: Date.now(),
});
pendingClawdSubmissionRef.current = {
chatId: activeChatId,
submittedTexts: [
textContent,
baseRequestMessage,
requestMessage,
optimisticMessageText,
],
startedAt: Date.now(),
};
setClawdProcessingHint(nextProcessingHint);
setIsClawdSubmitting(true);
setMessages((previousMessages) =>
@ -9397,16 +9470,11 @@ export function CanvasChatPanel({
optimisticUserMessage,
])
);
setInput("");
clearComposerEditor();
setAttachments([]);
setClawdTableFiles([]);
clearSelection();
const editableDiv = textareaRef.current as HTMLDivElement | null;
if (editableDiv) {
editableDiv.innerHTML = "";
}
try {
const formData = new FormData();
formData.append("id", rawChatId);
@ -9474,6 +9542,7 @@ export function CanvasChatPanel({
toast.error(error instanceof Error ? error.message : `${CLAW_MODE_LABEL} 请求失败`);
setClawdTableFiles(tableFilesSnapshot);
setAttachments(attachmentsSnapshot);
const editableDiv = textareaRef.current as HTMLDivElement | null;
const currentEditorText = (editableDiv?.textContent || "")
.replace(/\u200b/g, " ")
.replace(/\s+/g, " ")
@ -9495,6 +9564,7 @@ export function CanvasChatPanel({
}
}
} finally {
pendingClawdSubmissionRef.current = null;
setIsClawdSubmitting(false);
setClawdProcessingHint(null);
releaseSendGuard(activeChatId);
@ -9828,6 +9898,7 @@ export function CanvasChatPanel({
releaseSendGuard,
setSendGuard,
setMessages,
clearComposerEditor,
shouldBlockDuplicateSend,
status,
mutate,