ScrollTopButton: make better use of callbacks, keep `scrolledTop` state
This commit is contained in:
parent
2380a0b667
commit
460a6e14c3
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue