Show raw lens content next to photos
This commit is contained in:
parent
bac0c51f75
commit
bfe00c9565
@ -5,6 +5,7 @@ import { Camera } from '@/camera';
|
|||||||
import { FilmSimulation } from '@/simulation';
|
import { FilmSimulation } from '@/simulation';
|
||||||
import { parameterize } from '@/utility/string';
|
import { parameterize } from '@/utility/string';
|
||||||
import { TAG_HIDDEN } from '@/tag';
|
import { TAG_HIDDEN } from '@/tag';
|
||||||
|
import { Lens } from '@/lens';
|
||||||
|
|
||||||
// Core paths
|
// Core paths
|
||||||
export const PATH_ROOT = '/';
|
export const PATH_ROOT = '/';
|
||||||
@ -23,9 +24,10 @@ export const PATH_FEED_INFERRED = GRID_HOMEPAGE_ENABLED ? PATH_FEED : PATH
|
|||||||
export const PREFIX_PHOTO = '/p';
|
export const PREFIX_PHOTO = '/p';
|
||||||
export const PREFIX_TAG = '/tag';
|
export const PREFIX_TAG = '/tag';
|
||||||
export const PREFIX_CAMERA = '/shot-on';
|
export const PREFIX_CAMERA = '/shot-on';
|
||||||
|
export const PREFIX_LENS = '/lens';
|
||||||
|
export const PREFIX_RECIPE = '/recipe';
|
||||||
export const PREFIX_FILM_SIMULATION = '/film';
|
export const PREFIX_FILM_SIMULATION = '/film';
|
||||||
export const PREFIX_FOCAL_LENGTH = '/focal';
|
export const PREFIX_FOCAL_LENGTH = '/focal';
|
||||||
export const PREFIX_RECIPE = '/recipe';
|
|
||||||
|
|
||||||
// Dynamic paths
|
// Dynamic paths
|
||||||
const PATH_PHOTO_DYNAMIC = `${PREFIX_PHOTO}/[photoId]`;
|
const PATH_PHOTO_DYNAMIC = `${PREFIX_PHOTO}/[photoId]`;
|
||||||
@ -113,6 +115,7 @@ export const pathForPhoto = ({
|
|||||||
photo,
|
photo,
|
||||||
tag,
|
tag,
|
||||||
camera,
|
camera,
|
||||||
|
lens,
|
||||||
simulation,
|
simulation,
|
||||||
focal,
|
focal,
|
||||||
recipe,
|
recipe,
|
||||||
@ -123,6 +126,8 @@ export const pathForPhoto = ({
|
|||||||
? `${pathForTag(tag)}/${getPhotoId(photo)}`
|
? `${pathForTag(tag)}/${getPhotoId(photo)}`
|
||||||
: camera
|
: camera
|
||||||
? `${pathForCamera(camera)}/${getPhotoId(photo)}`
|
? `${pathForCamera(camera)}/${getPhotoId(photo)}`
|
||||||
|
: lens
|
||||||
|
? `${pathForLens(lens)}/${getPhotoId(photo)}`
|
||||||
: simulation
|
: simulation
|
||||||
? `${pathForFilmSimulation(simulation)}/${getPhotoId(photo)}`
|
? `${pathForFilmSimulation(simulation)}/${getPhotoId(photo)}`
|
||||||
: recipe
|
: recipe
|
||||||
@ -140,6 +145,9 @@ export const pathForCamera = ({ make, model }: Camera) =>
|
|||||||
export const pathForFilmSimulation = (simulation: FilmSimulation) =>
|
export const pathForFilmSimulation = (simulation: FilmSimulation) =>
|
||||||
`${PREFIX_FILM_SIMULATION}/${simulation}`;
|
`${PREFIX_FILM_SIMULATION}/${simulation}`;
|
||||||
|
|
||||||
|
export const pathForLens = ({ make, model }: Lens) =>
|
||||||
|
`${PREFIX_LENS}/${parameterize(make, true)}/${parameterize(model, true)}`;
|
||||||
|
|
||||||
export const pathForFocalLength = (focal: number) =>
|
export const pathForFocalLength = (focal: number) =>
|
||||||
`${PREFIX_FOCAL_LENGTH}/${focal}mm`;
|
`${PREFIX_FOCAL_LENGTH}/${focal}mm`;
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import { parameterize } from '@/utility/string';
|
|||||||
|
|
||||||
const CAMERA_PLACEHOLDER: Camera = { make: 'Camera', model: 'Model' };
|
const CAMERA_PLACEHOLDER: Camera = { make: 'Camera', model: 'Model' };
|
||||||
|
|
||||||
|
const CAMERA_MAKE_APPLE = 'apple';
|
||||||
|
|
||||||
export type Camera = {
|
export type Camera = {
|
||||||
make: string
|
make: string
|
||||||
model: string
|
model: string
|
||||||
@ -57,7 +59,7 @@ export const cameraFromPhoto = (
|
|||||||
: fallback ?? CAMERA_PLACEHOLDER;
|
: fallback ?? CAMERA_PLACEHOLDER;
|
||||||
|
|
||||||
const isCameraMakeApple = (make?: string) =>
|
const isCameraMakeApple = (make?: string) =>
|
||||||
make?.toLocaleLowerCase() === 'apple';
|
make?.toLocaleLowerCase() === CAMERA_MAKE_APPLE;
|
||||||
|
|
||||||
export const isCameraApple = ({ make }: Camera) =>
|
export const isCameraApple = ({ make }: Camera) =>
|
||||||
isCameraMakeApple(make);
|
isCameraMakeApple(make);
|
||||||
|
|||||||
34
src/lens/PhotoLens.tsx
Normal file
34
src/lens/PhotoLens.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { pathForLens } from '@/app/paths';
|
||||||
|
import { Lens, formatLensText } from '.';
|
||||||
|
import EntityLink, {
|
||||||
|
EntityLinkExternalProps,
|
||||||
|
} from '@/components/primitives/EntityLink';
|
||||||
|
import { TbCone } from 'react-icons/tb';
|
||||||
|
|
||||||
|
export default function PhotoLens({
|
||||||
|
lens,
|
||||||
|
type,
|
||||||
|
badged,
|
||||||
|
contrast,
|
||||||
|
prefetch,
|
||||||
|
countOnHover,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
lens: Lens
|
||||||
|
hideAppleIcon?: boolean
|
||||||
|
countOnHover?: number
|
||||||
|
} & EntityLinkExternalProps) {
|
||||||
|
return (
|
||||||
|
<EntityLink
|
||||||
|
label={formatLensText(lens)}
|
||||||
|
href={pathForLens(lens)}
|
||||||
|
icon={<TbCone className="rotate-[270deg] translate-x-[-1px]" />}
|
||||||
|
type={type}
|
||||||
|
className={className}
|
||||||
|
badged={badged}
|
||||||
|
contrast={contrast}
|
||||||
|
prefetch={prefetch}
|
||||||
|
hoverEntity={countOnHover}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -3,6 +3,8 @@ import { parameterize } from '@/utility/string';
|
|||||||
|
|
||||||
const LENS_PLACEHOLDER: Lens = { make: 'Lens', model: 'Model' };
|
const LENS_PLACEHOLDER: Lens = { make: 'Lens', model: 'Model' };
|
||||||
|
|
||||||
|
const LENS_MAKE_APPLE = 'apple';
|
||||||
|
|
||||||
export type Lens = {
|
export type Lens = {
|
||||||
make: string
|
make: string
|
||||||
model: string
|
model: string
|
||||||
@ -45,3 +47,12 @@ export const lensFromPhoto = (
|
|||||||
photo?.lensMake && photo?.lensModel
|
photo?.lensMake && photo?.lensModel
|
||||||
? { make: photo.lensMake, model: photo.lensModel }
|
? { make: photo.lensMake, model: photo.lensModel }
|
||||||
: fallback ?? LENS_PLACEHOLDER;
|
: fallback ?? LENS_PLACEHOLDER;
|
||||||
|
|
||||||
|
const isLensMakeApple = (make?: string) =>
|
||||||
|
make?.toLocaleLowerCase() === LENS_MAKE_APPLE;
|
||||||
|
|
||||||
|
export const isLensApple = ({ make }: Lens) =>
|
||||||
|
isLensMakeApple(make);
|
||||||
|
|
||||||
|
export const formatLensText = ({ make, model }: Lens, short = true) =>
|
||||||
|
short ? model : `${make} ${model}`;
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
doesPhotoNeedBlurCompatibility,
|
doesPhotoNeedBlurCompatibility,
|
||||||
shouldShowCameraDataForPhoto,
|
shouldShowCameraDataForPhoto,
|
||||||
shouldShowExifDataForPhoto,
|
shouldShowExifDataForPhoto,
|
||||||
|
shouldShowLensDataForPhoto,
|
||||||
titleForPhoto,
|
titleForPhoto,
|
||||||
} from '.';
|
} from '.';
|
||||||
import SiteGrid from '@/components/SiteGrid';
|
import SiteGrid from '@/components/SiteGrid';
|
||||||
@ -45,6 +46,8 @@ import { AnimatePresence } from 'framer-motion';
|
|||||||
import useRecipeOverlay from '../recipe/useRecipeOverlay';
|
import useRecipeOverlay from '../recipe/useRecipeOverlay';
|
||||||
import PhotoRecipeOverlay from '@/recipe/PhotoRecipeOverlay';
|
import PhotoRecipeOverlay from '@/recipe/PhotoRecipeOverlay';
|
||||||
import PhotoRecipe from '@/recipe/PhotoRecipe';
|
import PhotoRecipe from '@/recipe/PhotoRecipe';
|
||||||
|
import PhotoLens from '@/lens/PhotoLens';
|
||||||
|
import { lensFromPhoto } from '@/lens';
|
||||||
|
|
||||||
export default function PhotoLarge({
|
export default function PhotoLarge({
|
||||||
photo,
|
photo,
|
||||||
@ -57,6 +60,7 @@ export default function PhotoLarge({
|
|||||||
showTitle = true,
|
showTitle = true,
|
||||||
showTitleAsH1,
|
showTitleAsH1,
|
||||||
showCamera = true,
|
showCamera = true,
|
||||||
|
showLens = true,
|
||||||
showSimulation = true,
|
showSimulation = true,
|
||||||
showRecipe = true,
|
showRecipe = true,
|
||||||
showZoomControls: showZoomControlsProp = true,
|
showZoomControls: showZoomControlsProp = true,
|
||||||
@ -80,6 +84,7 @@ export default function PhotoLarge({
|
|||||||
showTitle?: boolean
|
showTitle?: boolean
|
||||||
showTitleAsH1?: boolean
|
showTitleAsH1?: boolean
|
||||||
showCamera?: boolean
|
showCamera?: boolean
|
||||||
|
showLens?: boolean
|
||||||
showSimulation?: boolean
|
showSimulation?: boolean
|
||||||
showRecipe?: boolean
|
showRecipe?: boolean
|
||||||
showZoomControls?: boolean
|
showZoomControls?: boolean
|
||||||
@ -121,10 +126,11 @@ export default function PhotoLarge({
|
|||||||
const tags = sortTags(photo.tags, primaryTag);
|
const tags = sortTags(photo.tags, primaryTag);
|
||||||
|
|
||||||
const camera = cameraFromPhoto(photo);
|
const camera = cameraFromPhoto(photo);
|
||||||
|
const lens = lensFromPhoto(photo);
|
||||||
const { recipeTitle: recipe } = photo;
|
const { recipeTitle: recipe } = photo;
|
||||||
|
|
||||||
const showCameraContent = showCamera && shouldShowCameraDataForPhoto(photo);
|
const showCameraContent = showCamera && shouldShowCameraDataForPhoto(photo);
|
||||||
|
const showLensContent = showLens && shouldShowLensDataForPhoto(photo);
|
||||||
const showRecipeContent = showRecipe && recipe;
|
const showRecipeContent = showRecipe && recipe;
|
||||||
const showTagsContent = tags.length > 0;
|
const showTagsContent = tags.length > 0;
|
||||||
const showExifContent = shouldShowExifDataForPhoto(photo);
|
const showExifContent = shouldShowExifDataForPhoto(photo);
|
||||||
@ -284,6 +290,15 @@ export default function PhotoLarge({
|
|||||||
contrast="medium"
|
contrast="medium"
|
||||||
prefetch={prefetchRelatedLinks}
|
prefetch={prefetchRelatedLinks}
|
||||||
/>}
|
/>}
|
||||||
|
{showLensContent &&
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<PhotoLens
|
||||||
|
lens={lens}
|
||||||
|
contrast="medium"
|
||||||
|
prefetch={prefetchRelatedLinks}
|
||||||
|
/>
|
||||||
|
</>}
|
||||||
{showRecipeContent &&
|
{showRecipeContent &&
|
||||||
<PhotoRecipe
|
<PhotoRecipe
|
||||||
recipe={recipe}
|
recipe={recipe}
|
||||||
|
|||||||
@ -298,6 +298,10 @@ const photoHasCameraData = (photo: Photo) =>
|
|||||||
Boolean(photo.make) &&
|
Boolean(photo.make) &&
|
||||||
Boolean(photo.model);
|
Boolean(photo.model);
|
||||||
|
|
||||||
|
const photoHasLensData = (photo: Photo) =>
|
||||||
|
Boolean(photo.lensMake) &&
|
||||||
|
Boolean(photo.lensModel);
|
||||||
|
|
||||||
const photoHasExifData = (photo: Photo) =>
|
const photoHasExifData = (photo: Photo) =>
|
||||||
Boolean(photo.focalLength) ||
|
Boolean(photo.focalLength) ||
|
||||||
Boolean(photo.focalLengthIn35MmFormat) ||
|
Boolean(photo.focalLengthIn35MmFormat) ||
|
||||||
@ -309,6 +313,9 @@ const photoHasExifData = (photo: Photo) =>
|
|||||||
export const shouldShowCameraDataForPhoto = (photo: Photo) =>
|
export const shouldShowCameraDataForPhoto = (photo: Photo) =>
|
||||||
SHOW_EXIF_DATA && photoHasCameraData(photo);
|
SHOW_EXIF_DATA && photoHasCameraData(photo);
|
||||||
|
|
||||||
|
export const shouldShowLensDataForPhoto = (photo: Photo) =>
|
||||||
|
SHOW_EXIF_DATA && photoHasLensData(photo);
|
||||||
|
|
||||||
export const shouldShowExifDataForPhoto = (photo: Photo) =>
|
export const shouldShowExifDataForPhoto = (photo: Photo) =>
|
||||||
SHOW_EXIF_DATA && photoHasExifData(photo);
|
SHOW_EXIF_DATA && photoHasExifData(photo);
|
||||||
|
|
||||||
|
|||||||
@ -10,10 +10,10 @@ import { Recipes } from '@/recipe';
|
|||||||
const CATEGORY_KEYS = [
|
const CATEGORY_KEYS = [
|
||||||
'tags',
|
'tags',
|
||||||
'cameras',
|
'cameras',
|
||||||
|
'lenses',
|
||||||
'recipes',
|
'recipes',
|
||||||
'films',
|
'films',
|
||||||
'focal-lengths',
|
'focal-lengths',
|
||||||
'lenses',
|
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
type CategoryKey = (typeof CATEGORY_KEYS)[number];
|
type CategoryKey = (typeof CATEGORY_KEYS)[number];
|
||||||
@ -23,6 +23,7 @@ type CategoryKeys = CategoryKey[];
|
|||||||
export const DEFAULT_CATEGORY_KEYS: CategoryKeys = [
|
export const DEFAULT_CATEGORY_KEYS: CategoryKeys = [
|
||||||
'tags',
|
'tags',
|
||||||
'cameras',
|
'cameras',
|
||||||
|
'lenses',
|
||||||
'recipes',
|
'recipes',
|
||||||
'films',
|
'films',
|
||||||
];
|
];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user