Add core focal length views

This commit is contained in:
Sam Becker 2024-05-21 12:03:32 -05:00
parent 393ec17f84
commit 7cd5ccbe15
33 changed files with 401 additions and 77 deletions

View File

@ -25,7 +25,7 @@ export default function AdminPhotoMenuClient({
const isFav = isPhotoFav(photo);
const path = usePathname();
const shouldRedirectFav = isPathFavs(path) && isFav;
const shouldRedirectDelete = pathForPhoto(photo.id) === path;
const shouldRedirectDelete = pathForPhoto({ photo: photo.id }) === path;
return (
isUserSignedIn

View File

@ -45,7 +45,7 @@ export default function AdminPhotosTable({
<div className="flex flex-col lg:flex-row">
<Link
key={photo.id}
href={pathForPhoto(photo)}
href={pathForPhoto({ photo })}
className="lg:w-[50%] flex items-center gap-2"
prefetch={false}
>

View File

@ -41,7 +41,7 @@ export async function generateMetadata({
const title = titleForPhoto(photo);
const description = descriptionForPhoto(photo);
const images = absolutePathForPhotoImage(photo);
const url = absolutePathForPhoto(photo, simulation);
const url = absolutePathForPhoto({ photo, simulation });
return {
title,

View File

@ -0,0 +1,41 @@
import { getPhotosCached } from '@/photo/cache';
import {
IMAGE_OG_DIMENSION_SMALL,
MAX_PHOTOS_TO_SHOW_PER_TAG,
} from '@/image-response';
import { getIBMPlexMonoMedium } from '@/site/font';
import { ImageResponse } from 'next/og';
import { getImageResponseCacheControlHeaders } from '@/image-response/cache';
import FocalLengthImageResponse from
'@/image-response/FocalLengthImageResponse';
import { getFocalLengthFromString } from '@/focal';
export async function GET(
_: Request,
context: { params: { focal: string } },
) {
const focal = getFocalLengthFromString(context.params.focal);
const [
photos,
{ fontFamily, fonts },
headers,
] = await Promise.all([
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_PER_TAG, focal }),
getIBMPlexMonoMedium(),
getImageResponseCacheControlHeaders(),
]);
const { width, height } = IMAGE_OG_DIMENSION_SMALL;
return new ImageResponse(
<FocalLengthImageResponse {...{
focal,
photos,
width,
height,
fontFamily,
}}/>,
{ width, height, fonts, headers },
);
}

View File

@ -0,0 +1,71 @@
import { generateMetaForFocalLength, getFocalLengthFromString } from '@/focal';
import FocalLengthOverview from '@/focal/FocalLengthOverview';
import { getPhotosFocalDataCached } from '@/focal/data';
import { INFINITE_SCROLL_GRID_PHOTO_INITIAL } from '@/photo';
import { PATH_ROOT } from '@/site/paths';
import type { Metadata } from 'next';
import { redirect } from 'next/navigation';
import { cache } from 'react';
const getPhotosFocalDataCachedCached = cache((focal: number) =>
getPhotosFocalDataCached({
focal,
limit: INFINITE_SCROLL_GRID_PHOTO_INITIAL,
}));
interface FocalLengthProps {
params: { focal: string }
}
export async function generateMetadata({
params: { focal: focalString },
}: FocalLengthProps): Promise<Metadata> {
const focal = getFocalLengthFromString(focalString);
const [
photos,
{ count, dateRange },
] = await getPhotosFocalDataCachedCached(focal);
if (photos.length === 0) { return {}; }
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 TagPage({
params: { focal: focalString },
}:FocalLengthProps) {
const focal = getFocalLengthFromString(focalString);
const [
photos,
{ count, dateRange },
] = await getPhotosFocalDataCachedCached(focal);
if (photos.length === 0) { redirect(PATH_ROOT); }
return (
<FocalLengthOverview {...{ focal, photos, count, dateRange }} />
);
}

View File

@ -44,7 +44,7 @@ export async function generateMetadata({
const title = titleForPhoto(photo);
const description = descriptionForPhoto(photo);
const images = absolutePathForPhotoImage(photo);
const url = absolutePathForPhoto(photo);
const url = absolutePathForPhoto({ photo });
return {
title,

View File

@ -44,11 +44,10 @@ export async function generateMetadata({
const title = titleForPhoto(photo);
const description = descriptionForPhoto(photo);
const images = absolutePathForPhotoImage(photo);
const url = absolutePathForPhoto(
const url = absolutePathForPhoto({
photo,
undefined,
cameraFromPhoto(photo, { make, model }),
);
camera: cameraFromPhoto(photo, { make, model }),
});
return {
title,

View File

@ -35,7 +35,7 @@ export async function generateMetadata({
const title = titleForPhoto(photo);
const description = descriptionForPhoto(photo);
const images = absolutePathForPhotoImage(photo);
const url = absolutePathForPhoto(photo, tag);
const url = absolutePathForPhoto({ photo, tag });
return {
title,

View File

@ -33,7 +33,7 @@ export async function generateMetadata({
const title = titleForPhoto(photo);
const description = descriptionForPhoto(photo);
const url = absolutePathForPhoto(photo, TAG_HIDDEN);
const url = absolutePathForPhoto({ photo, tag: TAG_HIDDEN });
return {
title,

View File

@ -147,7 +147,7 @@ export default function CommandKClient({
keywords: getKeywordsForPhoto(photo),
annotation: <PhotoDate {...{ photo }} />,
accessory: <PhotoSmall photo={photo} />,
path: pathForPhoto(photo),
path: pathForPhoto({ photo }),
})),
}]
: []);

View File

@ -0,0 +1,39 @@
import { Photo, PhotoDateRange } from '@/photo';
import { descriptionForFocalLengthPhotos } from '.';
import { pathForFocalLength } from '@/site/paths';
import PhotoSetHeader from '@/photo/PhotoSetHeader';
import PhotoFocalLength from './PhotoFocalLength';
export default function FocalLengthHeader({
focal,
photos,
selectedPhoto,
indexNumber,
count,
dateRange,
}: {
focal: number
photos: Photo[]
selectedPhoto?: Photo
indexNumber?: number
count?: number
dateRange?: PhotoDateRange
}) {
return (
<PhotoSetHeader
entity={<PhotoFocalLength focal={focal} contrast="high" />}
entityVerb="Tagged"
entityDescription={descriptionForFocalLengthPhotos(
photos,
undefined,
count,
)}
photos={photos}
selectedPhoto={selectedPhoto}
sharePath={pathForFocalLength(focal)}
indexNumber={indexNumber}
count={count}
dateRange={dateRange}
/>
);
}

View File

@ -0,0 +1,33 @@
import { Photo, PhotoDateRange } from '@/photo';
import PhotoGridPage from '@/photo/PhotoGridPage';
import FocalLengthHeader from './FocalLengthHeader';
export default function FocalLengthOverview({
focal,
photos,
count,
dateRange,
animateOnFirstLoadOnly,
}: {
focal: number,
photos: Photo[],
count: number,
dateRange?: PhotoDateRange,
animateOnFirstLoadOnly?: boolean,
}) {
return (
<PhotoGridPage {...{
cacheKey: `focal-${focal}`,
photos,
count,
focal,
header: <FocalLengthHeader {...{
focal,
photos,
count,
dateRange,
}} />,
animateOnFirstLoadOnly,
}} />
);
}

View File

@ -0,0 +1,31 @@
import { pathForFocalLength } from '@/site/paths';
import EntityLink, {
EntityLinkExternalProps,
} from '@/components/primitives/EntityLink';
import { TbCone } from 'react-icons/tb';
import { formatFocalLength } from '.';
export default function PhotoFocalLength({
focal,
type,
badged,
contrast,
prefetch,
countOnHover,
}: {
focal: number
countOnHover?: number
} & EntityLinkExternalProps) {
return (
<EntityLink
label={formatFocalLength(focal)}
href={pathForFocalLength(focal)}
icon={<TbCone className="rotate-[270deg]" />}
type={type}
badged={badged}
contrast={contrast}
prefetch={prefetch}
hoverEntity={countOnHover}
/>
);
}

17
src/focal/data.ts Normal file
View File

@ -0,0 +1,17 @@
import {
getPhotosCached,
getPhotosMetaCached,
} from '@/photo/cache';
export const getPhotosFocalDataCached = ({
focal,
limit,
}: {
focal: number,
limit?: number,
}) =>
Promise.all([
getPhotosCached({ focal, limit }),
getPhotosMetaCached({ focal }),
]);

View File

@ -9,12 +9,21 @@ import {
absolutePathForFocalLengthImage,
} from '@/site/paths';
export const getFocalLengthFromString = (focalString?: string) => {
const focal = focalString?.match(/^([0-9]+)mm/)?.[1];
return focal ? parseInt(focal, 10) : 0;
};
export const formatFocalLength = (focal?: number) => focal ?
`${focal}mm`
: undefined;
export const titleForFocalLength = (
focal: number,
photos: Photo[],
explicitCount?: number,
) => [
`${focal}mm`,
formatFocalLength(focal),
photoQuantityText(explicitCount ?? photos.length),
].join(' ');

View File

@ -0,0 +1,46 @@
import type { Photo } from '../photo';
import ImageCaption from './components/ImageCaption';
import ImagePhotoGrid from './components/ImagePhotoGrid';
import ImageContainer from './components/ImageContainer';
import type { NextImageSize } from '@/services/next-image';
import { TbCone } from 'react-icons/tb';
import { formatFocalLength } from '@/focal';
export default function FocalLengthImageResponse({
focal,
photos,
width,
height,
fontFamily,
}: {
focal: number,
photos: Photo[]
width: NextImageSize
height: number
fontFamily: string
}) {
return (
<ImageContainer {...{
width,
height,
...photos.length === 0 && { background: 'black' },
}}>
<ImagePhotoGrid
{...{
photos,
width,
height,
}}
/>
<ImageCaption {...{ width, height, fontFamily }}>
<TbCone
size={height * .08}
style={{
transform: `translateY(${height * .01}px) rotate(270deg)`,
}}
/>
<span>{formatFocalLength(focal)}</span>
</ImageCaption>
</ImageContainer>
);
}

View File

@ -12,6 +12,7 @@ export default function PhotoGrid({
tag,
camera,
simulation,
focal,
photoPriority,
fast,
animate = true,
@ -28,6 +29,7 @@ export default function PhotoGrid({
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
photoPriority?: boolean
fast?: boolean
animate?: boolean
@ -77,6 +79,7 @@ export default function PhotoGrid({
tag,
camera,
simulation,
focal,
selected: photo.id === selectedPhoto?.id,
priority: photoPriority,
onVisible: index === photos.length - 1

View File

@ -13,6 +13,7 @@ export default function PhotoGridInfinite({
tag,
camera,
simulation,
focal,
animateOnFirstLoadOnly,
}: {
cacheKey: string
@ -21,6 +22,7 @@ export default function PhotoGridInfinite({
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
animateOnFirstLoadOnly?: boolean
}) {
return (
@ -39,6 +41,7 @@ export default function PhotoGridInfinite({
tag,
camera,
simulation,
focal,
onLastPhotoVisible,
animateOnFirstLoadOnly,
}} />}

View File

@ -17,6 +17,7 @@ export default function PhotoGridPage({
tag,
camera,
simulation,
focal,
animateOnFirstLoadOnly,
header,
sidebar,
@ -27,6 +28,7 @@ export default function PhotoGridPage({
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
animateOnFirstLoadOnly?: boolean
header?: JSX.Element
sidebar?: JSX.Element
@ -58,6 +60,7 @@ export default function PhotoGridPage({
tag,
camera,
simulation,
focal,
animateOnFirstLoadOnly,
onAnimationComplete,
}} />
@ -69,6 +72,7 @@ export default function PhotoGridPage({
tag,
camera,
simulation,
focal,
animateOnFirstLoadOnly,
}} />}
</div>

View File

@ -40,6 +40,7 @@ export default function PhotoLarge({
shouldShareTag,
shouldShareCamera,
shouldShareSimulation,
shouldShareFocalLength,
shouldScrollOnShare,
onVisible,
}: {
@ -54,6 +55,7 @@ export default function PhotoLarge({
shouldShareTag?: boolean
shouldShareCamera?: boolean
shouldShareSimulation?: boolean
shouldShareFocalLength?: boolean
shouldScrollOnShare?: boolean
onVisible?: () => void
}) {
@ -76,7 +78,7 @@ export default function PhotoLarge({
containerRef={ref}
contentMain={
<Link
href={pathForPhoto(photo)}
href={pathForPhoto({ photo })}
className={clsx(arePhotosMatted &&
'flex items-center aspect-[3/2] bg-gray-100',
)}
@ -189,12 +191,14 @@ export default function PhotoLarge({
'md:translate-x-[-2.5px]',
'translate-y-[1.5px] md:translate-y-0',
)}
path={pathForPhotoShare(
path={pathForPhotoShare({
photo,
shouldShareTag ? primaryTag : undefined,
shouldShareCamera ? camera : undefined,
shouldShareSimulation ? photo.filmSimulation : undefined,
)}
tag: shouldShareTag ? primaryTag : undefined,
camera: shouldShareCamera ? camera : undefined,
// eslint-disable-next-line max-len
simulation: shouldShareSimulation ? photo.filmSimulation : undefined,
focal: shouldShareFocalLength ? photo.focalLength : undefined,
})}
prefetch={prefetchRelatedLinks}
shouldScroll={shouldScrollOnShare}
/>

View File

@ -15,6 +15,7 @@ export default function PhotoLink({
tag,
camera,
simulation,
focal,
scroll,
prefetch,
nextPhotoAnimation,
@ -25,6 +26,7 @@ export default function PhotoLink({
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
scroll?: boolean
prefetch?: boolean
nextPhotoAnimation?: AnimationConfig
@ -36,7 +38,7 @@ export default function PhotoLink({
return (
photo
? <Link
href={pathForPhoto(photo, tag, camera, simulation)}
href={pathForPhoto({ photo, tag, camera, simulation, focal })}
prefetch={prefetch}
onClick={() => {
if (nextPhotoAnimation) {

View File

@ -21,12 +21,14 @@ export default function PhotoLinks({
tag,
camera,
simulation,
focal,
}: {
photo: Photo
photos: Photo[]
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
}) {
const router = useRouter();
@ -47,7 +49,13 @@ export default function PhotoLinks({
if (previousPhoto) {
setNextPhotoAnimation?.(ANIMATION_RIGHT);
router.push(
pathForPhoto(previousPhoto, tag, camera, simulation),
pathForPhoto({
photo: previousPhoto,
tag,
camera,
simulation,
focal,
}),
{ scroll: false },
);
}
@ -57,7 +65,13 @@ export default function PhotoLinks({
if (nextPhoto) {
setNextPhotoAnimation?.(ANIMATION_LEFT);
router.push(
pathForPhoto(nextPhoto, tag, camera, simulation),
pathForPhoto({
photo: nextPhoto,
tag,
camera,
simulation,
focal,
}),
{ scroll: false },
);
}
@ -76,6 +90,7 @@ export default function PhotoLinks({
tag,
camera,
simulation,
focal,
]);
return (

View File

@ -16,6 +16,7 @@ export default function PhotoMedium({
tag,
camera,
simulation,
focal,
selected,
priority,
prefetch = SHOULD_PREFETCH_ALL_LINKS,
@ -26,6 +27,7 @@ export default function PhotoMedium({
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
selected?: boolean
priority?: boolean
prefetch?: boolean
@ -39,7 +41,7 @@ export default function PhotoMedium({
return (
<Link
ref={ref}
href={pathForPhoto(photo, tag, camera, simulation)}
href={pathForPhoto({ photo, tag, camera, simulation, focal })}
className={clsx(
'active:brightness-75',
selected && 'brightness-50',

View File

@ -29,7 +29,7 @@ export default function PhotoOGTile({
<OGTile {...{
title: titleForPhoto(photo),
description: descriptionForPhoto(photo),
path: pathForPhoto(photo),
path: pathForPhoto({ photo }),
pathImageAbsolute: absolutePathForPhotoImage(photo),
loadingState: loadingStateExternal,
onLoad,

View File

@ -5,24 +5,20 @@ import ShareModal from '@/components/ShareModal';
import { Camera } from '@/camera';
import { FilmSimulation } from '@/simulation';
export default function PhotoShareModal({
photo,
tag,
camera,
simulation,
}: {
export default function PhotoShareModal(props: {
photo: Photo
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
}) {
return (
<ShareModal
title="Share Photo"
pathShare={absolutePathForPhoto(photo, tag, camera, simulation)}
pathClose={pathForPhoto(photo, tag, camera, simulation)}
pathShare={absolutePathForPhoto(props)}
pathClose={pathForPhoto(props)}
>
<PhotoOGTile photo={photo} />
<PhotoOGTile photo={props.photo} />
</ShareModal>
);
};

View File

@ -6,10 +6,15 @@ import { pathForPhoto } from '@/site/paths';
import { SHOULD_PREFETCH_ALL_LINKS } from '@/site/config';
import { useRef } from 'react';
import useOnVisible from '@/utility/useOnVisible';
import { Camera } from '@/camera';
import { FilmSimulation } from '@/simulation';
export default function PhotoSmall({
photo,
tag,
camera,
simulation,
focal,
selected,
className,
prefetch = SHOULD_PREFETCH_ALL_LINKS,
@ -17,6 +22,9 @@ export default function PhotoSmall({
}: {
photo: Photo
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
selected?: boolean
className?: string
prefetch?: boolean
@ -29,7 +37,7 @@ export default function PhotoSmall({
return (
<Link
ref={ref}
href={pathForPhoto(photo, tag)}
href={pathForPhoto({ photo, tag, camera, simulation, focal })}
className={clsx(
className,
'active:brightness-75',

View File

@ -92,7 +92,7 @@ export const toggleFavoritePhotoAction = async (
await updatePhoto(convertPhotoToPhotoDbInsert(photo));
revalidateAllKeysAndPaths();
if (shouldRedirect) {
redirect(pathForPhoto(photoId));
redirect(pathForPhoto({ photo: photoId }));
}
}
});

View File

@ -113,7 +113,7 @@ export const revalidatePhoto = (photoId: string) => {
revalidateCamerasKey();
revalidateFilmSimulationsKey();
// Paths
revalidatePath(pathForPhoto(photoId), 'layout');
revalidatePath(pathForPhoto({ photo: photoId }), 'layout');
revalidatePath(PATH_ROOT, 'layout');
revalidatePath(PATH_GRID, 'layout');
revalidatePath(PREFIX_TAG, 'layout');

View File

@ -7,16 +7,17 @@ export const GENERATE_STATIC_PARAMS_LIMIT = 1000;
export const PHOTO_DEFAULT_LIMIT = 100;
export type GetPhotosOptions = {
sortBy?: 'createdAt' | 'takenAt' | 'priority';
limit?: number;
offset?: number;
query?: string;
tag?: string;
camera?: Camera;
simulation?: FilmSimulation;
takenBefore?: Date;
takenAfterInclusive?: Date;
hidden?: 'exclude' | 'include' | 'only';
sortBy?: 'createdAt' | 'takenAt' | 'priority'
limit?: number
offset?: number
query?: string
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
takenBefore?: Date
takenAfterInclusive?: Date
hidden?: 'exclude' | 'include' | 'only'
};
export const getWheresFromOptions = (
@ -31,6 +32,7 @@ export const getWheresFromOptions = (
tag,
camera,
simulation,
focal,
} = options;
const wheres = [] as string[];
@ -73,6 +75,10 @@ export const getWheresFromOptions = (
wheres.push(`film_simulation=$${valuesIndex++}`);
wheresValues.push(simulation);
}
if (focal) {
wheres.push(`focal_length=$${valuesIndex++}`);
wheresValues.push(focal);
}
return {
wheres: wheres.length > 0

View File

@ -1,3 +1,4 @@
import { formatFocalLength } from '@/focal';
import { getNextImageUrlForRequest } from '@/services/next-image';
import { FilmSimulation } from '@/simulation';
import { HIGH_DENSITY_GRID, SHOW_EXIF_DATA } from '@/site/config';
@ -8,7 +9,6 @@ import {
formatIso,
formatExposureCompensation,
formatExposureTime,
formatFocalLength,
} from '@/utility/exif';
import camelcaseKeys from 'camelcase-keys';
import { isBefore } from 'date-fns';

View File

@ -30,7 +30,7 @@ interface PublicApiPhoto {
export const formatPhotoForApi = (photo: Photo): PublicApiPhoto => ({
id: photo.id,
title: photo.title,
url: absolutePathForPhoto(photo),
url: absolutePathForPhoto({ photo }),
...photo.make && { make: photo.make },
...photo.model && { model: photo.model },
...photo.tags.length > 0 && { tags: photo.tags },

View File

@ -63,6 +63,14 @@ export const PATHS_TO_CACHE = [
...PATHS_ADMIN,
];
interface PhotoPathParams {
photo: PhotoOrPhotoId
tag?: string
camera?: Camera
simulation?: FilmSimulation
focal?: number
}
// Absolute paths
export const ABSOLUTE_PATH_FOR_HOME_IMAGE = `${BASE_URL}/home-image`;
@ -80,13 +88,13 @@ type PhotoOrPhotoId = Photo | string;
const getPhotoId = (photoOrPhotoId: PhotoOrPhotoId) =>
typeof photoOrPhotoId === 'string' ? photoOrPhotoId : photoOrPhotoId.id;
export const pathForPhoto = (
photo: PhotoOrPhotoId,
tag?: string,
camera?: Camera,
simulation?: FilmSimulation,
focal?: number,
) =>
export const pathForPhoto = ({
photo,
tag,
camera,
simulation,
focal,
}: PhotoPathParams) =>
typeof photo !== 'string' && photo.hidden
? `${pathForTag(TAG_HIDDEN)}/${getPhotoId(photo)}`
: tag
@ -99,13 +107,8 @@ export const pathForPhoto = (
? `${pathForFocalLength(focal)}/${getPhotoId(photo)}`
: `${PREFIX_PHOTO}/${getPhotoId(photo)}`;
export const pathForPhotoShare = (
photo: PhotoOrPhotoId,
tag?: string,
camera?: Camera,
simulation?: FilmSimulation,
) =>
`${pathForPhoto(photo, tag, camera, simulation)}/${SHARE}`;
export const pathForPhotoShare = (params: PhotoPathParams) =>
`${pathForPhoto(params)}/${SHARE}`;
export const pathForTag = (tag: string) =>
`${PREFIX_TAG}/${tag}`;
@ -128,13 +131,8 @@ export const pathForFocalLength = (focal: number) =>
export const pathForFilmSimulationShare = (simulation: FilmSimulation) =>
`${pathForFilmSimulation(simulation)}/${SHARE}`;
export const absolutePathForPhoto = (
photo: PhotoOrPhotoId,
tag?: string,
camera?: Camera,
simulation?: FilmSimulation
) =>
`${BASE_URL}${pathForPhoto(photo, tag, camera, simulation)}`;
export const absolutePathForPhoto = (params: PhotoPathParams) =>
`${BASE_URL}${pathForPhoto(params)}`;
export const absolutePathForTag = (tag: string) =>
`${BASE_URL}${pathForTag(tag)}`;
@ -149,7 +147,7 @@ export const absolutePathForFocalLength = (focal: number) =>
`${BASE_URL}${pathForFocalLength(focal)}`;
export const absolutePathForPhotoImage = (photo: PhotoOrPhotoId) =>
`${absolutePathForPhoto(photo)}/image`;
`${absolutePathForPhoto({ photo })}/image`;
export const absolutePathForTagImage = (tag: string) =>
`${absolutePathForTag(tag)}/image`;
@ -329,15 +327,15 @@ export const getEscapePath = (pathname?: string) => {
) {
return PATH_GRID;
} else if (photoId && isPathTagPhotoShare(pathname)) {
return pathForPhoto(photoId, tag);
return pathForPhoto({ photo: photoId, tag });
} else if (photoId && isPathCameraPhotoShare(pathname)) {
return pathForPhoto(photoId, undefined, camera);
return pathForPhoto({ photo: photoId, camera });
} else if (photoId && isPathFilmSimulationPhotoShare(pathname)) {
return pathForPhoto(photoId, undefined, undefined, simulation);
return pathForPhoto({ photo: photoId, simulation });
} else if (photoId && isPathFocalLengthPhotoShare(pathname)) {
return pathForPhoto(photoId, undefined, undefined, undefined, focal);
return pathForPhoto({ photo: photoId, focal });
} else if (photoId && isPathPhotoShare(pathname)) {
return pathForPhoto(photoId);
return pathForPhoto({ photo: photoId });
} else if (tag && (
isPathTagPhoto(pathname) ||
isPathTagShare(pathname)

View File

@ -31,9 +31,6 @@ export const getAspectRatioFromExif = (data: ExifData): number => {
}
};
export const formatFocalLength = (focalLength?: number) =>
focalLength ? `${focalLength}mm` : undefined;
export const formatAperture = (aperture?: number) =>
aperture ? `ƒ/${aperture}` : undefined;