fix: clear Clawd input on send
This commit is contained in:
parent
43e01e7613
commit
d434485987
@ -3,6 +3,7 @@ import { z } from "zod";
|
||||
import { auth } from "@/app/(auth)/auth";
|
||||
import {
|
||||
getChatById,
|
||||
getMessagesByChatId,
|
||||
getSystemSetting,
|
||||
saveChat,
|
||||
saveMessages,
|
||||
@ -91,7 +92,6 @@ export async function POST(request: Request) {
|
||||
|
||||
const userMessageId = parsed.data.userMessageId || generateUUID();
|
||||
const assistantMessageId = generateUUID();
|
||||
const now = new Date();
|
||||
const conversationId = createConversationId(session.user.id, parsed.data.id);
|
||||
const endpoint = `${config.baseUrl}/api/chat`;
|
||||
|
||||
@ -159,13 +159,28 @@ export async function POST(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
const existingMessages = await getMessagesByChatId({ id: parsed.data.id }).catch(
|
||||
() => []
|
||||
);
|
||||
const latestMessageTimestamp = existingMessages.reduce((latest, item) => {
|
||||
const timestamp =
|
||||
item.createdAt instanceof Date
|
||||
? item.createdAt.getTime()
|
||||
: Date.parse(String(item.createdAt || ""));
|
||||
return Number.isFinite(timestamp) ? Math.max(latest, timestamp) : latest;
|
||||
}, 0);
|
||||
const userCreatedAt = new Date(
|
||||
Math.max(Date.now(), latestMessageTimestamp + 1)
|
||||
);
|
||||
const assistantCreatedAt = new Date(userCreatedAt.getTime() + 1);
|
||||
|
||||
const userMessage = {
|
||||
id: userMessageId,
|
||||
chatId: parsed.data.id,
|
||||
role: "user",
|
||||
parts: [{ type: "text", text: parsed.data.message }],
|
||||
attachments: [],
|
||||
createdAt: now,
|
||||
createdAt: userCreatedAt,
|
||||
videoStorageStatus: null,
|
||||
temporaryVideoUrl: null,
|
||||
permanentVideoUrl: null,
|
||||
@ -178,7 +193,7 @@ export async function POST(request: Request) {
|
||||
role: "assistant",
|
||||
parts: [{ type: "text", text: answer }],
|
||||
attachments: [],
|
||||
createdAt: new Date(now.getTime() + 1),
|
||||
createdAt: assistantCreatedAt,
|
||||
videoStorageStatus: null,
|
||||
temporaryVideoUrl: null,
|
||||
permanentVideoUrl: null,
|
||||
@ -199,12 +214,14 @@ export async function POST(request: Request) {
|
||||
id: userMessage.id,
|
||||
role: "user",
|
||||
parts: userMessage.parts,
|
||||
createdAt: userMessage.createdAt.toISOString(),
|
||||
metadata: { createdAt: userMessage.createdAt.toISOString() },
|
||||
},
|
||||
{
|
||||
id: assistantMessage.id,
|
||||
role: "assistant",
|
||||
parts: assistantMessage.parts,
|
||||
createdAt: assistantMessage.createdAt.toISOString(),
|
||||
metadata: { createdAt: assistantMessage.createdAt.toISOString() },
|
||||
},
|
||||
],
|
||||
|
||||
@ -3367,6 +3367,23 @@ export function CanvasChatPanel({
|
||||
: isPresetAgentSelection
|
||||
? getToolbarItem("chatModePresetAgent").label
|
||||
: "Agent";
|
||||
const getComposerModeMenuItemClass = useCallback(
|
||||
(mode: CanvasComposerMode) =>
|
||||
cn(
|
||||
"h-11 cursor-pointer rounded-[12px] px-3 text-[16px] font-normal outline-none transition-colors focus:text-[#1f2937] dark:focus:text-white [&_svg]:!size-5",
|
||||
isVideoWorkspace
|
||||
? "text-foreground focus:bg-background/80"
|
||||
: "text-[#2e3238] focus:bg-[#eef0f3] dark:text-zinc-100 dark:focus:bg-white/12",
|
||||
activeComposerMode === mode
|
||||
? isVideoWorkspace
|
||||
? "bg-background text-foreground"
|
||||
: "bg-[#eef0f3] text-[#1f2937] dark:bg-white/12 dark:text-white"
|
||||
: isVideoWorkspace
|
||||
? "hover:bg-background/80"
|
||||
: "hover:bg-[#f5f6f7] dark:hover:bg-white/8"
|
||||
),
|
||||
[activeComposerMode, isVideoWorkspace]
|
||||
);
|
||||
const shouldMaskAgentRuntimeModelName =
|
||||
activeComposerMode === "agent" || selectedModelId === "auto";
|
||||
const getAgentSafeModelName = useCallback(
|
||||
@ -8536,11 +8553,19 @@ export function CanvasChatPanel({
|
||||
}
|
||||
|
||||
const userMessageId = generateUUID();
|
||||
const latestMessageTimestamp = messages.reduce(
|
||||
(latest, message) => Math.max(latest, getMessageTimestamp(message) ?? 0),
|
||||
0
|
||||
);
|
||||
const optimisticCreatedAt = new Date(
|
||||
Math.max(Date.now(), latestMessageTimestamp + 1)
|
||||
);
|
||||
const optimisticUserMessage: ChatMessage = {
|
||||
id: userMessageId,
|
||||
role: "user",
|
||||
parts: [{ type: "text", text: textContent }],
|
||||
metadata: { createdAt: new Date().toISOString() },
|
||||
createdAt: optimisticCreatedAt,
|
||||
metadata: { createdAt: optimisticCreatedAt.toISOString() },
|
||||
} as ChatMessage;
|
||||
|
||||
setSendGuard(activeChatId, {
|
||||
@ -8555,6 +8580,14 @@ export function CanvasChatPanel({
|
||||
optimisticUserMessage,
|
||||
])
|
||||
);
|
||||
setInput("");
|
||||
setAttachments([]);
|
||||
clearSelection();
|
||||
|
||||
const editableDiv = textareaRef.current as HTMLDivElement | null;
|
||||
if (editableDiv) {
|
||||
editableDiv.innerHTML = "";
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/canvas/clawd-chat", {
|
||||
@ -8594,17 +8627,19 @@ export function CanvasChatPanel({
|
||||
void mutate(buildHistoryMessagesUrl(rawChatId, { cacheBust: true }));
|
||||
}
|
||||
hasHydratedHistoryRef.current = true;
|
||||
setInput("");
|
||||
setAttachments([]);
|
||||
clearSelection();
|
||||
|
||||
const editableDiv = textareaRef.current as HTMLDivElement | null;
|
||||
if (editableDiv) {
|
||||
editableDiv.innerHTML = "";
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[CanvasChat] Clawd request failed:", error);
|
||||
toast.error(error instanceof Error ? error.message : "Clawd 请求失败");
|
||||
const currentEditorText = (editableDiv?.textContent || "")
|
||||
.replace(/\u200b/g, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
if (!currentEditorText) {
|
||||
setInput(textContent);
|
||||
if (editableDiv) {
|
||||
editableDiv.textContent = textContent;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setIsClawdSubmitting(false);
|
||||
releaseSendGuard(activeChatId);
|
||||
@ -12448,7 +12483,7 @@ export function CanvasChatPanel({
|
||||
side="top"
|
||||
sideOffset={10}
|
||||
className={cn(
|
||||
"w-[200px] rounded-[18px] border border-[#d8dce3] bg-white p-2 text-[#20242a] shadow-[0_22px_54px_rgba(15,23,42,0.16)]",
|
||||
"w-[200px] space-y-1 rounded-[18px] border border-[#d8dce3] bg-white p-2 text-[#20242a] shadow-[0_22px_54px_rgba(15,23,42,0.16)]",
|
||||
isVideoWorkspace
|
||||
? "border border-border/60 bg-background/95 shadow-[0_14px_30px_-20px_rgba(15,23,42,0.35)] backdrop-blur-xl"
|
||||
: "dark:border-white/10 dark:bg-zinc-900/95 dark:text-zinc-100"
|
||||
@ -12457,19 +12492,7 @@ export function CanvasChatPanel({
|
||||
{effectiveAgentEnabled ? (
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleSelectGenerationMode("agent")}
|
||||
className={cn(
|
||||
"h-11 cursor-pointer rounded-[12px] px-3 text-[16px] font-normal [&_svg]:!size-5",
|
||||
isVideoWorkspace
|
||||
? "text-foreground"
|
||||
: "text-[#2e3238] dark:text-zinc-100",
|
||||
activeComposerMode === "agent"
|
||||
? isVideoWorkspace
|
||||
? "bg-background"
|
||||
: "bg-transparent dark:bg-white/10"
|
||||
: isVideoWorkspace
|
||||
? "hover:bg-background/80"
|
||||
: "hover:bg-[#f5f6f7] dark:hover:bg-white/8"
|
||||
)}
|
||||
className={getComposerModeMenuItemClass("agent")}
|
||||
>
|
||||
<CanvasToolbarIcon
|
||||
className="h-5 w-5"
|
||||
@ -12487,19 +12510,7 @@ export function CanvasChatPanel({
|
||||
{isClawdModeEnabled ? (
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleSelectGenerationMode("clawd")}
|
||||
className={cn(
|
||||
"h-11 cursor-pointer rounded-[12px] px-3 text-[16px] font-normal [&_svg]:!size-5",
|
||||
isVideoWorkspace
|
||||
? "text-foreground"
|
||||
: "text-[#2e3238] dark:text-zinc-100",
|
||||
activeComposerMode === "clawd"
|
||||
? isVideoWorkspace
|
||||
? "bg-background"
|
||||
: "bg-transparent dark:bg-white/10"
|
||||
: isVideoWorkspace
|
||||
? "hover:bg-background/80"
|
||||
: "hover:bg-[#f5f6f7] dark:hover:bg-white/8"
|
||||
)}
|
||||
className={getComposerModeMenuItemClass("clawd")}
|
||||
>
|
||||
<MessageCircle className="h-5 w-5" />
|
||||
<span className="flex-1">Clawd模式</span>
|
||||
@ -12511,19 +12522,7 @@ export function CanvasChatPanel({
|
||||
{canUseDetailGeneration ? (
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleSelectGenerationMode("detail")}
|
||||
className={cn(
|
||||
"h-11 cursor-pointer rounded-[12px] px-3 text-[16px] font-normal [&_svg]:!size-5",
|
||||
isVideoWorkspace
|
||||
? "text-foreground"
|
||||
: "text-[#2e3238] dark:text-zinc-100",
|
||||
activeComposerMode === "detail"
|
||||
? isVideoWorkspace
|
||||
? "bg-background"
|
||||
: "bg-transparent dark:bg-white/10"
|
||||
: isVideoWorkspace
|
||||
? "hover:bg-background/80"
|
||||
: "hover:bg-[#f5f6f7] dark:hover:bg-white/8"
|
||||
)}
|
||||
className={getComposerModeMenuItemClass("detail")}
|
||||
>
|
||||
<CanvasToolbarIcon
|
||||
className="h-5 w-5"
|
||||
@ -12540,19 +12539,7 @@ export function CanvasChatPanel({
|
||||
) : null}
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleSelectGenerationMode("image")}
|
||||
className={cn(
|
||||
"h-11 cursor-pointer rounded-[12px] px-3 text-[16px] font-normal [&_svg]:!size-5",
|
||||
isVideoWorkspace
|
||||
? "text-foreground"
|
||||
: "text-[#2e3238] dark:text-zinc-100",
|
||||
activeComposerMode === "image"
|
||||
? isVideoWorkspace
|
||||
? "bg-background"
|
||||
: "bg-transparent dark:bg-white/10"
|
||||
: isVideoWorkspace
|
||||
? "hover:bg-background/80"
|
||||
: "hover:bg-[#f5f6f7] dark:hover:bg-white/8"
|
||||
)}
|
||||
className={getComposerModeMenuItemClass("image")}
|
||||
>
|
||||
<CanvasToolbarIcon
|
||||
className="h-5 w-5"
|
||||
@ -12568,19 +12555,7 @@ export function CanvasChatPanel({
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleSelectGenerationMode("video")}
|
||||
className={cn(
|
||||
"h-11 cursor-pointer rounded-[12px] px-3 text-[16px] font-normal [&_svg]:!size-5",
|
||||
isVideoWorkspace
|
||||
? "text-foreground"
|
||||
: "text-[#2e3238] dark:text-zinc-100",
|
||||
activeComposerMode === "video"
|
||||
? isVideoWorkspace
|
||||
? "bg-background"
|
||||
: "bg-transparent dark:bg-white/10"
|
||||
: isVideoWorkspace
|
||||
? "hover:bg-background/80"
|
||||
: "hover:bg-[#f5f6f7] dark:hover:bg-white/8"
|
||||
)}
|
||||
className={getComposerModeMenuItemClass("video")}
|
||||
>
|
||||
<CanvasToolbarIcon
|
||||
className="h-5 w-5"
|
||||
|
||||
@ -328,10 +328,17 @@ export function messageHasAssistantMedia(
|
||||
}
|
||||
|
||||
export function getMessageTimestamp(message: ChatMessage): number | null {
|
||||
const metadata =
|
||||
(message as any).metadata && typeof (message as any).metadata === "object"
|
||||
? ((message as any).metadata as Record<string, unknown>)
|
||||
: null;
|
||||
const rawValue =
|
||||
(message as any).createdAt ??
|
||||
(message as any).created_at ??
|
||||
(message as any).timestamp ??
|
||||
metadata?.createdAt ??
|
||||
metadata?.created_at ??
|
||||
metadata?.timestamp ??
|
||||
null;
|
||||
|
||||
if (rawValue instanceof Date) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user