Cozy-Nest/cozy-nest-client/image-browser/Browser.jsx

68 lines
2.0 KiB
JavaScript

import React, {useContext, useEffect, useRef, useState} from "react";
import CozyImage from "./CozyImage.jsx";
import {ImagesContext} from "./ImagesContext.tsx";
const _LAZY_LOAD_MARGIN = 300
export default function Browser(props) {
const {images, filteredImages} = useContext(ImagesContext)
const _me = useRef(null)
const [page, setPage] = useState(0)
const [imagesLoaded, setImagesLoaded] = useState([])
const [viewPort, setViewPort] = useState({
top: 0,
bottom: window.innerHeight + _LAZY_LOAD_MARGIN
})
//when imagesRef changes, reset imagesLoaded
useEffect(() => {
setImagesLoaded([...filteredImages.slice(0, Math.min(page*20+20, filteredImages.length))])
}, [filteredImages, images])
//load 20 images on mount when imagesRef is set
if (filteredImages.length > 0 && imagesLoaded.length === 0) {
setImagesLoaded(filteredImages.slice(0, Math.min(20, filteredImages.length)))
}
const scrollHandler = () => {
maybeLoadMore()
let _page = Math.floor(imagesLoaded.length / 20)
if (_page !== page) {
setPage(_page)
}
const _viewPort = {
top: (_me.current.scrollTop - _LAZY_LOAD_MARGIN) > 0 ? (_me.current.scrollTop - _LAZY_LOAD_MARGIN) : 0,
bottom: _me.current.scrollTop + _me.current.clientHeight + _LAZY_LOAD_MARGIN
}
setViewPort(_viewPort)
}
const maybeLoadMore = () => {
//check if loadMoreThreshold is visible
const loadMoreThreshold = document.getElementById("loadMoreThreshold")
if (loadMoreThreshold.getBoundingClientRect().top < window.innerHeight) {
//load 20 more images
setImagesLoaded(filteredImages.slice(0, page*20+20))
}
}
return <div className="browser nevysha nevysha-scrollable" onScroll={() => scrollHandler()} ref={_me}>
{imagesLoaded.map((image, index) => {
return (
<CozyImage
key={image.hash}
imageHash={image.hash}
index={index}
viewPort={viewPort}/>
)
})}
<div id="loadMoreThreshold" className="hackyOffPageElement"/>
</div>;
}