Skip to content

Conversation

MayankBansal2004
Copy link
Contributor

@MayankBansal2004 MayankBansal2004 commented Oct 10, 2025

Description

chatpage space buffer reducer for sources/followps divs

Testing

tested locally.

Additional Notes

Summary by CodeRabbit

  • New Features

    • Smoother chat experience: message area now continuously adjusts bottom spacing during streaming and finalizes spacing after responses so action buttons, sources, and follow-ups remain visible.
    • Follow-up suggestions notify the layout when finished loading to trigger spacing recalculation.
  • Bug Fixes

    • Reduced layout jitter and flicker during streaming.
    • Prevented content from overlapping or being cut off near the bottom of the chat.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @MayankBansal2004, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors and enhances the dynamic bottom spacing mechanism on the chat page. The primary goal is to ensure that the buffer space at the bottom of the chat window correctly accommodates the height of dynamically rendered elements such as sources, action buttons, and follow-up questions, particularly after an assistant message has completed streaming. This prevents UI elements from being cut off or having excessive whitespace, improving the overall user experience.

Highlights

  • Refactored Bottom Space Adjustment Logic: The dynamic logic for adjusting the chat page's bottom buffer has been consolidated into a shared, memoized adjustBottomSpaceForContent function, improving reusability and control over updates.
  • Improved Post-Streaming Spacing: A new useEffect has been introduced to specifically handle bottom space adjustments after an assistant message finishes streaming. This uses timed delays to accurately account for the rendering of action buttons, sources, and follow-up questions, preventing UI elements from being cut off.
  • Dedicated Follow-Up Load Callback: A new callback mechanism (onFollowUpQuestionsLoaded) has been added to trigger a precise bottom space adjustment once follow-up questions have finished loading, ensuring optimal UI presentation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 10, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Centralizes chat bottom-space management by adding adjustBottomSpaceForContent with ResizeObserver + interval-driven updates during streaming, a post-stream finalization flow, and a follow-up-loaded callback. Threads a new onFollowUpQuestionsLoaded prop through VirtualizedMessages → ChatBox → FollowUpQuestions. (≤50 words)

Changes

Cohort / File(s) Summary
Chat bottom-space & streaming flow
frontend/src/routes/_authenticated/chat.tsx
Adds adjustBottomSpaceForContent(forceUpdate) to compute/update bottomSpace from last assistant message height with jitter control; uses ResizeObserver + periodic interval during streaming; adds post-stream finalization (observer + timed adjustments); adds handleFollowUpQuestionsLoaded.
Public API / Prop threading
frontend/src/routes/_authenticated/.../VirtualizedMessages*, frontend/src/routes/_authenticated/.../ChatBox*, .../FollowUpQuestions*
Adds onFollowUpQuestionsLoaded: () => void to VirtualizedMessagesProps and wires it through VirtualizedMessagesChatBoxFollowUpQuestions (mapped to onQuestionsLoaded) so follow-up loads trigger spacing recalculation. Minor prop/type adjustments to accommodate wiring.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant Chat as Chat Route
  participant RO as ResizeObserver
  participant T as Interval Timer
  participant VM as VirtualizedMessages
  participant CB as ChatBox
  participant FU as FollowUpQuestions

  User->>Chat: open chat / start streaming
  Chat->>RO: observe last assistant message
  Chat->>T: start periodic spacing ticks
  RO-->>Chat: resize event
  T-->>Chat: tick
  Chat->>Chat: adjustBottomSpaceForContent()

  Chat->>VM: render (onFollowUpQuestionsLoaded)
  VM->>CB: pass onFollowUpQuestionsLoaded
  CB->>FU: render (onQuestionsLoaded wired)

  FU-->>CB: onQuestionsLoaded
  CB-->>VM: onFollowUpQuestionsLoaded
  VM-->>Chat: onFollowUpQuestionsLoaded
  Chat->>Chat: adjustBottomSpaceForContent(forceUpdate)

  Chat->>T: stop interval
  Chat->>RO: finalize observe + timers
  Chat->>Chat: final adjust for actions/sources/follow-ups
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • zereraz
  • shivamashtikar
  • kalpadhwaryu
  • junaid-shirur
  • devesh-juspay

Poem

A twitch and hop, my whiskers gleam,
I nudge the bottom, tune the stream.
Observers hum and timers play,
Follow-ups hop in right away.
This rabbit bumps the chat to rhyme — neat space, on time! 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title refers to reducing the space buffer for sources and follow-ups, which aligns with a valid part of the changes introduced around bottom-space management, so it is at least partially related to the changeset.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/chatpage-extra-space-bug

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the logic for adjusting the empty space at the bottom of the chat page to reduce it as content like sources and follow-up questions appear. The changes introduce a shared callback function and new effects to handle this adjustment both during and after message streaming.

