diff --git a/components/chat-messages.tsx b/components/chat-messages.tsx index 6bfa3642..8eda416b 100644 --- a/components/chat-messages.tsx +++ b/components/chat-messages.tsx @@ -62,6 +62,7 @@ export function ChatMessages({ messages }: ChatMessagesProps) { isLastMessage={ groupedMessage.id === messages[messages.length - 1].id } + index={index} /> ) )} diff --git a/components/collapsible-message.tsx b/components/collapsible-message.tsx index b3349bc7..5b49f4d3 100644 --- a/components/collapsible-message.tsx +++ b/components/collapsible-message.tsx @@ -1,6 +1,6 @@ 'use client' -import React, { useEffect, useState } from 'react' +import React, { useEffect, useRef, useState } from 'react' import { Collapsible, CollapsibleTrigger, @@ -9,7 +9,7 @@ import { import { Button } from './ui/button' import { ChevronDown } from 'lucide-react' import { StreamableValue, useStreamableValue } from 'ai/rsc' -import { motion, AnimatePresence } from 'framer-motion' +import { motion, AnimatePresence, useInView } from 'framer-motion' import { cn } from '@/lib/utils' import { Separator } from './ui/separator' @@ -20,71 +20,93 @@ interface CollapsibleMessageProps { component: React.ReactNode } isLastMessage?: boolean + index?: number } export const CollapsibleMessage: React.FC = ({ message, - isLastMessage = false + isLastMessage = false, + index = 0 }) => { const [data] = useStreamableValue(message.isCollapsed) const isCollapsed = data ?? false const [open, setOpen] = useState(isLastMessage) + const ref = useRef(null) + const isInView = useInView(ref, { once: true, margin: '0px 0px -50px 0px' }) useEffect(() => { setOpen(isLastMessage) }, [isCollapsed, isLastMessage]) - // if not collapsed, return the component + const staggerDelay = index * 0.08 + + // if not collapsed, return the component with entrance animation if (!isCollapsed) { - return message.component + return ( + + {message.component} + + ) } return ( - { - setOpen(value) - }} + - -
- -
-
- - {open && ( - - - {message.component} - - - )} - - {!open && } -
+ + collapse + + + + + {open && ( + + + {message.component} + + + )} + + {!open && } + + ) }