diff --git a/src/app/admin/photos/page.tsx b/src/app/admin/photos/page.tsx
index 2474f3d2..bbdbd868 100644
--- a/src/app/admin/photos/page.tsx
+++ b/src/app/admin/photos/page.tsx
@@ -12,7 +12,7 @@ import {
pathForAdminPhotoEdit,
} from '@/site/paths';
import { titleForPhoto } from '@/photo';
-import MorePhotos from '@/photo/MorePhotos';
+import MoreComponentsClient from '@/components/MoreComponentsClient';
import {
getBlobPhotoUrlsNoStore,
getPhotosCached,
@@ -144,7 +144,10 @@ export default async function AdminPhotosPage({
)}
{showMorePhotos &&
- }
+ }
}
/>
diff --git a/src/app/og/page.tsx b/src/app/og/page.tsx
index a9f9e2b8..d0d38d46 100644
--- a/src/app/og/page.tsx
+++ b/src/app/og/page.tsx
@@ -1,5 +1,5 @@
import { getPhotosCached, getPhotosCountCached } from '@/cache';
-import MorePhotos from '@/photo/MorePhotos';
+import MoreComponentsClient from '@/components/MoreComponentsClient';
import StaggeredOgPhotos from '@/photo/StaggeredOgPhotos';
import {
PaginationParams,
@@ -26,7 +26,10 @@ export default async function GridPage({ searchParams }: PaginationParams) {
{showMorePhotos &&
- }
+ }
);
}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 4f86b556..42e8ce81 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,19 +1,10 @@
-import { getPhotosCached, getPhotosCountCached } from '@/cache';
-import AnimateItems from '@/components/AnimateItems';
-import MorePhotos from '@/photo/MorePhotos';
-import SiteGrid from '@/components/SiteGrid';
+import { getPhotosCached } from '@/cache';
import { generateOgImageMetaForPhotos } from '@/photo';
-import PhotoLarge from '@/photo/PhotoLarge';
import PhotosEmptyState from '@/photo/PhotosEmptyState';
-import {
- PaginationParams,
- getPaginationForSearchParams,
-} from '@/site/pagination';
-import { pathForRoot } from '@/site/paths';
import { Metadata } from 'next';
import { MAX_PHOTOS_TO_SHOW_OG } from '@/photo/image-response';
-
-export const dynamic = 'force-static';
+import MoreComponents from '@/components/MoreComponents';
+import PhotosLarge from '@/photo/PhotosLarge';
export async function generateMetadata(): Promise {
// Make homepage queries resilient to error on first time setup
@@ -22,40 +13,24 @@ export async function generateMetadata(): Promise {
return generateOgImageMetaForPhotos(photos);
}
-export default async function HomePage({ searchParams }: PaginationParams) {
- const { offset, limit } = getPaginationForSearchParams(searchParams, 12);
-
- const [
- photos,
- count,
- ] = await Promise.all([
- // Make homepage queries resilient to error on first time setup
- getPhotosCached({ limit }).catch(() => []),
- getPhotosCountCached().catch(() => 0),
- ]);
-
- const showMorePhotos = count > photos.length;
+export default async function HomePage() {
+ // Make homepage queries resilient to error on first time setup
+ const photos = await getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG })
+ .catch(() => []);
return (
photos.length > 0
- ?
-
- )}
+ ?
+
+
{
+ 'use server';
+ return ;
+ }}
/>
- {showMorePhotos &&
- }
- />}
:
);
diff --git a/src/components/MoreComponents.tsx b/src/components/MoreComponents.tsx
new file mode 100644
index 00000000..534df222
--- /dev/null
+++ b/src/components/MoreComponents.tsx
@@ -0,0 +1,27 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+
+export default function MoreComponents({
+ initialOffset = 1,
+ itemsPerRequest,
+ componentLoader,
+}: {
+ initialOffset?: number
+ itemsPerRequest: number
+ componentLoader: (limit: number) => Promise
+}) {
+ const [offset] = useState(initialOffset);
+ const [components, setComponents] = useState([]);
+
+ useEffect(() => {
+ const getPhotosLargeComponentAsync = async () => {
+ return componentLoader(itemsPerRequest * offset);
+ };
+ getPhotosLargeComponentAsync().then((component) => {
+ setComponents([component]);
+ });
+ }, [componentLoader, itemsPerRequest, offset]);
+
+ return components;
+}
diff --git a/src/photo/MorePhotos.tsx b/src/components/MoreComponentsClient.tsx
similarity index 90%
rename from src/photo/MorePhotos.tsx
rename to src/components/MoreComponentsClient.tsx
index c7902d5d..542ce57c 100644
--- a/src/photo/MorePhotos.tsx
+++ b/src/components/MoreComponentsClient.tsx
@@ -2,14 +2,16 @@
import { useRouter } from 'next/navigation';
import { useCallback, useEffect, useRef, useTransition } from 'react';
-import Spinner from '../components/Spinner';
+import Spinner from './Spinner';
-export default function MorePhotos({
+export default function MoreComponentsClient({
path,
+ label = 'Load more',
triggerOnView = true,
prefetch = true,
}: {
path: string
+ label?: string
triggerOnView?: boolean
prefetch?: boolean
}) {
@@ -59,7 +61,7 @@ export default function MorePhotos({
?
- : 'More photos'}
+ : label}
);
}
diff --git a/src/photo/PhotoGrid.tsx b/src/photo/PhotoGrid.tsx
index fefb0b4e..49c560db 100644
--- a/src/photo/PhotoGrid.tsx
+++ b/src/photo/PhotoGrid.tsx
@@ -3,7 +3,7 @@ import PhotoSmall from './PhotoSmall';
import { clsx } from 'clsx/lite';
import AnimateItems from '@/components/AnimateItems';
import { Camera } from '@/camera';
-import MorePhotos from '@/photo/MorePhotos';
+import MoreComponentsClient from '@/components/MoreComponentsClient';
import { FilmSimulation } from '@/simulation';
import { GRID_ASPECT_RATIO, HIGH_DENSITY_GRID } from '@/site/config';
@@ -79,7 +79,10 @@ export default function PhotoGrid({
).concat(additionalTile ?? [])}
/>
{showMorePath &&
- }
+ }
);
};
diff --git a/src/photo/PhotosLarge.tsx b/src/photo/PhotosLarge.tsx
new file mode 100644
index 00000000..938c2db6
--- /dev/null
+++ b/src/photo/PhotosLarge.tsx
@@ -0,0 +1,25 @@
+import AnimateItems from '@/components/AnimateItems';
+import { Photo } from '.';
+import PhotoLarge from './PhotoLarge';
+
+export default function PhotosLarge({
+ photos,
+}: {
+ photos: Photo[]
+}) {
+ return (
+
+ )}
+ />
+ );
+}