My review focuses on improving the performance and robustness of this new implementation. I've identified a couple of areas for improvement:

  1. A potential performance issue due to a dependency cycle in a useCallback, which can be fixed by using a functional state update.
  2. The use of brittle setTimeout calls with magic numbers and ResizeObservers attached to the wrong elements. I've suggested a more robust approach using ResizeObserver on the correct element, which should make the layout adjustments more reliable and remove the need for timers.

Overall, the goal of the PR is good, and the introduction of the onFollowUpQuestionsLoaded callback is a solid improvement. The suggested changes aim to make the implementation more efficient and maintainable.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
frontend/src/routes/_authenticated/chat.tsx (1)

891-918: Consider removing the redundant 400ms timeout for follow-up questions.

The effect uses a hardcoded 400ms timeout to catch follow-up questions loading (Line 904), but there's also a dedicated callback handleFollowUpQuestionsLoaded (Lines 920-923) that's triggered when follow-up questions actually finish loading (Line 2323). The callback-based approach is more reliable than a fixed timeout, so the 400ms timeout might be redundant.

Consider simplifying by removing the 400ms timeout and relying solely on the callback:

-    // Timed adjustments to catch elements as they appear:
-    // 50ms: action buttons, 200ms: sources, 400ms: follow-up loading, 600ms: safety check
-    const timeouts = [50, 200, 400, 600].map((delay) =>
+    // Timed adjustments to catch elements as they appear:
+    // 50ms: action buttons, 200ms: sources, 600ms: safety check
+    const timeouts = [50, 200, 600].map((delay) =>
       setTimeout(() => adjustBottomSpaceForContent(true), delay),
     )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f1ec904 and f827341.

📒 Files selected for processing (1)
  • frontend/src/routes/_authenticated/chat.tsx (6 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: MayankBansal2004
PR: xynehq/xyne#765
File: server/api/chat/chat.ts:5706-5712
Timestamp: 2025-09-04T08:53:33.995Z
Learning: MayankBansal2004 prefers to defer technical improvements like input validation and type safety when the current implementation is working, even when acknowledging potential benefits. He takes a pragmatic approach of "if it's not broken, don't fix it" and will revisit improvements when he has bandwidth.
Learnt from: MayankBansal2004
PR: xynehq/xyne#532
File: frontend/src/routes/_authenticated/chat.tsx:1238-1242
Timestamp: 2025-06-16T08:36:57.488Z
Learning: MayankBansal2004 prefers to keep working implementations even when security improvements are suggested, but appreciates being made aware of potential security considerations for future reference.
🔇 Additional comments (2)
frontend/src/routes/_authenticated/chat.tsx (2)

920-923: LGTM! Callback mechanism for follow-up questions is well-implemented.

The new handleFollowUpQuestionsLoaded callback and its integration through the component tree is clean:

  • Callback triggers spacing recalculation after follow-ups load (Lines 920-923)
  • Properly threaded through VirtualizedMessages props (Lines 1512, 1990, 2033)
  • Correctly passed to FollowUpQuestions as onQuestionsLoaded (Line 2323)

This event-driven approach is more reliable than fixed timeouts for handling dynamic content loading.

Also applies to: 1512-1512, 1990-1990, 2033-2033, 2323-2323


834-864: Verify assistant message wrapper includes all dynamic content.

Ensure the element with data-message-role="assistant" fully wraps each assistant message’s action buttons, source citations, and follow-up questions—any content rendered outside that wrapper won’t be included in offsetHeight, causing bottom-space miscalculations.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
frontend/src/routes/_authenticated/chat.tsx (2)

869-893: Observe the last assistant element; drop unused deps to prevent effect churn

Observing the scrolling container won’t fire when inner content grows; observe the last assistant message element instead. Also, partial and currentResp aren’t used here and cause re-subscribes during streaming.

Apply:

   useEffect(() => {
     if (!streamingStarted || (!isStreaming && !retryIsStreaming)) return
     if (initialBottomSpace === 0) return
 
-    const observer = new ResizeObserver(() => adjustBottomSpaceForContent())
-    const interval = setInterval(() => adjustBottomSpaceForContent(), 100)
+    const observer = new ResizeObserver(() => adjustBottomSpaceForContent())
+    const interval = setInterval(() => adjustBottomSpaceForContent(), 100)
+    // Initial sync
+    adjustBottomSpaceForContent()
 
-    const container = messagesContainerRef.current
-    if (container) observer.observe(container)
+    const container = messagesContainerRef.current
+    if (container) {
+      const assistants = container.querySelectorAll(
+        '[data-message-role="assistant"]',
+      )
+      const lastMessage = assistants[assistants.length - 1] as HTMLElement | null
+      if (lastMessage) observer.observe(lastMessage)
+    }
 
     return () => {
       observer.disconnect()
       clearInterval(interval)
     }
   }, [
     streamingStarted,
     isStreaming,
     retryIsStreaming,
     initialBottomSpace,
-    adjustBottomSpaceForContent,
-    partial,
-    currentResp,
+    adjustBottomSpaceForContent,
   ])

894-920: Post-stream observer should also track the last assistant element; timers can be simplified

Same as above, observe the last assistant message, not the container. Optional: the multiple timeouts can be replaced by a single RAF + one safety timeout now that you also get an explicit onQuestionsLoaded callback from FollowUpQuestions.

Apply (observer target change):

-  const container = messagesContainerRef.current
-  if (container) observer.observe(container)
+  const container = messagesContainerRef.current
+  if (container) {
+    const assistants = container.querySelectorAll(
+      '[data-message-role="assistant"]',
+    )
+    const lastMessage = assistants[assistants.length - 1] as HTMLElement | null
+    if (lastMessage) observer.observe(lastMessage)
+  }

Optional simplification (timers):

-  const timeouts = [50, 200, 400, 600].map((delay) =>
-    setTimeout(() => adjustBottomSpaceForContent(true), delay),
-  )
+  const rafId = requestAnimationFrame(() =>
+    adjustBottomSpaceForContent(true),
+  )
+  const safetyTimeout = setTimeout(
+    () => adjustBottomSpaceForContent(true),
+    300,
+  )
 
   return () => {
     observer.disconnect()
-    timeouts.forEach(clearTimeout)
+    cancelAnimationFrame(rafId)
+    clearTimeout(safetyTimeout)
   }
🧹 Nitpick comments (2)
frontend/src/routes/_authenticated/chat.tsx (2)

834-867: Core logic OK; consider avoiding repeated DOM queries in hot path

adjustBottomSpaceForContent looks correct and stable. Minor: calling querySelectorAll on every tick (observer/interval) is extra work. Cache the last assistant element ref outside the function and reuse it across calls within an effect cycle.


921-925: Good hook; prefer RAF over fixed delay

Use requestAnimationFrame to avoid arbitrary 150ms delay and reduce jank.

-const handleFollowUpQuestionsLoaded = useCallback(() => {
-  setTimeout(() => adjustBottomSpaceForContent(true), 150)
-}, [adjustBottomSpaceForContent])
+const handleFollowUpQuestionsLoaded = useCallback(() => {
+  requestAnimationFrame(() => adjustBottomSpaceForContent(true))
+}, [adjustBottomSpaceForContent])
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f827341 and eaa96f6.

📒 Files selected for processing (1)
  • frontend/src/routes/_authenticated/chat.tsx (6 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: MayankBansal2004
PR: xynehq/xyne#765
File: server/api/chat/chat.ts:5706-5712
Timestamp: 2025-09-04T08:53:33.995Z
Learning: MayankBansal2004 prefers to defer technical improvements like input validation and type safety when the current implementation is working, even when acknowledging potential benefits. He takes a pragmatic approach of "if it's not broken, don't fix it" and will revisit improvements when he has bandwidth.
Learnt from: MayankBansal2004
PR: xynehq/xyne#532
File: frontend/src/routes/_authenticated/chat.tsx:1238-1242
Timestamp: 2025-06-16T08:36:57.488Z
Learning: MayankBansal2004 prefers to keep working implementations even when security improvements are suggested, but appreciates being made aware of potential security considerations for future reference.
🔇 Additional comments (3)
frontend/src/routes/_authenticated/chat.tsx (3)

1991-1992: LGTM: Prop added to type surface

onFollowUpQuestionsLoaded added to VirtualizedMessagesProps is clear and minimal.


2034-2035: LGTM: Prop threaded into component

Destructuring onFollowUpQuestionsLoaded in VirtualizedMessages is correct.


2314-2325: LGTM: Follow-ups wired with onQuestionsLoaded

Hooking onQuestionsLoaded to onFollowUpQuestionsLoaded enables precise spacing finalization after follow-ups load.

@shivamashtikar shivamashtikar merged commit 6ed3d75 into main Oct 10, 2025
3 of 4 checks passed
@shivamashtikar shivamashtikar deleted the fix/chatpage-extra-space-bug branch October 10, 2025 13:11
junaid-shirur pushed a commit that referenced this pull request Oct 13, 2025
## [3.13.4](v3.13.3...v3.13.4) (2025-10-10)

### Bug Fixes

* XYN-175 chatpage space buffer reducer for sources/followps divs ([#1087](#1087)) ([6ed3d75](6ed3d75))
Sign up for free to 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