524370711c
(1) Reduced the debouncing duration so that the final element can be rendered asap after visible. - If the user is scrolling non-stop, it would continue to debounce and the GUI ends up not showing the final element. - 25ms seems enough to prevent the initial false-positive that occurs in the scenario of "adjacent/upper elements resized late, so our element was briefly on screen when mounted". If not enough, we can make this a parameter. (2) Removed `lastUpdateDate` that was a quick hack for Recommended section. We don't use it on that element anymore, so remove the hack to keep the file clean.
53 lines
1.4 KiB
JavaScript
53 lines
1.4 KiB
JavaScript
// @flow
|
|
import React from 'react';
|
|
import debounce from 'util/debounce';
|
|
|
|
const DEBOUNCE_SCROLL_HANDLER_MS = 25;
|
|
|
|
type Props = {
|
|
children: any,
|
|
skipWait?: boolean,
|
|
placeholder?: any,
|
|
};
|
|
|
|
export default function WaitUntilOnPage(props: Props) {
|
|
const ref = React.useRef();
|
|
const [shouldRender, setShouldRender] = React.useState(false);
|
|
|
|
React.useEffect(() => {
|
|
const handleDisplayingRef = debounce((e) => {
|
|
const element = ref && ref.current;
|
|
if (element) {
|
|
const bounding = element.getBoundingClientRect();
|
|
if (
|
|
bounding.bottom >= 0 &&
|
|
bounding.right >= 0 &&
|
|
// $FlowFixMe
|
|
bounding.top <= (window.innerHeight || document.documentElement.clientHeight) &&
|
|
// $FlowFixMe
|
|
bounding.left <= (window.innerWidth || document.documentElement.clientWidth)
|
|
) {
|
|
setShouldRender(true);
|
|
}
|
|
}
|
|
|
|
if (element && !shouldRender) {
|
|
window.addEventListener('scroll', handleDisplayingRef);
|
|
return () => window.removeEventListener('scroll', handleDisplayingRef);
|
|
}
|
|
}, DEBOUNCE_SCROLL_HANDLER_MS);
|
|
|
|
if (ref) {
|
|
handleDisplayingRef();
|
|
}
|
|
}, [ref, setShouldRender, shouldRender]);
|
|
|
|
const render = props.skipWait || shouldRender;
|
|
|
|
return (
|
|
<div ref={ref}>
|
|
{render && props.children}
|
|
{!render && props.placeholder !== undefined && props.placeholder}
|
|
</div>
|
|
);
|
|
}
|