diff --git a/pitch-deck/components/ChatFAB.tsx b/pitch-deck/components/ChatFAB.tsx index fe65677..4be309c 100644 --- a/pitch-deck/components/ChatFAB.tsx +++ b/pitch-deck/components/ChatFAB.tsx @@ -88,6 +88,7 @@ export default function ChatFAB({ lang, currentSlide, currentIndex, visitedSlide const [messages, setMessages] = useState([]) const [input, setInput] = useState('') const [isStreaming, setIsStreaming] = useState(false) + const [isWaiting, setIsWaiting] = useState(false) const [parsedResponses, setParsedResponses] = useState>(new Map()) const messagesEndRef = useRef(null) const inputRef = useRef(null) @@ -126,6 +127,7 @@ export default function ChatFAB({ lang, currentSlide, currentIndex, visitedSlide setInput('') setMessages(prev => [...prev, { role: 'user', content: message }]) setIsStreaming(true) + setIsWaiting(true) abortRef.current = new AbortController() @@ -152,24 +154,31 @@ export default function ChatFAB({ lang, currentSlide, currentIndex, visitedSlide const reader = res.body!.getReader() const decoder = new TextDecoder() let content = '' - - setMessages(prev => [...prev, { role: 'assistant', content: '' }]) + let firstChunk = true while (true) { const { done, value } = await reader.read() if (done) break content += decoder.decode(value, { stream: true }) - const currentText = content - setMessages(prev => { - const updated = [...prev] - updated[updated.length - 1] = { role: 'assistant', content: currentText } - return updated - }) + + if (firstChunk) { + firstChunk = false + setIsWaiting(false) + setMessages(prev => [...prev, { role: 'assistant', content }]) + } else { + const currentText = content + setMessages(prev => { + const updated = [...prev] + updated[updated.length - 1] = { role: 'assistant', content: currentText } + return updated + }) + } } } catch (err: unknown) { if (err instanceof Error && err.name === 'AbortError') return console.error('Chat error:', err) + setIsWaiting(false) setMessages(prev => [ ...prev, { role: 'assistant', content: lang === 'de' @@ -179,6 +188,7 @@ export default function ChatFAB({ lang, currentSlide, currentIndex, visitedSlide ]) } finally { setIsStreaming(false) + setIsWaiting(false) abortRef.current = null } } @@ -344,6 +354,32 @@ export default function ChatFAB({ lang, currentSlide, currentIndex, visitedSlide )} + {/* Waiting indicator */} + + {isWaiting && ( + +
+ +
+
+ {[0, 1, 2].map(i => ( + + ))} +
+
+ )} +
+ {messages.map((msg, idx) => (