From f467db2ea09ff5fda2f79f1d1f67ee8fdd10cb83 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Fri, 6 Mar 2026 09:39:19 +0100 Subject: [PATCH] fix(pitch-deck): Waiting-Indicator in ChatFAB (richtiges Komponente) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ChatInterface.tsx war falsch — der echte Investor Agent laeuft in ChatFAB.tsx. Animierte Punkte + firstChunk-Logik dort implementiert. Session-History laeuft bereits korrekt (FAB permanent gemountet). Co-Authored-By: Claude Sonnet 4.6 --- pitch-deck/components/ChatFAB.tsx | 52 ++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 8 deletions(-) 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) => (