Files
Prompt-Envelope-Protocol/src/components/ChatView.tsx
T
carry 4c384fe566 feat: 实现协议双向映射,支持 Live 模式调用 OpenAI API
核心改动:
- 新增 src/utils/import.ts:OpenAI 响应 → Protocol Message 反向映射 + StreamingImporter 流式增量累加器
- 新增 src/services/api.ts:薄封装层,exportToOpenAIFormat → fetch → importFromOpenAIResponse
- 新增 src/services/api-config.ts:API 配置 localStorage 持久化
- 新增 src/components/ApiSettings.tsx:API 设置模态框
- 改造 ChatContext:新增 isLive / sendMessage / 流式状态管理
- 改造 ChatView/ChatInput:Live 模式下启用输入,支持回车发送和 loading 动画
- 改造 App.tsx:Demo/Live 模式切换 + 设置入口
- 新增 19 个 import.test.ts 测试用例,全部 48 测试通过
2026-06-09 15:02:10 +08:00

45 lines
1.3 KiB
TypeScript

import { useState } from 'react'
import { useChat } from '../context/ChatContext'
import MessageList from './MessageList'
import ChatInput from './ChatInput'
import { AlertCircle, X } from 'lucide-react'
export default function ChatView() {
const { envelope, isLive, isLoading, sendMessage, error, clearError } = useChat()
const [input, setInput] = useState('')
const handleSend = () => {
if (!input.trim() || isLoading) return
sendMessage(input.trim())
setInput('')
}
return (
<div className="flex-1 flex flex-col min-w-0">
{/* 错误提示条 */}
{error && (
<div className="flex items-center gap-2 mx-3 mt-2 px-3 py-2 rounded-lg bg-red-50 border border-red-200 text-red-700 text-xs">
<AlertCircle size={14} className="shrink-0" />
<span className="flex-1">{error}</span>
<button
onClick={clearError}
className="shrink-0 p-0.5 rounded hover:bg-red-100 transition-colors"
>
<X size={14} />
</button>
</div>
)}
<MessageList messages={envelope.messages} />
<ChatInput
value={input}
onChange={setInput}
disabled={!isLive}
loading={isLoading}
onSend={handleSend}
/>
</div>
)
}