4c384fe566
核心改动: - 新增 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 测试通过
45 lines
1.3 KiB
TypeScript
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>
|
|
)
|
|
}
|