aura-web/src/pages/chat/components/ChatPageWebBase.tsx

121 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { App as AntApp, Empty } from 'antd';
import type { DesktopViewport } from '../../../hooks/useDesktopViewport';
import { desktopViewportClass } from '../../../hooks/useDesktopViewport';
import type { ModelOverrides } from '../../../api';
import type { ChatPageLogicOutput } from '../ChatPageLogic';
import { markdownToPlainText } from '../utils/copy';
import AgentSidebar from './AgentSidebar';
import ChatBody from './ChatBody';
import ChatDrawers from './ChatDrawers';
import ChatHeader from './ChatHeader';
import ChatInput from './ChatInput';
import ChatOutline from './ChatOutline';
export interface ChatPageWebVariantProps {
logic: ChatPageLogicOutput;
viewport: DesktopViewport;
}
export default function ChatPageWebBase({ logic, viewport }: ChatPageWebVariantProps) {
const { message } = AntApp.useApp();
const { id, roomId, highlightId, historyDrawerOpen, mcpDrawerOpen, paramsDrawerOpen, tplDrawerOpen } = logic;
const { agent, agentList, messages, branches, bodyRef, sender, navigate, overrides } = logic;
const { setOverrides, setRoomId, setHighlightId, handleNewSession } = logic;
const { setHistoryDrawerOpen, setMcpDrawerOpen, setParamsDrawerOpen, setTplDrawerOpen } = logic;
return (
<div className={`chat-shell ${desktopViewportClass(viewport)}`}>
<AgentSidebar agentList={agentList} activeAgentId={id} onCreate={() => navigate('/agents/new')} onSelect={(aid) => navigate(`/chat/${aid}`)} />
<section className="chat-main">
{!agent ? (
<div className="chat-empty-state">
<Empty description="请在左侧选择一个智能体开始对话" />
</div>
) : (
<>
<ChatHeader
agent={agent}
useStream={sender.useStream}
setUseStream={sender.setUseStream}
onOpenHistory={() => setHistoryDrawerOpen(true)}
onOpenParams={() => setParamsDrawerOpen(true)}
onOpenMcp={() => setMcpDrawerOpen(true)}
onManageAgent={() => navigate(`/agents/${id}`)}
onClear={sender.handleClear}
/>
<div className="chat-content-row">
<ChatBody
bodyRef={bodyRef}
agent={agent}
agentList={agentList}
currentAgentId={id!}
messages={messages}
branches={branches}
highlightId={highlightId}
sending={sender.sending}
streaming={sender.streaming}
onRegenerate={sender.handleRegenerate}
onSwitchBranch={sender.handleSwitchBranch}
onCopy={(text, mode) => {
const content = mode === 'markdown' ? text : markdownToPlainText(text);
navigator.clipboard?.writeText(content).then(() => message.success(mode === 'markdown' ? '已复制Markdown' : '已复制(纯文本)'));
}}
/>
<ChatOutline messages={messages} activeId={highlightId} onJump={(msgId) => {
setHighlightId(msgId);
document.getElementById('msg-' + msgId)?.scrollIntoView({ block: 'start', behavior: 'smooth' });
}} />
</div>
<ChatInput
input={sender.input}
setInput={sender.setInput}
sending={sender.sending}
attachments={sender.attachments}
setAttachments={sender.setAttachments}
imageUrls={sender.imageUrls}
setImageUrls={sender.setImageUrls}
onSend={sender.handleSend}
onStop={sender.handleStop}
onAttach={sender.handleAttach}
onOpenTpl={() => setTplDrawerOpen(true)}
modelOptions={sender.modelOptions}
activeModelValue={sender.activeModelValue}
onChangeModel={(modelId) => {
const picked = sender.modelOptions.find((o) => o.value === modelId);
setOverrides((o: ModelOverrides) => ({ ...o, model_id: modelId, model: picked?.label ?? o.model }));
}}
agentList={agentList}
onInsertMention={() => {}}
onOpenHistory={() => setHistoryDrawerOpen(true)}
onNewSession={handleNewSession}
/>
</>
)}
</section>
<ChatDrawers
agentId={id}
agent={agent}
input={sender.input}
setInput={(updater) => sender.setInput(updater)}
overrides={overrides}
setOverrides={setOverrides}
roomId={roomId}
setRoomId={setRoomId}
setHighlightId={setHighlightId}
sessionRefresh={sender.sessionRefresh}
mcpDrawerOpen={mcpDrawerOpen}
setMcpDrawerOpen={setMcpDrawerOpen}
tplDrawerOpen={tplDrawerOpen}
setTplDrawerOpen={setTplDrawerOpen}
paramsDrawerOpen={paramsDrawerOpen}
setParamsDrawerOpen={setParamsDrawerOpen}
historyDrawerOpen={historyDrawerOpen}
setHistoryDrawerOpen={setHistoryDrawerOpen}
notify={{ success: (t) => message.success(t) }}
/>
</div>
);
}