@@ -31,6 +31,7 @@ import { RendererComponent } from "@/app/chat/message/messageComponents/renderMe
3131import AgentIcon from "@/refresh-components/AgentIcon" ;
3232import IconButton from "@/refresh-components/buttons/IconButton" ;
3333import SvgCopy from "@/icons/copy" ;
34+ import SvgCheck from "@/icons/check" ;
3435import SvgThumbsUp from "@/icons/thumbs-up" ;
3536import SvgThumbsDown from "@/icons/thumbs-down" ;
3637import {
@@ -59,8 +60,10 @@ export default function AIMessage({
5960 onMessageSelection,
6061} : AIMessageProps ) {
6162 const markdownRef = useRef < HTMLDivElement > ( null ) ;
63+ const copyTimeoutRef = useRef < NodeJS . Timeout | null > ( null ) ;
6264
6365 const { toggleModal } = useChatModal ( ) ;
66+ const [ copied , setCopied ] = useState ( false ) ;
6467
6568 const [ finalAnswerComing , _setFinalAnswerComing ] = useState (
6669 isFinalAnswerComing ( rawPackets ) || isStreamingComplete ( rawPackets )
@@ -113,6 +116,16 @@ export default function AIMessage({
113116 resetState ( ) ;
114117 } , [ nodeId ] ) ;
115118
119+ // Clean up copy timeout on unmount or when switching messages
120+ useEffect ( ( ) => {
121+ setCopied ( false ) ;
122+ return ( ) => {
123+ if ( copyTimeoutRef . current ) {
124+ clearTimeout ( copyTimeoutRef . current ) ;
125+ }
126+ } ;
127+ } , [ nodeId ] ) ;
128+
116129 // If the upstream replaces packets with a shorter list (reset), clear state
117130 if ( lastProcessedIndexRef . current > rawPackets . length ) {
118131 resetState ( ) ;
@@ -363,10 +376,19 @@ export default function AIMessage({
363376 ) }
364377
365378 < IconButton
366- icon = { SvgCopy }
367- onClick = { ( ) => copyAll ( getTextContent ( rawPackets ) ) }
379+ icon = { copied ? SvgCheck : SvgCopy }
380+ onClick = { ( ) => {
381+ copyAll ( getTextContent ( rawPackets ) ) ;
382+ setCopied ( true ) ;
383+ if ( copyTimeoutRef . current ) {
384+ clearTimeout ( copyTimeoutRef . current ) ;
385+ }
386+ copyTimeoutRef . current = setTimeout ( ( ) => {
387+ setCopied ( false ) ;
388+ } , 3000 ) ;
389+ } }
368390 tertiary
369- tooltip = " Copy"
391+ tooltip = { copied ? "Copied!" : " Copy"}
370392 data-testid = "AIMessage/copy-button"
371393 />
372394 < IconButton
0 commit comments