Files
codingroom/components/ChatBot.tsx
2026-01-28 00:19:52 +08:00

97 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useRef, useEffect } from 'react';
import { getRoboticsChatResponse } from '../services/geminiService';
import { Message } from '../types';
import { BrainIcon } from './SVGIcons';
const ChatBot: React.FC = () => {
const [messages, setMessages] = useState<Message[]>([]);
const [input, setInput] = useState('');
const [isLoading, setIsLoading] = useState(false);
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}
}, [messages, isLoading]);
const handleSend = async () => {
if (!input.trim() || isLoading) return;
const userMsg: Message = { role: 'user', text: input };
setMessages(prev => [...prev, userMsg]);
setInput('');
setIsLoading(true);
const botResponse = await getRoboticsChatResponse(messages, input);
setMessages(prev => [...prev, { role: 'model', text: botResponse }]);
setIsLoading(false);
};
return (
<div className="flex flex-col h-[600px] w-full max-w-2xl mx-auto glass rounded-2xl overflow-hidden shadow-2xl border border-blue-500/20">
<div className="bg-blue-600/20 p-4 border-b border-blue-500/30 flex items-center gap-3">
<BrainIcon />
<div>
<h3 className="font-bold text-blue-400"></h3>
<p className="text-xs text-slate-400"> CodingRoom AI </p>
</div>
</div>
<div ref={scrollRef} className="flex-1 overflow-y-auto p-4 space-y-4 custom-scrollbar">
{messages.length === 0 && (
<div className="text-center py-20 text-slate-500 italic">
"你可以问我关于 ROS2、逆运动学或者如何为你的下一个机器人编程。"
</div>
)}
{messages.map((msg, i) => (
<div key={i} className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}>
<div className={`max-w-[80%] p-3 rounded-2xl text-sm ${
msg.role === 'user'
? 'bg-blue-600 text-white rounded-tr-none shadow-lg'
: 'bg-slate-800 text-slate-200 rounded-tl-none border border-slate-700'
}`}>
{msg.text}
</div>
</div>
))}
{isLoading && (
<div className="flex justify-start">
<div className="bg-slate-800 p-3 rounded-2xl rounded-tl-none border border-slate-700">
<div className="flex gap-1">
<span className="w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce"></span>
<span className="w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce [animation-delay:0.2s]"></span>
<span className="w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce [animation-delay:0.4s]"></span>
</div>
</div>
</div>
)}
</div>
<div className="p-4 bg-slate-900/50 border-t border-slate-800">
<div className="flex gap-2">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleSend()}
placeholder="输入你的机器人技术问题..."
className="flex-1 bg-slate-800 border border-slate-700 rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 text-white"
/>
<button
onClick={handleSend}
disabled={isLoading}
className="bg-blue-600 hover:bg-blue-500 disabled:opacity-50 text-white px-5 py-2 rounded-lg transition-all font-medium text-sm shadow-lg shadow-blue-500/20"
>
</button>
</div>
</div>
</div>
);
};
export default ChatBot;