diff options
Diffstat (limited to 'extension/react-app')
| -rw-r--r-- | extension/react-app/src/pages/gui.tsx | 90 | 
1 files changed, 30 insertions, 60 deletions
| diff --git a/extension/react-app/src/pages/gui.tsx b/extension/react-app/src/pages/gui.tsx index c4e13d2a..c82f4f2b 100644 --- a/extension/react-app/src/pages/gui.tsx +++ b/extension/react-app/src/pages/gui.tsx @@ -3,7 +3,13 @@ import { defaultBorderRadius } from "../components";  import Loader from "../components/Loader";  import ContinueButton from "../components/ContinueButton";  import { FullState } from "../../../schema/FullState"; -import { useCallback, useEffect, useRef, useState, useContext } from "react"; +import { +  useEffect, +  useRef, +  useState, +  useContext, +  useLayoutEffect, +} from "react";  import { HistoryNode } from "../../../schema/HistoryNode";  import StepContainer from "../components/StepContainer";  import { GUIClientContext } from "../App"; @@ -99,70 +105,39 @@ function GUI(props: GUIProps) {      );    }, [bottomMessage, aboveComboBoxDivRef.current]); -  const [isScrolling, setIsScrolling] = useState(false); - -  const [scrollTimeoutId, setScrollTimeoutId] = useState<NodeJS.Timeout>(); +  const [userScrolledAwayFromBottom, setUserScrolledAwayFromBottom] = +    useState<boolean>(false); -  const scrollToBottom = useCallback( -    (force: boolean = false) => { -      if (scrollTimeoutId) { -        return; -      } - -      // Scroll only if user is within 100 pixels of the bottom of the window. -      const edgeOffset = 50; -      const scrollPosition = window.scrollY || 0; +  useEffect(() => { +    const handleScroll = () => { +      // Scroll only if user is within 200 pixels of the bottom of the window. +      const edgeOffset = -25; +      const scrollPosition = topGuiDivRef.current?.scrollTop || 0;        const scrollHeight = topGuiDivRef.current?.scrollHeight || 0;        const clientHeight = window.innerHeight || 0; -      const atBottomEdge = -        scrollPosition + clientHeight + edgeOffset >= scrollHeight; - -      if (isScrolling || (!atBottomEdge && !force)) { -        return; +      if (scrollPosition + clientHeight + edgeOffset >= scrollHeight) { +        setUserScrolledAwayFromBottom(false); +      } else { +        setUserScrolledAwayFromBottom(true);        } - -      window.scrollTo({ -        top: scrollHeight, -        behavior: "smooth", -      }); - -      setScrollTimeoutId( -        setTimeout(() => { -          setScrollTimeoutId(undefined); -        }, 800) -      ); -    }, -    [ -      window.scrollY, -      topGuiDivRef.current?.scrollHeight, -      topGuiDivRef.current?.clientHeight, -      isScrolling, -      scrollTimeoutId, -    ] -  ); - -  const [timerId, setTimerId] = useState<NodeJS.Timeout>(); - -  useEffect(() => { -    const handleScrollEnd = () => { -      setIsScrolling(false);      }; -    const handleScroll = () => { -      window.clearTimeout(timerId); - -      setIsScrolling(true); +    topGuiDivRef.current?.addEventListener("wheel", handleScroll); -      setTimerId(setTimeout(() => handleScrollEnd(), 800)); +    return () => { +      window.removeEventListener("wheel", handleScroll);      }; +  }, [topGuiDivRef.current]); -    window.addEventListener("scroll", handleScroll); +  useLayoutEffect(() => { +    if (userScrolledAwayFromBottom) return; -    return () => { -      window.removeEventListener("scroll", handleScroll); -    }; -  }, []); +    topGuiDivRef.current?.scrollTo({ +      top: topGuiDivRef.current?.scrollHeight, +      behavior: "smooth" as any, +    }); +  }, [topGuiDivRef.current?.scrollHeight, history.timeline]);    useEffect(() => {      // Cmd + Backspace to delete current step @@ -217,15 +192,9 @@ function GUI(props: GUIProps) {          }          return nextStepsOpen;        }); - -      scrollToBottom();      });    }, [client]); -  useEffect(() => { -    scrollToBottom(true); -  }, [waitingForSteps]); -    // #endregion    useEffect(() => { @@ -378,6 +347,7 @@ function GUI(props: GUIProps) {    }, []);    return (      <div +      className="overflow-scroll"        ref={topGuiDivRef}        onKeyDown={(e) => {          if (e.key === "Enter" && e.ctrlKey) { | 
