ECHO-212 add scroll to bottom button in chat for tablet and desktop#264
ECHO-212 add scroll to bottom button in chat for tablet and desktop#264
Conversation
WalkthroughAdds on-screen visibility tracking for a bottom anchor in ProjectChatRoute, exposes a scroll target ref and visibility, and integrates a responsive ScrollToBottomButton that appears when the anchor is off-screen and scrolls to the latest messages when activated. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant PCR as ProjectChatRoute
participant OBS as useElementOnScreen
participant BTN as ScrollToBottomButton
participant AN as Bottom Anchor
U->>PCR: Open chat / scroll
PCR->>OBS: Observe AN (scrollTargetRef)
OBS-->>PCR: isVisible
PCR->>BTN: Render with elementRef and isVisible
U->>BTN: Click
BTN->>AN: scrollIntoView()
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Assessment against linked issues
Suggested reviewers
LGTM. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx(5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx (2)
echo/frontend/src/hooks/useElementOnScreen.ts (1)
useElementOnScreen(3-22)echo/frontend/src/components/common/ScrollToBottom.tsx (1)
ScrollToBottomButton(10-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ci-check-server
🔇 Additional comments (3)
echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx (3)
47-49: Imports look tight.Good additions. Both the component and hook are used below; no dead imports. LGTM.
249-251: Exposing the bottom-anchor state from the hook is fine.Returning scrollTargetRef and isVisible from useDembraneChat keeps the route lean. LGTM.
280-282: Plumbing into the route is correct.Destructuring the new fields and passing them down is consistent. LGTM.
🚨 Bugbot Trial ExpiredYour team's Bugbot trial has expired. Please contact your team administrator to turn on the paid plan to continue using Bugbot. A team admin can activate the plan in the Cursor dashboard. |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx (2)
65-69: IntersectionObserver config: memoize options + use threshold 0 for zero-height sentinel; bottom-only rootMargin.
- Inline options cause the observer to be torn down/recreated on every render because the hook depends on
optionsidentity. Memoize.- Zero-height sentinel + threshold: 0.1 can be flaky; use 0 for reliable firing.
- Prefer bottom-only rootMargin: "0px 0px -83px 0px" so only the bottom is adjusted.
This is a refinement of a previous suggestion; keeping it concise here.
Apply within this hunk:
- const [scrollTargetRef, isVisible] = useElementOnScreen({ - root: null, - rootMargin: "-83px", - threshold: 0.1, - }); + const [scrollTargetRef, isVisible] = useElementOnScreen(intersectionOptions);And insert just above Line 65:
const intersectionOptions = useMemo<IntersectionObserverInit>( () => ({ root: null, rootMargin: "0px 0px -83px 0px", threshold: 0, }), [], );Optional: if 83px is a magic number, measure the sticky footer’s height (via a ref) and derive
rootMargindynamically so the button reliably hides when the footer height changes.
469-479: Absolute positioning above sticky footer: consider a stable offset and anchored container.
bottom-[105%]depends on the parent height and can drift as the footer grows/shrinks (textarea resize, alerts). A fixed offset above the footer’s top edge is more stable.- Use Tailwind’s
-translate-x-1/2instead of an arbitrary translate for consistency.- Ensure the immediate wrapper has
relativeso the absolute child is anchored predictably.Previous discussion noted; repeating succinctly for future hardening.
For example:
-<Stack className="pb-2"> +<Stack className="relative pb-2">- className="absolute bottom-[105%] left-1/2 z-50 hidden translate-x-[-50%] md:flex" + className="absolute -top-3 left-1/2 z-50 hidden -translate-x-1/2 md:flex"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-13T09:55:32.304Z
Learnt from: ussaama
PR: Dembrane/echo#264
File: echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx:462-465
Timestamp: 2025-08-13T09:55:32.304Z
Learning: For scroll sentinel elements used with Intersection Observer in React components, aria-hidden="true" is sufficient for accessibility without needing explicit height styling, as the observer can detect zero-height elements entering/exiting the viewport.
Applied to files:
echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx
🧬 Code Graph Analysis (1)
echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx (2)
echo/frontend/src/hooks/useElementOnScreen.ts (1)
useElementOnScreen(3-22)echo/frontend/src/components/common/ScrollToBottom.tsx (1)
ScrollToBottomButton(10-32)
🔇 Additional comments (3)
echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx (3)
47-49: LGTM: correct imports for the new UI control and hook.Imports are accurate and scoped to the new feature. Ship it.
249-251: LGTM: exposing the sentinel ref and visibility from the hook makes the component integration clean.Shape and naming are fine for now; good separation of concerns.
463-465: LGTM: sentinel placement and a11y.
aria-hidden="true"on the zero-height anchor matches our prior learning and keeps it out of the a11y tree while remaining observable. Clean.
…264) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a scroll-to-bottom button in project chat that appears when you’re not viewing the latest messages. * Button shows or hides based on whether the chat’s bottom anchor is visible on-screen. * One-tap scrolls to the most recent messages for quicker navigation. * Responsively positioned above the footer on medium and larger screens for improved accessibility. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary by CodeRabbit