feat(ui): 对话输入框 Enter 换行,Ctrl/Cmd+Enter 发送

会话界面共享 Composer 与任务详情主 Agent 输入框统一改为回车换行,避免长消息
误发。任务详情原本是单行 Input(根本无法换行),换成 Textarea 并对齐 Composer
的自动增高样式(rows=1 + max-h-40)。
This commit is contained in:
Autumn-27 committed 2026-08-19 11:12:21 -04:00
1 parent 0c653a2135
commit ca2c5e45a9
2 files changed
+17 -10

No files matched your search

+6 -5
View File
@@ -77,8 +77,8 @@ function LiveBadge() {
);
}
// Composer is the shared bottom input (textarea grows to a cap, Enter sends,
// Shift+Enter newlines) — the same affordance across DraftChat and ChatView.
// Composer is the shared bottom input (textarea grows to a cap, Enter newlines,
// Ctrl/Cmd+Enter sends) — the same affordance across DraftChat and ChatView.
function Composer({
value,
onChange,
@@ -112,7 +112,8 @@ function Composer({
const fileInputRef = React.useRef<HTMLInputElement>(null);
const atts = attachments ?? [];
function onKeyDown(e: React.KeyboardEvent<HTMLTextAreaElement>) {
if (e.key === "Enter" && !e.shiftKey) {
// Enter 换行;只有 Ctrl/Cmd+Enter 才发送(避免长消息误发)。
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
onSend();
}
@@ -363,7 +364,7 @@ function DraftChat({
onChange={setInput}
onSend={send}
disabled={sending || uploading || !agentKey}
placeholder="输入消息,Enter 发送,Shift+Enter 换行"
placeholder="输入消息,Enter 换行,Ctrl+Enter 发送"
leftSlot={agentPicker}
onPickFiles={pickFiles}
uploading={uploading}
@@ -691,7 +692,7 @@ function ChatView({
onChange={setInput}
onSend={send}
disabled={running}
placeholder={running ? "Agent 正在回复…" : "输入消息,Enter 发送,Shift+Enter 换行"}
placeholder={running ? "Agent 正在回复…" : "输入消息,Enter 换行,Ctrl+Enter 发送"}
running={running}
onStop={stop}
stopDisabled={stopping}
@@ -24,7 +24,7 @@ import { cn } from "@/lib/utils";
import { Transcript } from "@/components/transcript";
import { TodoPopover } from "@/components/todo-popover";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
Tooltip,
@@ -1070,7 +1070,7 @@ export function SessionsTab({ taskId }: { taskId: string }) {
))}
</div>
)}
<div className="flex items-center gap-2">
<div className="flex items-end gap-2">
<input
ref={fileInputRef}
type="file"
@@ -1087,12 +1087,18 @@ export function SessionsTab({ taskId }: { taskId: string }) {
>
{uploading ? <Loader2Icon className="animate-spin" /> : <PaperclipIcon />}
</Button>
<Input
placeholder="给主 Agent 发消息,引导探索方向…"
<Textarea
className="max-h-40 min-h-9 flex-1 resize-none"
rows={1}
placeholder="给主 Agent 发消息,Enter 换行,Ctrl+Enter 发送…"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter" && !mainLive) send();
// Enter 换行;只有 Ctrl/Cmd+Enter 才发送。
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
if (!mainLive) send();
}
}}
disabled={mainLive}
/>