From c555ec1f622f804ea98364555386eb7eba706ae0 Mon Sep 17 00:00:00 2001 From: 12975 <1297598740@qq.com> Date: Fri, 30 Jan 2026 00:00:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=EF=BC=8C=E5=8C=85=E5=90=AB=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=8F=91=E9=80=81=E3=80=81=E7=A1=AE=E8=AE=A4=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E3=80=81=E8=AF=AD=E9=9F=B3=E8=BE=93=E5=85=A5=E5=8F=8A=E6=89=93?= =?UTF-8?q?=E5=AD=97=E6=9C=BA=E6=95=88=E6=9E=9C=E7=BB=84=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/Typewriter/Typewriter.tsx | 32 +++++++++++++++++++ src/pages/Chat/Chat.tsx | 19 ++++++++--- 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 src/components/common/Typewriter/Typewriter.tsx diff --git a/src/components/common/Typewriter/Typewriter.tsx b/src/components/common/Typewriter/Typewriter.tsx new file mode 100644 index 0000000..599ff2b --- /dev/null +++ b/src/components/common/Typewriter/Typewriter.tsx @@ -0,0 +1,32 @@ +import React, { useState, useEffect } from 'react'; + +interface TypewriterProps { + text: string; + speed?: number; + onComplete?: () => void; + children?: (text: string) => React.ReactNode; +} + +export const Typewriter: React.FC = ({ text, speed = 30, onComplete, children }) => { + const [displayedText, setDisplayedText] = useState(''); + const [currentIndex, setCurrentIndex] = useState(0); + + useEffect(() => { + if (currentIndex < text.length) { + const timeout = setTimeout(() => { + setDisplayedText(prev => prev + text[currentIndex]); + setCurrentIndex(prev => prev + 1); + }, speed); + + return () => clearTimeout(timeout); + } else if (onComplete) { + onComplete(); + } + }, [currentIndex, text, speed, onComplete]); + + if (children) { + return <>{children(displayedText)}; + } + + return <>{displayedText}; +}; diff --git a/src/pages/Chat/Chat.tsx b/src/pages/Chat/Chat.tsx index 773d263..b6fe4d0 100644 --- a/src/pages/Chat/Chat.tsx +++ b/src/pages/Chat/Chat.tsx @@ -6,6 +6,7 @@ import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import aiService from '../../services/aiService'; import type { AIChatResponse, ConfirmationCard } from '../../types'; +import { Typewriter } from '../../components/common/Typewriter/Typewriter'; import './Chat.css'; interface Message { @@ -273,16 +274,26 @@ export default function Chat() { ) : ( <> - {messages.map((msg) => ( + {messages.map((msg, index) => (
{msg.role === 'assistant' ? '🪙' : '👤'}
- - {msg.content} - + {msg.role === 'assistant' && index === messages.length - 1 ? ( + + {(text) => ( + + {text} + + )} + + ) : ( + + {msg.content} + + )}
{msg.confirmationCard && (