Remove search params from /grid
This commit is contained in:
parent
927b80ab8a
commit
19965a1aea
@ -1,26 +1,24 @@
|
||||
import { getPhotosCached } from '@/cache';
|
||||
import SiteGrid from '@/components/SiteGrid';
|
||||
import { generateOgImageMetaForPhotos } from '@/photo';
|
||||
import {
|
||||
PHOTO_LOAD_MULTIPLE_GRID,
|
||||
generateOgImageMetaForPhotos,
|
||||
} from '@/photo';
|
||||
import PhotoGrid from '@/photo/PhotoGrid';
|
||||
import PhotosEmptyState from '@/photo/PhotosEmptyState';
|
||||
import { MAX_PHOTOS_TO_SHOW_OG } from '@/photo/image-response';
|
||||
import { pathForGrid } from '@/site/paths';
|
||||
import { Metadata } from 'next/types';
|
||||
import {
|
||||
PaginationParams,
|
||||
getPaginationForSearchParams,
|
||||
} from '@/site/pagination';
|
||||
import PhotoGridSidebar from '@/photo/PhotoGridSidebar';
|
||||
import { getPhotoSidebarDataCached } from '@/photo/data';
|
||||
import { MorePhotosGrid } from '@/photo/MorePhotosGrid';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const photos = await getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG });
|
||||
return generateOgImageMetaForPhotos(photos);
|
||||
}
|
||||
|
||||
export default async function GridPage({ searchParams }: PaginationParams) {
|
||||
const { offset, limit } = getPaginationForSearchParams(searchParams);
|
||||
|
||||
export default async function GridPage() {
|
||||
const [
|
||||
photos,
|
||||
photosCount,
|
||||
@ -28,18 +26,23 @@ export default async function GridPage({ searchParams }: PaginationParams) {
|
||||
cameras,
|
||||
simulations,
|
||||
] = await Promise.all([
|
||||
getPhotosCached({ limit }),
|
||||
getPhotosCached({ limit: PHOTO_LOAD_MULTIPLE_GRID }),
|
||||
...getPhotoSidebarDataCached(),
|
||||
]);
|
||||
|
||||
const showMorePath = photosCount > photos.length
|
||||
? pathForGrid(offset + 1)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
photos.length > 0
|
||||
? <SiteGrid
|
||||
contentMain={<PhotoGrid {...{ photos, showMorePath }} />}
|
||||
contentMain={<div className="space-y-0.5 sm:space-y-1">
|
||||
<PhotoGrid {...{ photos }} />
|
||||
<Suspense>
|
||||
<MorePhotosGrid
|
||||
initialOffset={PHOTO_LOAD_MULTIPLE_GRID}
|
||||
itemsPerRequest={PHOTO_LOAD_MULTIPLE_GRID}
|
||||
totalPhotosCount={photosCount}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>}
|
||||
contentSide={<div className="sticky top-4 space-y-4">
|
||||
<PhotoGridSidebar {...{
|
||||
tags,
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
import { getPhotosCached, getPhotosCountCached } from '@/cache';
|
||||
import { LARGE_PHOTOS_TO_SHOW, generateOgImageMetaForPhotos } from '@/photo';
|
||||
import {
|
||||
PHOTO_LOAD_MULTIPLE_ROOT,
|
||||
generateOgImageMetaForPhotos,
|
||||
} from '@/photo';
|
||||
import PhotosEmptyState from '@/photo/PhotosEmptyState';
|
||||
import { Metadata } from 'next/types';
|
||||
import { MAX_PHOTOS_TO_SHOW_OG } from '@/photo/image-response';
|
||||
import PhotosLarge from '@/photo/PhotosLarge';
|
||||
import { Suspense } from 'react';
|
||||
import { MorePhotosLarge } from '@/photo/MorePhotosLarge';
|
||||
import { MorePhotosRoot } from '@/photo/MorePhotosRoot';
|
||||
|
||||
export const revalidate = 3600;
|
||||
|
||||
@ -22,7 +25,7 @@ export default async function HomePage() {
|
||||
count,
|
||||
] = await Promise.all([
|
||||
// Make homepage queries resilient to error on first time setup
|
||||
getPhotosCached({ limit: LARGE_PHOTOS_TO_SHOW }).catch(() => []),
|
||||
getPhotosCached({ limit: PHOTO_LOAD_MULTIPLE_ROOT }).catch(() => []),
|
||||
getPhotosCountCached().catch(() => 0),
|
||||
]);
|
||||
|
||||
@ -31,9 +34,9 @@ export default async function HomePage() {
|
||||
? <div className="space-y-1">
|
||||
<PhotosLarge photos={photos} />
|
||||
<Suspense>
|
||||
<MorePhotosLarge
|
||||
initialOffset={LARGE_PHOTOS_TO_SHOW}
|
||||
itemsPerRequest={LARGE_PHOTOS_TO_SHOW}
|
||||
<MorePhotosRoot
|
||||
initialOffset={PHOTO_LOAD_MULTIPLE_ROOT}
|
||||
itemsPerRequest={PHOTO_LOAD_MULTIPLE_ROOT}
|
||||
totalPhotosCount={count}
|
||||
/>
|
||||
</Suspense>
|
||||
|
||||
42
src/photo/MorePhotosGrid.tsx
Normal file
42
src/photo/MorePhotosGrid.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import MoreComponents from '@/components/MoreComponents';
|
||||
import { getPhotosCached } from '@/cache';
|
||||
import PhotoGrid from './PhotoGrid';
|
||||
|
||||
export function MorePhotosGrid({
|
||||
initialOffset,
|
||||
itemsPerRequest,
|
||||
totalPhotosCount,
|
||||
}: {
|
||||
initialOffset: number
|
||||
itemsPerRequest: number
|
||||
totalPhotosCount: number
|
||||
}) {
|
||||
return (
|
||||
<MoreComponents
|
||||
stateKey="PhotosGrid"
|
||||
label="More photos"
|
||||
initialOffset={initialOffset}
|
||||
itemsPerRequest={itemsPerRequest}
|
||||
getNextComponent={async (offset, limit) => {
|
||||
'use server';
|
||||
if (
|
||||
process.env.NODE_ENV === 'development' &&
|
||||
Math.random() < 0.95
|
||||
) {
|
||||
return { didFail: true };
|
||||
}
|
||||
const photos = await getPhotosCached({ limit: offset + limit })
|
||||
.catch(() => undefined);
|
||||
if (!photos) {
|
||||
return { didFail: true };
|
||||
} else {
|
||||
const nextPhotos = photos.slice(offset);
|
||||
return {
|
||||
nextComponent: <PhotoGrid photos={nextPhotos} />,
|
||||
isFinished: offset + limit >= totalPhotosCount,
|
||||
};
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -2,7 +2,7 @@ import MoreComponents from '@/components/MoreComponents';
|
||||
import PhotosLarge from './PhotosLarge';
|
||||
import { getPhotosCached } from '@/cache';
|
||||
|
||||
export function MorePhotosLarge({
|
||||
export function MorePhotosRoot({
|
||||
initialOffset,
|
||||
itemsPerRequest,
|
||||
totalPhotosCount,
|
||||
@ -13,7 +13,7 @@ export function MorePhotosLarge({
|
||||
}) {
|
||||
return (
|
||||
<MoreComponents
|
||||
stateKey="PhotosLarge"
|
||||
stateKey="PhotosRoot"
|
||||
label="More photos"
|
||||
initialOffset={initialOffset}
|
||||
itemsPerRequest={itemsPerRequest}
|
||||
@ -3,7 +3,6 @@ import PhotoSmall from './PhotoSmall';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import AnimateItems from '@/components/AnimateItems';
|
||||
import { Camera } from '@/camera';
|
||||
import MoreComponentsClient from '@/components/MoreComponentsClient';
|
||||
import { FilmSimulation } from '@/simulation';
|
||||
import { GRID_ASPECT_RATIO, HIGH_DENSITY_GRID } from '@/site/config';
|
||||
|
||||
@ -17,7 +16,6 @@ export default function PhotoGrid({
|
||||
animate = true,
|
||||
animateOnFirstLoadOnly,
|
||||
staggerOnFirstLoadOnly = true,
|
||||
showMorePath,
|
||||
additionalTile,
|
||||
small,
|
||||
}: {
|
||||
@ -35,54 +33,47 @@ export default function PhotoGrid({
|
||||
small?: boolean
|
||||
}) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<AnimateItems
|
||||
className={clsx(
|
||||
'grid gap-0.5 sm:gap-1',
|
||||
small
|
||||
? 'grid-cols-3 xs:grid-cols-6'
|
||||
: HIGH_DENSITY_GRID
|
||||
? 'grid-cols-2 xs:grid-cols-4 lg:grid-cols-5'
|
||||
: 'grid-cols-2 sm:grid-cols-4 md:grid-cols-3 lg:grid-cols-4',
|
||||
'items-center',
|
||||
)}
|
||||
type={animate === false ? 'none' : undefined}
|
||||
duration={fast ? 0.3 : undefined}
|
||||
staggerDelay={0.075}
|
||||
distanceOffset={40}
|
||||
animateOnFirstLoadOnly={animateOnFirstLoadOnly}
|
||||
staggerOnFirstLoadOnly={staggerOnFirstLoadOnly}
|
||||
items={photos.map(photo =>
|
||||
<div
|
||||
key={photo.id}
|
||||
className={GRID_ASPECT_RATIO !== 0
|
||||
? clsx(
|
||||
'aspect-square',
|
||||
'overflow-hidden',
|
||||
'[&>*]:flex [&>*]:w-full [&>*]:h-full',
|
||||
'[&>*>*]:object-cover [&>*>*]:min-h-full',
|
||||
)
|
||||
: undefined}
|
||||
style={{
|
||||
...GRID_ASPECT_RATIO !== 0 && {
|
||||
aspectRatio: GRID_ASPECT_RATIO,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<PhotoSmall {...{
|
||||
photo,
|
||||
tag,
|
||||
camera,
|
||||
simulation,
|
||||
selected: photo.id === selectedPhoto?.id,
|
||||
}} />
|
||||
</div>).concat(additionalTile ?? [])}
|
||||
/>
|
||||
{showMorePath &&
|
||||
<MoreComponentsClient
|
||||
label="More photos"
|
||||
path={showMorePath}
|
||||
/>}
|
||||
</div>
|
||||
<AnimateItems
|
||||
className={clsx(
|
||||
'grid gap-0.5 sm:gap-1',
|
||||
small
|
||||
? 'grid-cols-3 xs:grid-cols-6'
|
||||
: HIGH_DENSITY_GRID
|
||||
? 'grid-cols-2 xs:grid-cols-4 lg:grid-cols-5'
|
||||
: 'grid-cols-2 sm:grid-cols-4 md:grid-cols-3 lg:grid-cols-4',
|
||||
'items-center',
|
||||
)}
|
||||
type={animate === false ? 'none' : undefined}
|
||||
duration={fast ? 0.3 : undefined}
|
||||
staggerDelay={0.075}
|
||||
distanceOffset={40}
|
||||
animateOnFirstLoadOnly={animateOnFirstLoadOnly}
|
||||
staggerOnFirstLoadOnly={staggerOnFirstLoadOnly}
|
||||
items={photos.map(photo =>
|
||||
<div
|
||||
key={photo.id}
|
||||
className={GRID_ASPECT_RATIO !== 0
|
||||
? clsx(
|
||||
'aspect-square',
|
||||
'overflow-hidden',
|
||||
'[&>*]:flex [&>*]:w-full [&>*]:h-full',
|
||||
'[&>*>*]:object-cover [&>*>*]:min-h-full',
|
||||
)
|
||||
: undefined}
|
||||
style={{
|
||||
...GRID_ASPECT_RATIO !== 0 && {
|
||||
aspectRatio: GRID_ASPECT_RATIO,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<PhotoSmall {...{
|
||||
photo,
|
||||
tag,
|
||||
camera,
|
||||
simulation,
|
||||
selected: photo.id === selectedPhoto?.id,
|
||||
}} />
|
||||
</div>).concat(additionalTile ?? [])}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@ -11,8 +11,11 @@ import {
|
||||
import camelcaseKeys from 'camelcase-keys';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export const LARGE_PHOTOS_TO_SHOW =
|
||||
export const PHOTO_LOAD_MULTIPLE_ROOT =
|
||||
process.env.NODE_ENV === 'development' ? 2 : 12;
|
||||
export const PHOTO_LOAD_MULTIPLE_GRID =
|
||||
process.env.NODE_ENV === 'development' ? 4 : 24;
|
||||
|
||||
export const GRID_THUMBNAILS_TO_SHOW_MAX = 12;
|
||||
|
||||
export const ACCEPTED_PHOTO_FILE_TYPES = [
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
export type MoreComponentsKey =
|
||||
'PhotosLarge';
|
||||
'PhotosRoot' |
|
||||
'PhotosGrid';
|
||||
|
||||
export interface MoreComponentsStateForKey {
|
||||
indexToView: number
|
||||
@ -39,7 +40,8 @@ export interface MoreComponentsContext {
|
||||
}
|
||||
|
||||
export const MORE_COMPONENTS_INITIAL_STATE: MoreComponentsState = {
|
||||
PhotosLarge: createInitialStateForKey(),
|
||||
PhotosRoot: createInitialStateForKey(),
|
||||
PhotosGrid: createInitialStateForKey(),
|
||||
};
|
||||
|
||||
export const MoreComponentsContext =
|
||||
|
||||
Loading…
Reference in New Issue
Block a user