Remove all share pages/layouts
This commit is contained in:
parent
bc5efad5ca
commit
39035bf188
@ -1,91 +0,0 @@
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { ReactNode, cache } from 'react';
|
||||
import { FilmSimulation } from '@/simulation';
|
||||
import {
|
||||
getPhotosMetaCached,
|
||||
getPhotosNearIdCached,
|
||||
} from '@/photo/cache';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((
|
||||
photoId: string,
|
||||
simulation: FilmSimulation,
|
||||
) =>
|
||||
getPhotosNearIdCached(
|
||||
photoId,
|
||||
{ simulation, limit: RELATED_GRID_PHOTOS_TO_SHOW + 2 },
|
||||
));
|
||||
|
||||
interface PhotoFilmSimulationProps {
|
||||
params: Promise<{ photoId: string, simulation: FilmSimulation }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: PhotoFilmSimulationProps): Promise<Metadata> {
|
||||
const { photoId, simulation } = await params;
|
||||
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId, simulation);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({ photo, simulation });
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoFilmSimulationPage({
|
||||
params,
|
||||
children,
|
||||
}: PhotoFilmSimulationProps & { children: ReactNode }) {
|
||||
const { photoId, simulation } = await params;
|
||||
|
||||
const { photo, photos, photosGrid, indexNumber } =
|
||||
await getPhotosNearIdCachedCached(photoId, simulation);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
const { count, dateRange } = await getPhotosMetaCached({ simulation });
|
||||
|
||||
return <>
|
||||
{children}
|
||||
<PhotoDetailPage {...{
|
||||
photo,
|
||||
photos,
|
||||
photosGrid,
|
||||
simulation,
|
||||
indexNumber,
|
||||
count,
|
||||
dateRange,
|
||||
}} />
|
||||
</>;
|
||||
}
|
||||
@ -1,3 +1,89 @@
|
||||
export default function Page() {
|
||||
return null;
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { FilmSimulation } from '@/simulation';
|
||||
import {
|
||||
getPhotosMetaCached,
|
||||
getPhotosNearIdCached,
|
||||
} from '@/photo/cache';
|
||||
import { cache } from 'react';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((
|
||||
photoId: string,
|
||||
simulation: FilmSimulation,
|
||||
) =>
|
||||
getPhotosNearIdCached(
|
||||
photoId,
|
||||
{ simulation, limit: RELATED_GRID_PHOTOS_TO_SHOW + 2 },
|
||||
));
|
||||
|
||||
interface PhotoFilmSimulationProps {
|
||||
params: Promise<{ photoId: string, simulation: FilmSimulation }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: PhotoFilmSimulationProps): Promise<Metadata> {
|
||||
const { photoId, simulation } = await params;
|
||||
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId, simulation);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({ photo, simulation });
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoFilmSimulationPage({
|
||||
params,
|
||||
}: PhotoFilmSimulationProps) {
|
||||
const { photoId, simulation } = await params;
|
||||
|
||||
const { photo, photos, photosGrid, indexNumber } =
|
||||
await getPhotosNearIdCachedCached(photoId, simulation);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
const { count, dateRange } = await getPhotosMetaCached({ simulation });
|
||||
|
||||
return (
|
||||
<PhotoDetailPage {...{
|
||||
photo,
|
||||
photos,
|
||||
photosGrid,
|
||||
simulation,
|
||||
indexNumber,
|
||||
count,
|
||||
dateRange,
|
||||
}} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
import { getPhotoCached } from '@/photo/cache';
|
||||
import PhotoShareModal from '@/photo/PhotoShareModal';
|
||||
import { FilmSimulation } from '@/simulation';
|
||||
import { PATH_ROOT } from '@/site/paths';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
export default async function Share({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ photoId: string, simulation: FilmSimulation }>
|
||||
}) {
|
||||
const { photoId, simulation } = await params;
|
||||
|
||||
const photo = await getPhotoCached(photoId);
|
||||
|
||||
if (!photo) { return redirect(PATH_ROOT); }
|
||||
|
||||
return <PhotoShareModal {...{ photo, simulation }} />;
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
import { INFINITE_SCROLL_GRID_INITIAL } from '@/photo';
|
||||
import { FilmSimulation, generateMetaForFilmSimulation } from '@/simulation';
|
||||
import FilmSimulationOverview from '@/simulation/FilmSimulationOverview';
|
||||
import FilmSimulationShareModal from '@/simulation/FilmSimulationShareModal';
|
||||
import { getPhotosFilmSimulationDataCached } from '@/simulation/data';
|
||||
import { Metadata } from 'next/types';
|
||||
import { cache } from 'react';
|
||||
|
||||
const getPhotosFilmSimulationDataCachedCached =
|
||||
cache((simulation: FilmSimulation) => getPhotosFilmSimulationDataCached({
|
||||
simulation,
|
||||
limit: INFINITE_SCROLL_GRID_INITIAL,
|
||||
}));
|
||||
|
||||
interface FilmSimulationProps {
|
||||
params: Promise<{ simulation: FilmSimulation }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: FilmSimulationProps): Promise<Metadata> {
|
||||
const { simulation } = await params;
|
||||
|
||||
const [
|
||||
photos,
|
||||
{ count, dateRange },
|
||||
] = await getPhotosFilmSimulationDataCachedCached(simulation);
|
||||
|
||||
const {
|
||||
url,
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
} = generateMetaForFilmSimulation(simulation, photos, count, dateRange);
|
||||
|
||||
return {
|
||||
title,
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
images,
|
||||
description,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
description,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function Share({
|
||||
params,
|
||||
}: FilmSimulationProps) {
|
||||
const { simulation } = await params;
|
||||
|
||||
const [
|
||||
photos,
|
||||
{ count, dateRange },
|
||||
] = await getPhotosFilmSimulationDataCachedCached(simulation);
|
||||
|
||||
return <>
|
||||
<FilmSimulationShareModal {...{ simulation, photos, count, dateRange }} />
|
||||
<FilmSimulationOverview
|
||||
{...{ simulation, photos, count, dateRange }}
|
||||
animateOnFirstLoadOnly
|
||||
/>
|
||||
</>;
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { getPhotosNearIdCached } from '@/photo/cache';
|
||||
import { ReactNode, cache } from 'react';
|
||||
import { getPhotosMeta } from '@/photo/db/query';
|
||||
import { getFocalLengthFromString } from '@/focal';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((photoId: string, focal: number) =>
|
||||
getPhotosNearIdCached(
|
||||
photoId,
|
||||
{ focal, limit: RELATED_GRID_PHOTOS_TO_SHOW + 2 },
|
||||
));
|
||||
|
||||
interface PhotoFocalLengthProps {
|
||||
params: Promise<{ photoId: string, focal: string }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: PhotoFocalLengthProps): Promise<Metadata> {
|
||||
const { photoId, focal: focalString } = await params;
|
||||
|
||||
const focal = getFocalLengthFromString(focalString);
|
||||
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId, focal);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({ photo, focal });
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoFocalLengthPage({
|
||||
params,
|
||||
children,
|
||||
}: PhotoFocalLengthProps & { children: ReactNode }) {
|
||||
const { photoId, focal: focalString } = await params;
|
||||
|
||||
const focal = getFocalLengthFromString(focalString);
|
||||
|
||||
const { photo, photos, photosGrid, indexNumber } =
|
||||
await getPhotosNearIdCachedCached(photoId, focal);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
const { count, dateRange } = await getPhotosMeta({ focal });
|
||||
|
||||
return <>
|
||||
{children}
|
||||
<PhotoDetailPage {...{
|
||||
photo,
|
||||
photos,
|
||||
photosGrid,
|
||||
focal,
|
||||
indexNumber,
|
||||
count,
|
||||
dateRange,
|
||||
}} />
|
||||
</>;
|
||||
}
|
||||
@ -1,3 +1,88 @@
|
||||
export default function Page() {
|
||||
return null;
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { getPhotosNearIdCached } from '@/photo/cache';
|
||||
import { cache } from 'react';
|
||||
import { getPhotosMeta } from '@/photo/db/query';
|
||||
import { getFocalLengthFromString } from '@/focal';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((photoId: string, focal: number) =>
|
||||
getPhotosNearIdCached(
|
||||
photoId,
|
||||
{ focal, limit: RELATED_GRID_PHOTOS_TO_SHOW + 2 },
|
||||
));
|
||||
|
||||
interface PhotoFocalLengthProps {
|
||||
params: Promise<{ photoId: string, focal: string }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: PhotoFocalLengthProps): Promise<Metadata> {
|
||||
const { photoId, focal: focalString } = await params;
|
||||
|
||||
const focal = getFocalLengthFromString(focalString);
|
||||
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId, focal);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({ photo, focal });
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoFocalLengthPage({
|
||||
params,
|
||||
}: PhotoFocalLengthProps) {
|
||||
const { photoId, focal: focalString } = await params;
|
||||
|
||||
const focal = getFocalLengthFromString(focalString);
|
||||
|
||||
const { photo, photos, photosGrid, indexNumber } =
|
||||
await getPhotosNearIdCachedCached(photoId, focal);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
const { count, dateRange } = await getPhotosMeta({ focal });
|
||||
|
||||
return (
|
||||
<PhotoDetailPage {...{
|
||||
photo,
|
||||
photos,
|
||||
photosGrid,
|
||||
focal,
|
||||
indexNumber,
|
||||
count,
|
||||
dateRange,
|
||||
}} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
import { getFocalLengthFromString } from '@/focal';
|
||||
import { getPhotoCached } from '@/photo/cache';
|
||||
import PhotoShareModal from '@/photo/PhotoShareModal';
|
||||
import { PATH_ROOT } from '@/site/paths';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
export default async function Share({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ photoId: string, focal: string }>
|
||||
}) {
|
||||
const { photoId, focal: focalString } = await params;
|
||||
|
||||
const focal = getFocalLengthFromString(focalString);
|
||||
|
||||
const photo = await getPhotoCached(photoId);
|
||||
|
||||
if (!photo) { return redirect(PATH_ROOT); }
|
||||
|
||||
return <PhotoShareModal {...{ photo, focal }} />;
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
import { generateMetaForFocalLength, getFocalLengthFromString } from '@/focal';
|
||||
import FocalLengthOverview from '@/focal/FocalLengthOverview';
|
||||
import FocalLengthShareModal from '@/focal/FocalLengthShareModal';
|
||||
import { getPhotosFocalLengthDataCached } from '@/focal/data';
|
||||
import { INFINITE_SCROLL_GRID_INITIAL } from '@/photo';
|
||||
import type { Metadata } from 'next';
|
||||
import { cache } from 'react';
|
||||
|
||||
const getPhotosFocalLengthDataCachedCached = cache((focal: number) =>
|
||||
getPhotosFocalLengthDataCached({
|
||||
focal,
|
||||
limit: INFINITE_SCROLL_GRID_INITIAL,
|
||||
}));
|
||||
|
||||
interface FocalLengthProps {
|
||||
params: Promise<{ focal: string }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: FocalLengthProps): Promise<Metadata> {
|
||||
const { focal: focalString } = await params;
|
||||
|
||||
const focal = getFocalLengthFromString(focalString);
|
||||
|
||||
const [
|
||||
photos,
|
||||
{ count, dateRange },
|
||||
] = await getPhotosFocalLengthDataCachedCached(focal);
|
||||
|
||||
const {
|
||||
url,
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
} = generateMetaForFocalLength(focal, photos, count, dateRange);
|
||||
|
||||
return {
|
||||
title,
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
images,
|
||||
description,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
description,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function Share({
|
||||
params,
|
||||
}: FocalLengthProps) {
|
||||
const { focal: focalString } = await params;
|
||||
|
||||
const focal = getFocalLengthFromString(focalString);
|
||||
|
||||
const [
|
||||
photos,
|
||||
{ count, dateRange },
|
||||
] = await getPhotosFocalLengthDataCachedCached(focal);
|
||||
|
||||
return <>
|
||||
<FocalLengthShareModal {...{ focal, photos, count, dateRange }} />
|
||||
<FocalLengthOverview
|
||||
{...{ focal, photos, count, dateRange }}
|
||||
animateOnFirstLoadOnly
|
||||
/>
|
||||
</>;
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { getPhotosNearIdCached } from '@/photo/cache';
|
||||
import { IS_PRODUCTION, STATICALLY_OPTIMIZED_PAGES } from '@/site/config';
|
||||
import { getPhotoIds } from '@/photo/db/query';
|
||||
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
||||
import { ReactNode, cache } from 'react';
|
||||
|
||||
export const maxDuration = 60;
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((photoId: string) =>
|
||||
getPhotosNearIdCached(photoId, { limit: RELATED_GRID_PHOTOS_TO_SHOW + 2 }));
|
||||
|
||||
export let generateStaticParams:
|
||||
(() => Promise<{ photoId: string }[]>) | undefined = undefined;
|
||||
|
||||
if (STATICALLY_OPTIMIZED_PAGES && IS_PRODUCTION) {
|
||||
generateStaticParams = async () => {
|
||||
const photos = await getPhotoIds({ limit: GENERATE_STATIC_PARAMS_LIMIT });
|
||||
return photos.map(photoId => ({ photoId }));
|
||||
};
|
||||
}
|
||||
|
||||
interface PhotoProps {
|
||||
params: Promise<{ photoId: string }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}:PhotoProps): Promise<Metadata> {
|
||||
const { photoId } = await params;
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({ photo });
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoPage({
|
||||
params,
|
||||
children,
|
||||
}: PhotoProps & { children: ReactNode }) {
|
||||
const { photoId } = await params;
|
||||
const { photo, photos, photosGrid } =
|
||||
await getPhotosNearIdCachedCached(photoId);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
return <>
|
||||
{children}
|
||||
<PhotoDetailPage {...{ photo, photos, photosGrid }} />
|
||||
</>;
|
||||
}
|
||||
@ -1,3 +1,82 @@
|
||||
export default function Page() {
|
||||
return null;
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { getPhotosNearIdCached } from '@/photo/cache';
|
||||
import { IS_PRODUCTION, STATICALLY_OPTIMIZED_PAGES } from '@/site/config';
|
||||
import { getPhotoIds } from '@/photo/db/query';
|
||||
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
|
||||
import { cache } from 'react';
|
||||
|
||||
export const maxDuration = 60;
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((photoId: string) =>
|
||||
getPhotosNearIdCached(photoId, { limit: RELATED_GRID_PHOTOS_TO_SHOW + 2 }));
|
||||
|
||||
export let generateStaticParams:
|
||||
(() => Promise<{ photoId: string }[]>) | undefined = undefined;
|
||||
|
||||
if (STATICALLY_OPTIMIZED_PAGES && IS_PRODUCTION) {
|
||||
generateStaticParams = async () => {
|
||||
const photos = await getPhotoIds({ limit: GENERATE_STATIC_PARAMS_LIMIT });
|
||||
return photos.map(photoId => ({ photoId }));
|
||||
};
|
||||
}
|
||||
|
||||
interface PhotoProps {
|
||||
params: Promise<{ photoId: string }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}:PhotoProps): Promise<Metadata> {
|
||||
const { photoId } = await params;
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({ photo });
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoPage({
|
||||
params,
|
||||
}: PhotoProps) {
|
||||
const { photoId } = await params;
|
||||
const { photo, photos, photosGrid } =
|
||||
await getPhotosNearIdCachedCached(photoId);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
return (
|
||||
<PhotoDetailPage {...{ photo, photos, photosGrid }} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
import { getPhotoCached } from '@/photo/cache';
|
||||
import PhotoShareModal from '@/photo/PhotoShareModal';
|
||||
import { PATH_ROOT } from '@/site/paths';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
export default async function Share({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ photoId: string }>
|
||||
}) {
|
||||
const { photoId } = await params;
|
||||
|
||||
const photo = await getPhotoCached(photoId);
|
||||
|
||||
if (!photo) { return redirect(PATH_ROOT); }
|
||||
|
||||
return <PhotoShareModal photo={photo} />;
|
||||
}
|
||||
@ -1,99 +0,0 @@
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import {
|
||||
getPhotosMetaCached,
|
||||
getPhotosNearIdCached,
|
||||
} from '@/photo/cache';
|
||||
import {
|
||||
PhotoCameraProps,
|
||||
cameraFromPhoto,
|
||||
getCameraFromParams,
|
||||
} from '@/camera';
|
||||
import { ReactNode, cache } from 'react';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((
|
||||
photoId: string,
|
||||
make: string,
|
||||
model: string,
|
||||
) =>
|
||||
getPhotosNearIdCached(
|
||||
photoId, {
|
||||
camera: getCameraFromParams({ make, model }),
|
||||
limit: RELATED_GRID_PHOTOS_TO_SHOW + 2,
|
||||
},
|
||||
));
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: PhotoCameraProps): Promise<Metadata> {
|
||||
const { photoId, make, model } = await params;
|
||||
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId, make, model);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({
|
||||
photo,
|
||||
camera: cameraFromPhoto(photo, { make, model }),
|
||||
});
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoCameraPage({
|
||||
params,
|
||||
children,
|
||||
}: PhotoCameraProps & { children: ReactNode }) {
|
||||
const { photoId, make, model } = await params;
|
||||
|
||||
const { photo, photos, photosGrid, indexNumber } =
|
||||
await getPhotosNearIdCachedCached(photoId, make, model);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
const camera = cameraFromPhoto(photo, { make, model });
|
||||
|
||||
const { count, dateRange } = await getPhotosMetaCached({ camera });
|
||||
|
||||
return <>
|
||||
{children}
|
||||
<PhotoDetailPage {...{
|
||||
photo,
|
||||
photos,
|
||||
photosGrid,
|
||||
camera,
|
||||
indexNumber,
|
||||
count,
|
||||
dateRange,
|
||||
}} />
|
||||
</>;
|
||||
}
|
||||
@ -1,3 +1,97 @@
|
||||
export default function Page() {
|
||||
return null;
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import {
|
||||
getPhotosMetaCached,
|
||||
getPhotosNearIdCached,
|
||||
} from '@/photo/cache';
|
||||
import {
|
||||
PhotoCameraProps,
|
||||
cameraFromPhoto,
|
||||
getCameraFromParams,
|
||||
} from '@/camera';
|
||||
import { cache } from 'react';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((
|
||||
photoId: string,
|
||||
make: string,
|
||||
model: string,
|
||||
) =>
|
||||
getPhotosNearIdCached(
|
||||
photoId, {
|
||||
camera: getCameraFromParams({ make, model }),
|
||||
limit: RELATED_GRID_PHOTOS_TO_SHOW + 2,
|
||||
},
|
||||
));
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: PhotoCameraProps): Promise<Metadata> {
|
||||
const { photoId, make, model } = await params;
|
||||
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId, make, model);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({
|
||||
photo,
|
||||
camera: cameraFromPhoto(photo, { make, model }),
|
||||
});
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoCameraPage({
|
||||
params,
|
||||
}: PhotoCameraProps) {
|
||||
const { photoId, make, model } = await params;
|
||||
|
||||
const { photo, photos, photosGrid, indexNumber } =
|
||||
await getPhotosNearIdCachedCached(photoId, make, model);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
const camera = cameraFromPhoto(photo, { make, model });
|
||||
|
||||
const { count, dateRange } = await getPhotosMetaCached({ camera });
|
||||
|
||||
return (
|
||||
<PhotoDetailPage {...{
|
||||
photo,
|
||||
photos,
|
||||
photosGrid,
|
||||
camera,
|
||||
indexNumber,
|
||||
count,
|
||||
dateRange,
|
||||
}} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
import { getPhotoCached } from '@/photo/cache';
|
||||
import { PhotoCameraProps, cameraFromPhoto } from '@/camera';
|
||||
import PhotoShareModal from '@/photo/PhotoShareModal';
|
||||
import { PATH_ROOT } from '@/site/paths';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
export default async function Share({
|
||||
params,
|
||||
}: PhotoCameraProps) {
|
||||
const { photoId, make, model } = await params;
|
||||
|
||||
const photo = await getPhotoCached(photoId);
|
||||
|
||||
if (!photo) { return redirect(PATH_ROOT); }
|
||||
|
||||
const camera = cameraFromPhoto(photo, { make, model });
|
||||
|
||||
return <PhotoShareModal {...{ photo, camera }} />;
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
import { CameraProps } from '@/camera';
|
||||
import CameraShareModal from '@/camera/CameraShareModal';
|
||||
import { generateMetaForCamera } from '@/camera/meta';
|
||||
import { Metadata } from 'next/types';
|
||||
import { INFINITE_SCROLL_GRID_INITIAL } from '@/photo';
|
||||
import { getPhotosCameraDataCached } from '@/camera/data';
|
||||
import CameraOverview from '@/camera/CameraOverview';
|
||||
import { cache } from 'react';
|
||||
|
||||
const getPhotosCameraDataCachedCached = cache((
|
||||
make: string,
|
||||
model: string,
|
||||
) => getPhotosCameraDataCached(
|
||||
make,
|
||||
model,
|
||||
INFINITE_SCROLL_GRID_INITIAL,
|
||||
));
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: CameraProps): Promise<Metadata> {
|
||||
const { make, model } = await params;
|
||||
|
||||
const [
|
||||
photos,
|
||||
{ count, dateRange },
|
||||
camera,
|
||||
] = await getPhotosCameraDataCachedCached(make, model);
|
||||
|
||||
const {
|
||||
url,
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
} = generateMetaForCamera(camera, photos, count, dateRange);
|
||||
|
||||
return {
|
||||
title,
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
images,
|
||||
description,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
description,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function Share({ params }: CameraProps) {
|
||||
const { make, model } = await params;
|
||||
|
||||
const [
|
||||
photos,
|
||||
{ count, dateRange },
|
||||
camera,
|
||||
] = await getPhotosCameraDataCachedCached(make, model);
|
||||
|
||||
return <>
|
||||
<CameraShareModal {...{ camera, photos, count, dateRange }} />
|
||||
<CameraOverview
|
||||
{...{ camera, photos, count, dateRange }}
|
||||
animateOnFirstLoadOnly
|
||||
/>
|
||||
</>;
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { getPhotosNearIdCached } from '@/photo/cache';
|
||||
import { ReactNode, cache } from 'react';
|
||||
import { getPhotosMeta } from '@/photo/db/query';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((photoId: string, tag: string) =>
|
||||
getPhotosNearIdCached(
|
||||
photoId,
|
||||
{ tag, limit: RELATED_GRID_PHOTOS_TO_SHOW + 2 },
|
||||
));
|
||||
|
||||
interface PhotoTagProps {
|
||||
params: Promise<{ photoId: string, tag: string }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: PhotoTagProps): Promise<Metadata> {
|
||||
const { photoId, tag } = await params;
|
||||
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId, tag);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({ photo, tag });
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoTagPage({
|
||||
params,
|
||||
children,
|
||||
}: PhotoTagProps & { children: ReactNode }) {
|
||||
const { photoId, tag } = await params;
|
||||
const { photo, photos, photosGrid, indexNumber } =
|
||||
await getPhotosNearIdCachedCached(photoId, tag);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
const { count, dateRange } = await getPhotosMeta({ tag });
|
||||
|
||||
return <>
|
||||
{children}
|
||||
<PhotoDetailPage {...{
|
||||
photo,
|
||||
photos,
|
||||
photosGrid,
|
||||
tag,
|
||||
indexNumber,
|
||||
count,
|
||||
dateRange,
|
||||
}} />
|
||||
</>;
|
||||
}
|
||||
@ -1,3 +1,82 @@
|
||||
export default function Page() {
|
||||
return null;
|
||||
import {
|
||||
RELATED_GRID_PHOTOS_TO_SHOW,
|
||||
descriptionForPhoto,
|
||||
titleForPhoto,
|
||||
} from '@/photo';
|
||||
import { Metadata } from 'next/types';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
PATH_ROOT,
|
||||
absolutePathForPhoto,
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/site/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { getPhotosNearIdCached } from '@/photo/cache';
|
||||
import { cache } from 'react';
|
||||
import { getPhotosMeta } from '@/photo/db/query';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((photoId: string, tag: string) =>
|
||||
getPhotosNearIdCached(
|
||||
photoId,
|
||||
{ tag, limit: RELATED_GRID_PHOTOS_TO_SHOW + 2 },
|
||||
));
|
||||
|
||||
interface PhotoTagProps {
|
||||
params: Promise<{ photoId: string, tag: string }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: PhotoTagProps): Promise<Metadata> {
|
||||
const { photoId, tag } = await params;
|
||||
|
||||
const { photo } = await getPhotosNearIdCachedCached(photoId, tag);
|
||||
|
||||
if (!photo) { return {}; }
|
||||
|
||||
const title = titleForPhoto(photo);
|
||||
const description = descriptionForPhoto(photo);
|
||||
const images = absolutePathForPhotoImage(photo);
|
||||
const url = absolutePathForPhoto({ photo, tag });
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
images,
|
||||
description,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PhotoTagPage({
|
||||
params,
|
||||
}: PhotoTagProps) {
|
||||
const { photoId, tag } = await params;
|
||||
const { photo, photos, photosGrid, indexNumber } =
|
||||
await getPhotosNearIdCachedCached(photoId, tag);
|
||||
|
||||
if (!photo) { redirect(PATH_ROOT); }
|
||||
|
||||
const { count, dateRange } = await getPhotosMeta({ tag });
|
||||
|
||||
return (
|
||||
<PhotoDetailPage {...{
|
||||
photo,
|
||||
photos,
|
||||
photosGrid,
|
||||
tag,
|
||||
indexNumber,
|
||||
count,
|
||||
dateRange,
|
||||
}} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
import { getPhotoCached } from '@/photo/cache';
|
||||
import PhotoShareModal from '@/photo/PhotoShareModal';
|
||||
import { PATH_ROOT } from '@/site/paths';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
export default async function Share({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ photoId: string, tag: string }>
|
||||
}) {
|
||||
const { photoId, tag } = await params;
|
||||
|
||||
const photo = await getPhotoCached(photoId);
|
||||
|
||||
if (!photo) { return redirect(PATH_ROOT); }
|
||||
|
||||
return <PhotoShareModal {...{ photo, tag }} />;
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
import { INFINITE_SCROLL_GRID_INITIAL } from '@/photo';
|
||||
import { generateMetaForTag } from '@/tag';
|
||||
import TagOverview from '@/tag/TagOverview';
|
||||
import TagShareModal from '@/tag/TagShareModal';
|
||||
import { getPhotosTagDataCached } from '@/tag/data';
|
||||
import type { Metadata } from 'next';
|
||||
import { cache } from 'react';
|
||||
|
||||
const getPhotosTagDataCachedCached = cache((tag: string) =>
|
||||
getPhotosTagDataCached({ tag, limit: INFINITE_SCROLL_GRID_INITIAL }));
|
||||
|
||||
interface TagProps {
|
||||
params: Promise<{ tag: string }>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: TagProps): Promise<Metadata> {
|
||||
const { tag: tagFromParams } = await params;
|
||||
|
||||
const tag = decodeURIComponent(tagFromParams);
|
||||
|
||||
const [
|
||||
photos,
|
||||
{ count, dateRange },
|
||||
] = await getPhotosTagDataCachedCached(tag);
|
||||
|
||||
const {
|
||||
url,
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
} = generateMetaForTag(tag, photos, count, dateRange);
|
||||
|
||||
return {
|
||||
title,
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
images,
|
||||
url,
|
||||
},
|
||||
twitter: {
|
||||
images,
|
||||
description,
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
description,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function Share({
|
||||
params,
|
||||
}: TagProps) {
|
||||
const { tag: tagFromParams } = await params;
|
||||
|
||||
const tag = decodeURIComponent(tagFromParams);
|
||||
|
||||
const [
|
||||
photos,
|
||||
{ count, dateRange },
|
||||
] = await getPhotosTagDataCachedCached(tag);
|
||||
|
||||
return <>
|
||||
<TagShareModal {...{ tag, photos, count, dateRange }} />
|
||||
<TagOverview
|
||||
{...{ tag, photos, count, dateRange }}
|
||||
animateOnFirstLoadOnly
|
||||
/>
|
||||
</>;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user