Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed autoscroll on hovering messaged + update messages #638

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

michaelwlt
Copy link

The previous implementation of the autoscroll was too broad, essentially moving the view too often.
This PR fixes #597

Copy link

vercel bot commented Dec 18, 2024

@michaelwlt is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

@gianpaj
Copy link

gianpaj commented Jan 14, 2025

i tried this but now it doesn't auto-scroll if there's a new message

@michaelwlt
Copy link
Author

michaelwlt commented Jan 14, 2025

@gianpaj Not sure, why it is not working on your end. My instance here: https://codeberg.org/michaelwlt/bettergptv2 works without any problem.
Maybe you have changed something in your codebase elsewhere?

@gianpaj
Copy link

gianpaj commented Jan 14, 2025

I have other code changes. But not in the components/messages.tsx or components/use-scroll-to-bottom.ts.

The issue is that it now scrolls only if you're at the bottom of the list of messages.
Maybe these videos can better explain the before and after this change.

before

before-scroll-opt.mp4

after

after-scroll-opt.mp4

I'm not sure how to debug the MutationObserver, but I think it should trigger if a Tooltip is visible.


I'm not sure if this is the correct fix, but I tried removing this line, and it seems to fix the original issue and keep the scrolling working for new messages

       observer.observe(container, {
         childList: true,
-        subtree: true,
+        // subtree: true,
         attributes: true,
         characterData: true,
       });

@michaelwlt
Copy link
Author

Remove subtree: true breaks the behavior for me.
I've fixed it now in the following way:

import { useEffect, useRef, type RefObject } from "react";

export function useScrollToBottom<T extends HTMLElement>(): [
  RefObject<T | null>,
  RefObject<T | null>,
] {
  const containerRef = useRef<T | null>(null);
  const endRef = useRef<T | null>(null);
  const shouldScrollRef = useRef(true);
  const prevChildCountRef = useRef(0);

  useEffect(() => {
    const container = containerRef.current;
    const end = endRef.current;

    if (container && end) {
      // Initial scroll
      end.scrollIntoView({ behavior: "instant", block: "end" });
      prevChildCountRef.current = container.childNodes.length;

      // Check if user has scrolled up
      const handleScroll = () => {
        if (!container) return;

        const isAtBottom =
          Math.abs(
            container.scrollHeight -
              container.scrollTop -
              container.clientHeight,
          ) < 10;

        shouldScrollRef.current = isAtBottom;
      };

      const observer = new MutationObserver(() => {
        if (!container) return;
        
        // Check if a new message was added (child count increased)
        const currentChildCount = container.childNodes.length;
        const isNewMessage = currentChildCount > prevChildCountRef.current;
        prevChildCountRef.current = currentChildCount;

        // Only force scroll on new message or if already at bottom
        if (isNewMessage || shouldScrollRef.current) {
          end.scrollIntoView({ behavior: "instant", block: "end" });
        }
      });

      observer.observe(container, {
        childList: true,
        subtree: true,
        characterData: true,
      });

      // Add scroll listener
      container.addEventListener("scroll", handleScroll);

      return () => {
        observer.disconnect();
        container.removeEventListener("scroll", handleScroll);
      };
    }
  }, []);

  return [containerRef, endRef];
}

This way it scrolls to the bottom if a new message is added but won't force you back down as soon as you start scrolling up.

@gianpaj
Copy link

gianpaj commented Jan 15, 2025

We should wait for a maintainer to weigh in on this, but I think the PR should fix the issue in the current version of the web app. And the less code, the better

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.

Hover over edit button scrolls to bottom of messages
2 participants