Update frontend/src/components/ChatInterface.jsx
Browse files
frontend/src/components/ChatInterface.jsx
CHANGED
@@ -9,23 +9,50 @@ saveBotResponse, toLogin }) => {
|
|
9 |
const [isLoading, setIsLoading] = useState(false);
|
10 |
const messagesEndRef = useRef(null);
|
11 |
const textareaRef = useRef(null);
|
12 |
-
|
|
|
|
|
|
|
13 |
const scrollToBottom = () => {
|
14 |
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
15 |
};
|
16 |
useEffect(scrollToBottom, [messages]);
|
17 |
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
try {
|
20 |
setIsLoading(true);
|
21 |
|
22 |
-
// Ajouter le message utilisateur à l'interface
|
23 |
setMessages(prev => [...prev, { sender: 'user', text: message }]);
|
24 |
|
25 |
-
// IMPORTANT: Obtenir l'ID de conversation mis à jour (nouvelle ou existante)
|
26 |
const updatedConversationId = await onMessageSent(message);
|
27 |
|
28 |
-
// Appel à l'API de chat
|
29 |
const chatRes = await fetch('/api/chat', {
|
30 |
method: 'POST',
|
31 |
headers: { 'Content-Type': 'application/json' },
|
@@ -37,10 +64,12 @@ saveBotResponse, toLogin }) => {
|
|
37 |
|
38 |
const { response: botResponse } = await chatRes.json();
|
39 |
|
40 |
-
|
41 |
-
|
|
|
|
|
|
|
42 |
|
43 |
-
// Utiliser l'ID de conversation mis à jour
|
44 |
if (updatedConversationId) {
|
45 |
saveBotResponse(updatedConversationId, botResponse);
|
46 |
} else if (activeConversationId) {
|
@@ -49,15 +78,14 @@ saveBotResponse, toLogin }) => {
|
|
49 |
|
50 |
} catch (error) {
|
51 |
console.error('Erreur:', error);
|
|
|
52 |
setMessages(prev => [...prev,
|
53 |
-
{ sender: 'user', text: message },
|
54 |
{ sender: 'bot', text: "Désolé, une erreur s'est produite. Veuillez réessayer." }
|
55 |
]);
|
56 |
-
} finally {
|
57 |
-
setIsLoading(false);
|
58 |
}
|
59 |
};
|
60 |
|
|
|
61 |
const handleSubmit = (e) => {
|
62 |
e.preventDefault();
|
63 |
const txt = inputMessage.trim();
|
@@ -120,13 +148,25 @@ saveBotResponse, toLogin }) => {
|
|
120 |
<h2 className="chat-title">Medic.ial</h2>
|
121 |
</div>
|
122 |
<div className="messages-container">
|
123 |
-
{messages.map((msg, index) =>
|
124 |
-
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
</div>
|
128 |
</div>
|
129 |
-
)
|
|
|
130 |
{isLoading && (
|
131 |
<div className="message bot">
|
132 |
<div className="message-content loading">
|
|
|
9 |
const [isLoading, setIsLoading] = useState(false);
|
10 |
const messagesEndRef = useRef(null);
|
11 |
const textareaRef = useRef(null);
|
12 |
+
const [streamingText, setStreamingText] = useState('');
|
13 |
+
const [isStreaming, setIsStreaming] = useState(false);
|
14 |
+
const [fullResponse, setFullResponse] = useState('');
|
15 |
+
|
16 |
const scrollToBottom = () => {
|
17 |
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
18 |
};
|
19 |
useEffect(scrollToBottom, [messages]);
|
20 |
|
21 |
+
|
22 |
+
|
23 |
+
|
24 |
+
const streamResponse = (response) => {
|
25 |
+
setIsStreaming(true);
|
26 |
+
setFullResponse(response);
|
27 |
+
setStreamingText('');
|
28 |
+
|
29 |
+
const words = response.split(' ');
|
30 |
+
let currentIndex = 0;
|
31 |
+
|
32 |
+
const streamInterval = setInterval(() => {
|
33 |
+
if (currentIndex < words.length) {
|
34 |
+
setStreamingText(prev => prev + (prev ? ' ' : '') + words[currentIndex]);
|
35 |
+
currentIndex++;
|
36 |
+
} else {
|
37 |
+
clearInterval(streamInterval);
|
38 |
+
setIsStreaming(false);
|
39 |
+
|
40 |
+
setMessages(prev => prev.filter(msg => msg.sender !== 'bot-streaming'));
|
41 |
+
setMessages(prev => [...prev, { sender: 'bot', text: response }]);
|
42 |
+
}
|
43 |
+
}, 40);
|
44 |
+
|
45 |
+
return () => clearInterval(streamInterval);
|
46 |
+
};
|
47 |
+
|
48 |
+
const sendMessage = async (message) => {
|
49 |
try {
|
50 |
setIsLoading(true);
|
51 |
|
|
|
52 |
setMessages(prev => [...prev, { sender: 'user', text: message }]);
|
53 |
|
|
|
54 |
const updatedConversationId = await onMessageSent(message);
|
55 |
|
|
|
56 |
const chatRes = await fetch('/api/chat', {
|
57 |
method: 'POST',
|
58 |
headers: { 'Content-Type': 'application/json' },
|
|
|
64 |
|
65 |
const { response: botResponse } = await chatRes.json();
|
66 |
|
67 |
+
setIsLoading(false);
|
68 |
+
|
69 |
+
setMessages(prev => [...prev, { sender: 'bot-streaming', text: '' }]);
|
70 |
+
|
71 |
+
streamResponse(botResponse);
|
72 |
|
|
|
73 |
if (updatedConversationId) {
|
74 |
saveBotResponse(updatedConversationId, botResponse);
|
75 |
} else if (activeConversationId) {
|
|
|
78 |
|
79 |
} catch (error) {
|
80 |
console.error('Erreur:', error);
|
81 |
+
setIsLoading(false);
|
82 |
setMessages(prev => [...prev,
|
|
|
83 |
{ sender: 'bot', text: "Désolé, une erreur s'est produite. Veuillez réessayer." }
|
84 |
]);
|
|
|
|
|
85 |
}
|
86 |
};
|
87 |
|
88 |
+
|
89 |
const handleSubmit = (e) => {
|
90 |
e.preventDefault();
|
91 |
const txt = inputMessage.trim();
|
|
|
148 |
<h2 className="chat-title">Medic.ial</h2>
|
149 |
</div>
|
150 |
<div className="messages-container">
|
151 |
+
{messages.map((msg, index) => {
|
152 |
+
if (msg.sender === 'bot-streaming') return null;
|
153 |
+
|
154 |
+
return (
|
155 |
+
<div key={index} className={`message ${msg.sender}`}>
|
156 |
+
<div className="message-content">
|
157 |
+
{isMarkdown(msg.text) ? <ReactMarkdown>{msg.text}</ReactMarkdown> : msg.text}
|
158 |
+
</div>
|
159 |
+
</div>
|
160 |
+
);
|
161 |
+
})}
|
162 |
+
{isStreaming && (
|
163 |
+
<div className="message bot">
|
164 |
+
<div className="message-content streaming-message">
|
165 |
+
{isMarkdown(streamingText) ? <ReactMarkdown>{streamingText}</ReactMarkdown> : streamingText}
|
166 |
</div>
|
167 |
</div>
|
168 |
+
)}
|
169 |
+
|
170 |
{isLoading && (
|
171 |
<div className="message bot">
|
172 |
<div className="message-content loading">
|