Skip to content

📝 CodeRabbit Chat: Implement requested code changes - #599

Closed
coderabbitai[bot] wants to merge 1 commit into
fix/followup-panel-streaming-5274824833186492759from
coderabbitai/chat/7ab4e93
Closed

📝 CodeRabbit Chat: Implement requested code changes#599
coderabbitai[bot] wants to merge 1 commit into
fix/followup-panel-streaming-5274824833186492759from
coderabbitai/chat/7ab4e93

Conversation

@coderabbitai

Copy link
Copy Markdown
Contributor

Code changes was requested by @ngoiyaeric.

The following files were modified:

  • app/actions.tsx

@coderabbitai
coderabbitaiBot requested a review from ngoiyaericMay 7, 2026 14:12
@vercel

vercelBot commented May 7, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
qcxErrorErrorMay 7, 2026 2:12pm

@coderabbitai

Copy link
Copy Markdown
ContributorAuthor

Important

Review skipped

This PR was authored by the user configured for CodeRabbit reviews. CodeRabbit does not review PRs authored by this user. It's recommended to use a dedicated user account to post CodeRabbit review feedback.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f06feb8f-85aa-49ca-a21d-7f5e10cadc6e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands and usage tips.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@ngoiyaeric

Copy link
Copy Markdown
Collaborator

@coderabbitai the reads is loading open instead of animating consecutively after the page loads to preview all the text as the user scrolls, fix this bug

@coderabbitai

Copy link
Copy Markdown
ContributorAuthor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Let me look at the relevant files to understand the current implementation.


🏁 Script executed:

#!/bin/bash
# Find the reads-related components
fd -e tsx -e ts -e jsx -e js | xargs grep -l -i "reads\|accordion\|collapse\|expand" 2>/dev/null | head -30
echo "---"
# Look at app/actions.tsx
cat app/actions.tsx 2>/dev/null || echo "File not found"

Length of output: 25352


Let me look at the collapsible message and chat message components.


🏁 Script executed:

#!/bin/bash
cat components/collapsible-message.tsx
echo "==="
cat components/chat-messages.tsx
echo "==="
cat components/section.tsx 2>/dev/null || echo "section not found"

Length of output: 5945


@ngoiyaeric, I found the root causes. There are three bugs working together:

  1. AnimatePresence initial={false} — This explicitly suppresses the entry animation on first render, so collapsible sections that are open on mount never animate in.
  2. open initialised to isLastMessage — The last message starts as open = true immediately on page load, with no animation.
  3. Non-collapsed messages have zero animation — The if (!isCollapsed) return message.component path renders content instantly with no scroll-triggered entrance at all.

Here is the fix across both files:


components/collapsible-message.tsx — add index prop, start open as false, use whileInView for scroll-triggered consecutive animation, and remove initial={false}:

'use client'importReact,{useEffect,useRef,useState}from'react'import{Collapsible,CollapsibleTrigger,CollapsibleContent}from'@radix-ui/react-collapsible'import{Button}from'./ui/button'import{ChevronDown}from'lucide-react'import{StreamableValue,useStreamableValue}from'ai/rsc'import{motion,AnimatePresence,useInView}from'framer-motion'import{cn}from'@/lib/utils'import{Separator}from'./ui/separator'interfaceCollapsibleMessageProps{message: {id: stringisCollapsed?: StreamableValue<boolean>component: React.ReactNode}isLastMessage?: booleanindex?: number}exportconstCollapsibleMessage: React.FC<CollapsibleMessageProps>=({
message,
isLastMessage =false,
index =0})=>{const[data]=useStreamableValue(message.isCollapsed)constisCollapsed=data??false// Always start closed so the staggered open animation can playconst[open,setOpen]=useState(false)// Ref used to detect when this message scrolls into viewconstref=useRef<HTMLDivElement>(null)constisInView=useInView(ref,{once: true,margin: '-60px'})useEffect(()=>{if(isInView){// Stagger: each message waits a little longer based on its positionconsttimer=setTimeout(()=>setOpen(true),index*120// 0 ms, 120 ms, 240 ms …)return()=>clearTimeout(timer)}},[isInView,index])// When the user manually toggles, respect that immediatelyconsthandleOpenChange=(value: boolean)=>setOpen(value)// Non-collapsed messages (BotMessage, Section wrappers, etc.)// Animate in with a fade + slight upward slide as they enter the viewportif(!isCollapsed){return(<motion.divref={ref}initial={{opacity: 0,y: 16}}animate={isInView ? {opacity: 1,y: 0} : {opacity: 0,y: 16}}transition={{duration: 0.45,ease: 'easeOut',delay: index*0.08}}>{message.component}</motion.div>)}return(<divref={ref}><Collapsibleopen={open}onOpenChange={handleOpenChange}><CollapsibleTriggerasChild><divclassName="w-full flex justify-end"><Buttonvariant="ghost"size={'icon'}className={cn('-mt-3 rounded-full')}><ChevronDownsize={14}className={cn(open ? 'rotate-180' : 'rotate-0','h-4 w-4 transition-all')}/><spanclassName="sr-only">collapse</span></Button></div></CollapsibleTrigger>{/* Remove initial={false} so the animation fires on first mount */}<AnimatePresence>{open&&(<CollapsibleContentasChildforceMount><motion.divinitial={{opacity: 0,height: 0}}animate={{opacity: 1,height: 'auto'}}exit={{opacity: 0,height: 0}}transition={{duration: 0.35,ease: 'easeInOut'}}className="overflow-hidden">{message.component}</motion.div></CollapsibleContent>)}</AnimatePresence>{!open&&<SeparatorclassName="my-2 bg-muted"/>}</Collapsible></div>)}

components/chat-messages.tsx — pass index so each message gets its own stagger delay:

return(<>{groupedMessagesArray.map((groupedMessage: {id: stringcomponents: React.ReactNode[]isCollapsed?: StreamableValue<boolean>},index// ← already available, just pass it down)=>(<CollapsibleMessagekey={`${groupedMessage.id}`}message={{id: groupedMessage.id,component: groupedMessage.components.map((component,i)=>(<divkey={`${groupedMessage.id}-${i}`}>{component}</div>)),isCollapsed: groupedMessage.isCollapsed}}isLastMessage={groupedMessage.id===messages[messages.length-1].id}index={index}// ← add this/>))}</>)

What this achieves:

BeforeAfter
All sections render open immediately on page loadAll sections start hidden (opacity: 0, y: 16)
AnimatePresence initial={false} kills mount animationEntry animation fires when each section scrolls into the viewport
No stagger — everything pops in at onceEach section waits index × 120 ms, creating a consecutive wave as you scroll
Non-collapsed messages had zero animationNon-collapsed messages now fade+slide in via whileInView
  • Apply animation fix to components/collapsible-message.tsx — add index prop, useInView hook, viewport-triggered staggered open, remove AnimatePresence initial={false}, wrap non-collapsed path in animated motion.div
  • Apply index prop pass-through in components/chat-messages.tsx

The requested changes have been implemented and a pull request has been created: View PR

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@CLAassistant@ngoiyaeric