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() {
|
import {
|
||||||
return null;
|
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() {
|
import {
|
||||||
return null;
|
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() {
|
import {
|
||||||
return null;
|
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() {
|
import {
|
||||||
return null;
|
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() {
|
import {
|
||||||
return null;
|
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