ScrollTopButton: make better use of callbacks, keep `scrolledTop` state

This commit is contained in:
Alex Gleason 2023-10-02 11:50:20 -05:00
parent 2380a0b667
commit 460a6e14c3
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
1 changed files with 20 additions and 19 deletions

View File

@ -29,39 +29,40 @@ const ScrollTopButton: React.FC<IScrollTopButton> = ({
const intl = useIntl(); const intl = useIntl();
const settings = useSettings(); const settings = useSettings();
// Whether we are scrolled past the `threshold`.
const [scrolled, setScrolled] = useState<boolean>(false); const [scrolled, setScrolled] = useState<boolean>(false);
const autoload = settings.get('autoloadTimelines') === true; // Whether we are scrolled above the `autoloadThreshold`.
const [scrolledTop, setScrolledTop] = useState<boolean>(true);
const autoload = settings.get('autoloadTimelines') === true;
const visible = count > 0 && scrolled; const visible = count > 0 && scrolled;
/** Number of pixels scrolled down from the top of the page. */
const getScrollTop = (): number => { const getScrollTop = (): number => {
return (document.scrollingElement || document.documentElement).scrollTop; return (document.scrollingElement || document.documentElement).scrollTop;
}; };
const maybeUnload = () => { /** Unload feed items if scrolled to the top. */
if (autoload && getScrollTop() <= autoloadThreshold) { const maybeUnload = useCallback(() => {
if (autoload && scrolledTop) {
onClick(); onClick();
} }
}; }, [autoload, scrolledTop, onClick]);
/** Set state while scrolling. */
const handleScroll = useCallback(throttle(() => { const handleScroll = useCallback(throttle(() => {
maybeUnload(); const scrollTop = getScrollTop();
if (getScrollTop() > threshold) { setScrolled(scrollTop > threshold);
setScrolled(true); setScrolledTop(scrollTop <= autoloadThreshold);
} else {
setScrolled(false);
}
}, 150, { trailing: true }), [autoload, threshold, autoloadThreshold, onClick]);
const scrollUp = () => { }, 150, { trailing: true }), [threshold, autoloadThreshold]);
/** Scroll to top and trigger `onClick`. */
const handleClick: React.MouseEventHandler = useCallback(() => {
window.scrollTo({ top: 0 }); window.scrollTo({ top: 0 });
};
const handleClick: React.MouseEventHandler = () => {
setTimeout(scrollUp, 10);
onClick(); onClick();
}; }, [onClick]);
useEffect(() => { useEffect(() => {
window.addEventListener('scroll', handleScroll); window.addEventListener('scroll', handleScroll);
@ -69,11 +70,11 @@ const ScrollTopButton: React.FC<IScrollTopButton> = ({
return () => { return () => {
window.removeEventListener('scroll', handleScroll); window.removeEventListener('scroll', handleScroll);
}; };
}, [onClick]); }, [handleScroll]);
useEffect(() => { useEffect(() => {
maybeUnload(); maybeUnload();
}, [count]); }, [maybeUnload]);
if (!visible) { if (!visible) {
return null; return null;