diff --git a/__tests__/camera.test.ts b/__tests__/camera.test.ts new file mode 100644 index 00000000..41f11eb3 --- /dev/null +++ b/__tests__/camera.test.ts @@ -0,0 +1,14 @@ +import { Camera, formatCameraText } from '@/camera'; + +describe('Camera', () => { + it('labels correctly', () => { + const apple: Camera = { make: 'Apple', model: 'iPhone 11 Pro' }; + expect(formatCameraText(apple, true)).toBe('Apple iPhone 11 Pro'); + expect(formatCameraText(apple, false)).toBe('iPhone 11 Pro'); + const fujifilm: Camera = { make: 'Fujifilm', model: 'X-T5' }; + expect(formatCameraText(fujifilm)).toBe('Fujifilm X-T5'); + const canon: Camera = { make: 'Canon', model: 'Canon EOS 800D' }; + expect(formatCameraText(canon)).toBe('Canon EOS 800D'); + }); +}); + diff --git a/src/camera/PhotoCamera.tsx b/src/camera/PhotoCamera.tsx index 5a2c27bc..15f58ede 100644 --- a/src/camera/PhotoCamera.tsx +++ b/src/camera/PhotoCamera.tsx @@ -1,7 +1,7 @@ import { AiFillApple } from 'react-icons/ai'; import { pathForCamera } from '@/site/paths'; import { IoMdCamera } from 'react-icons/io'; -import { Camera } from '.'; +import { Camera, formatCameraText } from '.'; import EntityLink, { EntityLinkExternalProps } from '@/components/EntityLink'; import { clsx } from 'clsx/lite'; @@ -22,10 +22,7 @@ export default function PhotoCamera({ return ( - {!isCameraApple && <>{camera.make} } - {camera.model} - } + label={formatCameraText(camera)} href={pathForCamera(camera)} icon={showAppleIcon ? - make === 'Apple' && !includeMakeApple +) => { + // Remove potential duplicate make from model + const model = modelRaw.replace(`${make} `, ''); + return make === 'Apple' && !includeMakeApple ? model : `${make} ${model}`; +}; + +export const formatCameraModelText = ( + { make, model: modelRaw }: Camera, +) => { + // Remove potential duplicate make from model + const model = modelRaw.replace(`${make} `, ''); + const textLength = model?.length ?? 0; + if (textLength > 0 && textLength <= 8) { + return model; + } else if (model?.includes('iPhone')) { + return model.split('iPhone')[1]; + } else { + return undefined; + } +}; diff --git a/src/photo/PhotoLarge.tsx b/src/photo/PhotoLarge.tsx index 49b51e75..faa64436 100644 --- a/src/photo/PhotoLarge.tsx +++ b/src/photo/PhotoLarge.tsx @@ -82,18 +82,18 @@ export default function PhotoLarge({ } {showCamera && photoHasCameraData(photo) && -
- - {showSimulation && photo.filmSimulation && -
- -
} -
} +
+ + {showSimulation && photo.filmSimulation && +
+ +
} +
} )} {renderMiniGrid(<> {photoHasExifData(photo) && diff --git a/src/photo/image-response/CameraImageResponse.tsx b/src/photo/image-response/CameraImageResponse.tsx index e5be1a03..526cb9c8 100644 --- a/src/photo/image-response/CameraImageResponse.tsx +++ b/src/photo/image-response/CameraImageResponse.tsx @@ -2,7 +2,7 @@ import { Photo } from '..'; import ImageCaption from './components/ImageCaption'; import ImagePhotoGrid from './components/ImagePhotoGrid'; import ImageContainer from './components/ImageContainer'; -import { Camera, cameraFromPhoto } from '@/camera'; +import { Camera, cameraFromPhoto, formatCameraText } from '@/camera'; import { IoMdCamera } from 'react-icons/io'; import { NextImageSize } from '@/services/next-image'; @@ -19,7 +19,7 @@ export default function CameraImageResponse({ height: number fontFamily: string }) { - const { make, model } = cameraFromPhoto(photos[0], cameraProp); + const camera = cameraFromPhoto(photos[0], cameraProp); return ( - {make.toLowerCase() !== 'apple' && - {make}} - {model} + + {formatCameraText(camera)} + ); diff --git a/src/photo/image-response/PhotoImageResponse.tsx b/src/photo/image-response/PhotoImageResponse.tsx index 2d2a3b5b..499ca283 100644 --- a/src/photo/image-response/PhotoImageResponse.tsx +++ b/src/photo/image-response/PhotoImageResponse.tsx @@ -1,11 +1,11 @@ import { Photo } from '..'; -import { formatModelShort } from '@/utility/exif'; import { AiFillApple } from 'react-icons/ai'; import ImageCaption from './components/ImageCaption'; import ImagePhotoGrid from './components/ImagePhotoGrid'; import ImageContainer from './components/ImageContainer'; import { OG_TEXT_BOTTOM_ALIGNMENT } from '@/site/config'; import { NextImageSize } from '@/services/next-image'; +import { cameraFromPhoto, formatCameraModelText } from '@/camera'; export default function PhotoImageResponse({ photo, @@ -18,6 +18,10 @@ export default function PhotoImageResponse({ height: number fontFamily: string }) { + const model = photo.model + ? formatCameraModelText(cameraFromPhoto(photo)) + : undefined; + return ( } -
- {formatModelShort(photo.model)} -
+ {model && +
+ {model} +
}
{photo.focalLengthFormatted}
diff --git a/src/utility/exif.ts b/src/utility/exif.ts index c83b8ac6..ebc36bf9 100644 --- a/src/utility/exif.ts +++ b/src/utility/exif.ts @@ -57,14 +57,3 @@ export const formatExposureCompensation = (exposureCompensation?: number) => { return undefined; } }; - -export const formatModelShort = (model?: string) => { - const textLength = model?.length ?? 0; - if (textLength > 0 && textLength <= 8) { - return model; - } else if (model?.includes('iPhone')) { - return model.split('iPhone')[1]; - } else { - return undefined; - } -};