Test new <MoreButton /> behavior

This commit is contained in:
Sam Becker 2024-01-15 11:49:20 -06:00
parent 52e84132e9
commit c92ce68dae
3 changed files with 25 additions and 15 deletions

View File

@ -33,13 +33,14 @@ export default async function HomePage() {
<Suspense>
<MoreComponents
label="More photos"
initialOffset={LARGE_PHOTOS_TO_SHOW + 1}
initialOffset={LARGE_PHOTOS_TO_SHOW}
itemsPerRequest={LARGE_PHOTOS_TO_SHOW}
getNextComponent={async (offset, limit) => {
'use server';
console.log('Getting next component', { offset, limit});
// console.log('Getting next component', { offset, limit });
const photos = await getPhotosCached({ limit: offset + limit });
const nextPhotos = photos.slice(-limit);
console.log(`Sending ${nextPhotos.length} photos`);
return {
nextComponent: <PhotosLarge photos={nextPhotos} />,
isFinished: offset + limit >= count,

View File

@ -22,31 +22,41 @@ export default function MoreComponents({
triggerOnView?: boolean
prefetch?: boolean
}) {
const [indexToLoad, setIndexToLoad] = useState(prefetch ? 1 : 0);
const [indexToView, setIndexToView] = useState(0);
const [indexLoaded, setIndexLoaded] = useState(0);
const [isLoading, setIsLoading] = useState(false);
const [lastIndexToLoad, setLastIndexToLoad] = useState<number>();
const [components, setComponents] = useState<JSX.Element[]>([]);
const [isFinished, setIsFinished] = useState(false);
const indexToLoad = lastIndexToLoad
?? (prefetch ? indexToView + 1 : indexToView);
useEffect(() => {
if (!isLoading && indexToLoad > indexLoaded) {
if (
!isLoading &&
// (lastIndexToLoad === undefined || indexToLoad <= lastIndexToLoad) &&
indexToLoad > indexToView &&
indexToLoad > indexLoaded
) {
setIsLoading(true);
getNextComponent(
initialOffset + (indexToLoad - 1) * itemsPerRequest,
initialOffset + indexToLoad * itemsPerRequest,
itemsPerRequest,
)
.then(({ nextComponent, isFinished }) => {
setComponents(current => [...current, nextComponent]);
setIsFinished(isFinished);
setIndexLoaded(i => i + 1);
setIndexLoaded(indexToLoad);
if (isFinished) {
setLastIndexToLoad(indexToLoad);
}
})
.finally(() => setIsLoading(false));
}
}, [
isLoading,
// lastIndexToLoad,
indexToLoad,
indexToView,
indexLoaded,
getNextComponent,
initialOffset,
@ -56,13 +66,10 @@ export default function MoreComponents({
const buttonRef = useRef<HTMLButtonElement>(null);
const advance = useCallback(() => {
if (!isFinished && !isLoading) {
setIndexToLoad(i => i + 1);
}
if (indexToView < indexToLoad) {
if (indexToView < indexLoaded) {
setIndexToView(i => i + 1);
}
}, [isLoading, isFinished, indexToView, indexToLoad]);
}, [indexToView, indexLoaded]);
useEffect(() => {
// Only add observer if button is rendered
@ -82,6 +89,8 @@ export default function MoreComponents({
}
}, [triggerOnView, advance]);
console.log({ indexToLoad, indexToView, indexLoaded, lastIndexToLoad });
return <>
{components.slice(0, indexToView)}
{indexToView < indexLoaded &&

View File

@ -11,7 +11,7 @@ import {
import camelcaseKeys from 'camelcase-keys';
import type { Metadata } from 'next';
export const LARGE_PHOTOS_TO_SHOW = 3;
export const LARGE_PHOTOS_TO_SHOW = 2;
export const GRID_THUMBNAILS_TO_SHOW_MAX = 12;
export const ACCEPTED_PHOTO_FILE_TYPES = [