Refactor camera paths and string parsing
This commit is contained in:
parent
ef0b652c97
commit
eb94f4f0fb
@ -1,14 +1,30 @@
|
|||||||
import { Camera, formatCameraText } from '@/camera';
|
import { Camera, formatCameraText } from '@/camera';
|
||||||
|
|
||||||
|
const APPLE : Camera = { make: 'Apple', model: 'iPhone 11 Pro' };
|
||||||
|
const APPLE_01 : Camera = { make: 'Apple', model: 'iPhone 11' };
|
||||||
|
const APPLE_02 : Camera = { make: 'Apple', model: 'iPhone 15 Pro Max' };
|
||||||
|
const FUJIFILM : Camera = { make: 'Fujifilm', model: 'X-T5' };
|
||||||
|
const CANON : Camera = { make: 'Canon', model: 'Canon EOS 800D' };
|
||||||
|
const NIKON : Camera = {
|
||||||
|
make: 'Nikon Corporation',
|
||||||
|
model: 'Nikon D7000',
|
||||||
|
};
|
||||||
|
|
||||||
describe('Camera', () => {
|
describe('Camera', () => {
|
||||||
it('labels correctly', () => {
|
it('labels full text correctly', () => {
|
||||||
const apple: Camera = { make: 'Apple', model: 'iPhone 11 Pro' };
|
expect(formatCameraText(APPLE)).toBe('iPhone 11 Pro');
|
||||||
expect(formatCameraText(apple, true)).toBe('Apple iPhone 11 Pro');
|
expect(formatCameraText(APPLE, 'always')).toBe('Apple iPhone 11 Pro');
|
||||||
expect(formatCameraText(apple, false)).toBe('iPhone 11 Pro');
|
expect(formatCameraText(APPLE, 'if-not-apple')).toBe('iPhone 11 Pro');
|
||||||
const fujifilm: Camera = { make: 'Fujifilm', model: 'X-T5' };
|
expect(formatCameraText(APPLE, 'never')).toBe('iPhone 11 Pro');
|
||||||
expect(formatCameraText(fujifilm)).toBe('Fujifilm 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');
|
||||||
expect(formatCameraText(canon)).toBe('Canon EOS 800D');
|
expect(formatCameraText(NIKON)).toBe('Nikon D7000');
|
||||||
|
});
|
||||||
|
it('labels models correctly', () => {
|
||||||
|
expect(formatCameraText(APPLE, 'never')).toBe('iPhone 11 Pro');
|
||||||
|
expect(formatCameraText(APPLE, 'never', true)).toBe('11 Pro');
|
||||||
|
expect(formatCameraText(APPLE_01, 'never', true)).toBe('iPhone 11');
|
||||||
|
expect(formatCameraText(APPLE_02, 'never', true)).toBe('15 Pro Max');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -18,12 +18,12 @@ import {
|
|||||||
isPathTagPhotoShare,
|
isPathTagPhotoShare,
|
||||||
isPathTagShare,
|
isPathTagShare,
|
||||||
} from '@/site/paths';
|
} from '@/site/paths';
|
||||||
import { getCameraFromKey } from '@/camera';
|
|
||||||
|
|
||||||
const PHOTO_ID = 'UsKSGcbt';
|
const PHOTO_ID = 'UsKSGcbt';
|
||||||
const TAG = 'tag-name';
|
const TAG = 'tag-name';
|
||||||
const CAMERA = 'fujifilm-x-t1';
|
const CAMERA_MAKE = 'fujifilm';
|
||||||
const CAMERA_OBJECT = getCameraFromKey(CAMERA);
|
const CAMERA_MODEL = 'x-t1';
|
||||||
|
const CAMERA_OBJECT = { make: CAMERA_MAKE, model: CAMERA_MODEL };
|
||||||
const FILM_SIMULATION = 'acros';
|
const FILM_SIMULATION = 'acros';
|
||||||
const SHARE = 'share';
|
const SHARE = 'share';
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ const PATH_TAG_SHARE = `${PATH_TAG}/${SHARE}`;
|
|||||||
const PATH_TAG_PHOTO = `${PATH_TAG}/${PHOTO_ID}`;
|
const PATH_TAG_PHOTO = `${PATH_TAG}/${PHOTO_ID}`;
|
||||||
const PATH_TAG_PHOTO_SHARE = `${PATH_TAG_PHOTO}/${SHARE}`;
|
const PATH_TAG_PHOTO_SHARE = `${PATH_TAG_PHOTO}/${SHARE}`;
|
||||||
|
|
||||||
const PATH_CAMERA = `/shot-on/${CAMERA}`;
|
const PATH_CAMERA = `/shot-on/${CAMERA_MAKE}/${CAMERA_MODEL}`;
|
||||||
const PATH_CAMERA_SHARE = `${PATH_CAMERA}/${SHARE}`;
|
const PATH_CAMERA_SHARE = `${PATH_CAMERA}/${SHARE}`;
|
||||||
const PATH_CAMERA_PHOTO = `${PATH_CAMERA}/${PHOTO_ID}`;
|
const PATH_CAMERA_PHOTO = `${PATH_CAMERA}/${PHOTO_ID}`;
|
||||||
const PATH_CAMERA_PHOTO_SHARE = `${PATH_CAMERA_PHOTO}/${SHARE}`;
|
const PATH_CAMERA_PHOTO_SHARE = `${PATH_CAMERA_PHOTO}/${SHARE}`;
|
||||||
|
|||||||
@ -11,16 +11,12 @@ import {
|
|||||||
} from '@/site/paths';
|
} from '@/site/paths';
|
||||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||||
import { getPhotoCached } from '@/photo/cache';
|
import { getPhotoCached } from '@/photo/cache';
|
||||||
import { cameraFromPhoto } from '@/camera';
|
import { PhotoCameraProps, cameraFromPhoto } from '@/camera';
|
||||||
import { getPhotosCameraDataCached } from '@/camera/data';
|
import { getPhotosCameraDataCached } from '@/camera/data';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
interface PhotoCameraProps {
|
|
||||||
params: { photoId: string, camera: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function generateMetadata({
|
export async function generateMetadata({
|
||||||
params: { photoId, camera },
|
params: { photoId, make, model },
|
||||||
}: PhotoCameraProps): Promise<Metadata> {
|
}: PhotoCameraProps): Promise<Metadata> {
|
||||||
const photo = await getPhotoCached(photoId);
|
const photo = await getPhotoCached(photoId);
|
||||||
|
|
||||||
@ -32,7 +28,7 @@ export async function generateMetadata({
|
|||||||
const url = absolutePathForPhoto(
|
const url = absolutePathForPhoto(
|
||||||
photo,
|
photo,
|
||||||
undefined,
|
undefined,
|
||||||
cameraFromPhoto(photo, camera),
|
cameraFromPhoto(photo, { make, model }),
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -54,14 +50,14 @@ export async function generateMetadata({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function PhotoCameraPage({
|
export default async function PhotoCameraPage({
|
||||||
params: { photoId, camera: cameraProp },
|
params: { photoId, make, model },
|
||||||
children,
|
children,
|
||||||
}: PhotoCameraProps & { children: ReactNode }) {
|
}: PhotoCameraProps & { children: ReactNode }) {
|
||||||
const photo = await getPhotoCached(photoId);
|
const photo = await getPhotoCached(photoId);
|
||||||
|
|
||||||
if (!photo) { redirect(PATH_ROOT); }
|
if (!photo) { redirect(PATH_ROOT); }
|
||||||
|
|
||||||
const camera = cameraFromPhoto(photo, cameraProp);
|
const camera = cameraFromPhoto(photo, { make, model });
|
||||||
|
|
||||||
const [
|
const [
|
||||||
photos,
|
photos,
|
||||||
@ -1,19 +1,17 @@
|
|||||||
import { getPhotoCached } from '@/photo/cache';
|
import { getPhotoCached } from '@/photo/cache';
|
||||||
import { cameraFromPhoto } from '@/camera';
|
import { PhotoCameraProps, cameraFromPhoto } from '@/camera';
|
||||||
import PhotoShareModal from '@/photo/PhotoShareModal';
|
import PhotoShareModal from '@/photo/PhotoShareModal';
|
||||||
import { PATH_ROOT } from '@/site/paths';
|
import { PATH_ROOT } from '@/site/paths';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
export default async function Share({
|
export default async function Share({
|
||||||
params: { photoId, camera: cameraProp },
|
params: { photoId, make, model },
|
||||||
}: {
|
}: PhotoCameraProps) {
|
||||||
params: { photoId: string, camera: string }
|
|
||||||
}) {
|
|
||||||
const photo = await getPhotoCached(photoId);
|
const photo = await getPhotoCached(photoId);
|
||||||
|
|
||||||
if (!photo) { return redirect(PATH_ROOT); }
|
if (!photo) { return redirect(PATH_ROOT); }
|
||||||
|
|
||||||
const camera = cameraFromPhoto(photo, cameraProp);
|
const camera = cameraFromPhoto(photo, { make, model });
|
||||||
|
|
||||||
return <PhotoShareModal {...{ photo, camera }} />;
|
return <PhotoShareModal {...{ photo, camera }} />;
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import { getPhotosCached } from '@/photo/cache';
|
import { getPhotosCached } from '@/photo/cache';
|
||||||
import { getCameraFromKey } from '@/camera';
|
import { CameraProps, getCameraFromParams } from '@/camera';
|
||||||
import {
|
import {
|
||||||
IMAGE_OG_DIMENSION_SMALL,
|
IMAGE_OG_DIMENSION_SMALL,
|
||||||
MAX_PHOTOS_TO_SHOW_PER_TAG,
|
MAX_PHOTOS_TO_SHOW_PER_TAG,
|
||||||
@ -13,9 +13,9 @@ export const runtime = 'edge';
|
|||||||
|
|
||||||
export async function GET(
|
export async function GET(
|
||||||
_: Request,
|
_: Request,
|
||||||
context: { params: { camera: string } },
|
context: CameraProps,
|
||||||
) {
|
) {
|
||||||
const camera = getCameraFromKey(context.params.camera);
|
const camera = getCameraFromParams(context.params);
|
||||||
|
|
||||||
const [
|
const [
|
||||||
photos,
|
photos,
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { getCameraFromKey } from '@/camera';
|
import { CameraProps, getCameraFromParams } from '@/camera';
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
import { generateMetaForCamera } from '@/camera/meta';
|
import { generateMetaForCamera } from '@/camera/meta';
|
||||||
import { GRID_THUMBNAILS_TO_SHOW_MAX } from '@/photo';
|
import { GRID_THUMBNAILS_TO_SHOW_MAX } from '@/photo';
|
||||||
@ -9,14 +9,10 @@ import {
|
|||||||
} from '@/camera/data';
|
} from '@/camera/data';
|
||||||
import CameraOverview from '@/camera/CameraOverview';
|
import CameraOverview from '@/camera/CameraOverview';
|
||||||
|
|
||||||
interface CameraProps {
|
|
||||||
params: { camera: string },
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function generateMetadata({
|
export async function generateMetadata({
|
||||||
params,
|
params,
|
||||||
}: CameraProps): Promise<Metadata> {
|
}: CameraProps): Promise<Metadata> {
|
||||||
const camera = getCameraFromKey(params.camera);
|
const camera = getCameraFromParams(params);
|
||||||
|
|
||||||
const [
|
const [
|
||||||
photos,
|
photos,
|
||||||
@ -55,7 +51,7 @@ export default async function CameraPage({
|
|||||||
params,
|
params,
|
||||||
searchParams,
|
searchParams,
|
||||||
}: CameraProps & PaginationParams) {
|
}: CameraProps & PaginationParams) {
|
||||||
const camera = getCameraFromKey(params.camera);
|
const camera = getCameraFromParams(params);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
photos,
|
photos,
|
||||||
@ -1,4 +1,8 @@
|
|||||||
import { cameraFromPhoto, getCameraFromKey } from '@/camera';
|
import {
|
||||||
|
CameraProps,
|
||||||
|
cameraFromPhoto,
|
||||||
|
getCameraFromParams,
|
||||||
|
} from '@/camera';
|
||||||
import CameraShareModal from '@/camera/CameraShareModal';
|
import CameraShareModal from '@/camera/CameraShareModal';
|
||||||
import { generateMetaForCamera } from '@/camera/meta';
|
import { generateMetaForCamera } from '@/camera/meta';
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
@ -10,14 +14,10 @@ import {
|
|||||||
} from '@/camera/data';
|
} from '@/camera/data';
|
||||||
import CameraOverview from '@/camera/CameraOverview';
|
import CameraOverview from '@/camera/CameraOverview';
|
||||||
|
|
||||||
interface CameraProps {
|
|
||||||
params: { camera: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function generateMetadata({
|
export async function generateMetadata({
|
||||||
params,
|
params,
|
||||||
}: CameraProps): Promise<Metadata> {
|
}: CameraProps): Promise<Metadata> {
|
||||||
const camera = getCameraFromKey(params.camera);
|
const camera = getCameraFromParams(params);
|
||||||
|
|
||||||
const [
|
const [
|
||||||
photos,
|
photos,
|
||||||
@ -56,7 +56,7 @@ export default async function Share({
|
|||||||
params,
|
params,
|
||||||
searchParams,
|
searchParams,
|
||||||
}: CameraProps & PaginationParams) {
|
}: CameraProps & PaginationParams) {
|
||||||
const cameraFromParams = getCameraFromKey(params.camera);
|
const cameraFromParams = getCameraFromParams(params);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
photos,
|
photos,
|
||||||
@ -8,6 +8,14 @@ export type Camera = {
|
|||||||
model: string
|
model: string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface CameraProps {
|
||||||
|
params: Camera
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PhotoCameraProps {
|
||||||
|
params: Camera & { photoId: string }
|
||||||
|
}
|
||||||
|
|
||||||
export type CameraWithCount = {
|
export type CameraWithCount = {
|
||||||
cameraKey: string
|
cameraKey: string
|
||||||
camera: Camera
|
camera: Camera
|
||||||
@ -19,11 +27,16 @@ export type Cameras = CameraWithCount[];
|
|||||||
export const createCameraKey = ({ make, model }: Camera) =>
|
export const createCameraKey = ({ make, model }: Camera) =>
|
||||||
parameterize(`${make}-${model}`, true);
|
parameterize(`${make}-${model}`, true);
|
||||||
|
|
||||||
// Assumes no makes ('Fujifilm,' 'Apple,' 'Canon', etc.) have dashes
|
export const getCameraFromParams = ({
|
||||||
export const getCameraFromKey = (cameraKey: string): Camera => {
|
make,
|
||||||
const [make, model] = cameraKey.toLowerCase().split(/[-| ](.*)/s);
|
model,
|
||||||
return { make, model };
|
}: {
|
||||||
};
|
make: string,
|
||||||
|
model: string,
|
||||||
|
}): Camera => ({
|
||||||
|
make: parameterize(make, true),
|
||||||
|
model: parameterize(model, true),
|
||||||
|
});
|
||||||
|
|
||||||
export const sortCamerasWithCount = (
|
export const sortCamerasWithCount = (
|
||||||
a: CameraWithCount,
|
a: CameraWithCount,
|
||||||
@ -36,36 +49,34 @@ export const sortCamerasWithCount = (
|
|||||||
|
|
||||||
export const cameraFromPhoto = (
|
export const cameraFromPhoto = (
|
||||||
photo: Photo | undefined,
|
photo: Photo | undefined,
|
||||||
fallback?: Camera | string,
|
fallback?: Camera,
|
||||||
): Camera =>
|
): Camera =>
|
||||||
photo?.make && photo?.model
|
photo?.make && photo?.model
|
||||||
? { make: photo.make, model: photo.model }
|
? { make: photo.make, model: photo.model }
|
||||||
: typeof fallback === 'string'
|
: fallback ?? CAMERA_PLACEHOLDER;
|
||||||
? getCameraFromKey(fallback)
|
|
||||||
: fallback ?? CAMERA_PLACEHOLDER;
|
|
||||||
|
|
||||||
export const formatCameraText = (
|
export const formatCameraText = (
|
||||||
{ make, model: modelRaw }: Camera,
|
{ make: makeRaw, model: modelRaw }: Camera,
|
||||||
includeMakeApple?: boolean,
|
includeMake: 'always' | 'never' | 'if-not-apple' = 'if-not-apple',
|
||||||
|
removeIPhoneOnLongModels?: boolean
|
||||||
) => {
|
) => {
|
||||||
|
// Remove 'Corporation' from makes like 'Nikon Corporation'
|
||||||
|
const make = makeRaw.replace(/ Corporation/i, '');
|
||||||
// Remove potential duplicate make from model
|
// Remove potential duplicate make from model
|
||||||
const model = modelRaw.replace(`${make} `, '');
|
let model = modelRaw.replace(`${make} `, '');
|
||||||
return make === 'Apple' && !includeMakeApple
|
if (
|
||||||
? model
|
removeIPhoneOnLongModels &&
|
||||||
|
model.includes('iPhone') &&
|
||||||
|
model.length > 9
|
||||||
|
) {
|
||||||
|
model = model.replace(/iPhone\s*/i, '');
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
includeMake === 'never' ||
|
||||||
|
includeMake === 'if-not-apple' && make === 'Apple'
|
||||||
|
) ? model
|
||||||
: `${make} ${model}`;
|
: `${make} ${model}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const formatCameraModelText = (
|
export const formatCameraModelTextShort = (camera: Camera) =>
|
||||||
{ make, model: modelRaw }: Camera,
|
formatCameraText(camera, 'never', true);
|
||||||
) => {
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import ImagePhotoGrid from './components/ImagePhotoGrid';
|
|||||||
import ImageContainer from './components/ImageContainer';
|
import ImageContainer from './components/ImageContainer';
|
||||||
import { OG_TEXT_BOTTOM_ALIGNMENT } from '@/site/config';
|
import { OG_TEXT_BOTTOM_ALIGNMENT } from '@/site/config';
|
||||||
import { NextImageSize } from '@/services/next-image';
|
import { NextImageSize } from '@/services/next-image';
|
||||||
import { cameraFromPhoto, formatCameraModelText } from '@/camera';
|
import { cameraFromPhoto, formatCameraModelTextShort } from '@/camera';
|
||||||
|
|
||||||
export default function PhotoImageResponse({
|
export default function PhotoImageResponse({
|
||||||
photo,
|
photo,
|
||||||
@ -19,7 +19,7 @@ export default function PhotoImageResponse({
|
|||||||
fontFamily: string
|
fontFamily: string
|
||||||
}) {
|
}) {
|
||||||
const model = photo.model
|
const model = photo.model
|
||||||
? formatCameraModelText(cameraFromPhoto(photo))
|
? formatCameraModelTextShort(cameraFromPhoto(photo))
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -191,7 +191,7 @@ const sqlGetPhotosTagCount = async (tag: string) => sql`
|
|||||||
const sqlGetPhotosCameraCount = async (camera: Camera) => sql`
|
const sqlGetPhotosCameraCount = async (camera: Camera) => sql`
|
||||||
SELECT COUNT(*) FROM photos
|
SELECT COUNT(*) FROM photos
|
||||||
WHERE
|
WHERE
|
||||||
LOWER(make)=${parameterize(camera.make, true)} AND
|
LOWER(REPLACE(make, ' ', '-'))=${parameterize(camera.make, true)} AND
|
||||||
LOWER(REPLACE(model, ' ', '-'))=${parameterize(camera.model, true)} AND
|
LOWER(REPLACE(model, ' ', '-'))=${parameterize(camera.model, true)} AND
|
||||||
hidden IS NOT TRUE
|
hidden IS NOT TRUE
|
||||||
`.then(({ rows }) => parseInt(rows[0].count, 10));
|
`.then(({ rows }) => parseInt(rows[0].count, 10));
|
||||||
@ -225,7 +225,7 @@ const sqlGetPhotosCameraDateRange = async (camera: Camera) => sql`
|
|||||||
SELECT MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
|
SELECT MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
|
||||||
FROM photos
|
FROM photos
|
||||||
WHERE
|
WHERE
|
||||||
LOWER(make)=${parameterize(camera.make, true)} AND
|
LOWER(REPLACE(make, ' ', '-'))=${parameterize(camera.make, true)} AND
|
||||||
LOWER(REPLACE(model, ' ', '-'))=${parameterize(camera.model, true)} AND
|
LOWER(REPLACE(model, ' ', '-'))=${parameterize(camera.model, true)} AND
|
||||||
hidden IS NOT TRUE
|
hidden IS NOT TRUE
|
||||||
`.then(({ rows }) => rows[0]?.start && rows[0]?.end
|
`.then(({ rows }) => rows[0]?.start && rows[0]?.end
|
||||||
@ -380,7 +380,7 @@ export const getPhotos = async (options: GetPhotosOptions = {}) => {
|
|||||||
values.push(tag);
|
values.push(tag);
|
||||||
}
|
}
|
||||||
if (camera) {
|
if (camera) {
|
||||||
wheres.push(`LOWER(make)=$${valueIndex++}`);
|
wheres.push(`LOWER(REPLACE(make, ' ', '-'))=$${valueIndex++}`);
|
||||||
wheres.push(`LOWER(REPLACE(model, ' ', '-'))=$${valueIndex++}`);
|
wheres.push(`LOWER(REPLACE(model, ' ', '-'))=$${valueIndex++}`);
|
||||||
values.push(parameterize(camera.make, true));
|
values.push(parameterize(camera.make, true));
|
||||||
values.push(parameterize(camera.model, true));
|
values.push(parameterize(camera.model, true));
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
import { Photo } from '@/photo';
|
import { Photo } from '@/photo';
|
||||||
import { BASE_URL } from './config';
|
import { BASE_URL } from './config';
|
||||||
import {
|
import { Camera } from '@/camera';
|
||||||
Camera,
|
|
||||||
createCameraKey,
|
|
||||||
getCameraFromKey,
|
|
||||||
} from '@/camera';
|
|
||||||
import { FilmSimulation } from '@/simulation';
|
import { FilmSimulation } from '@/simulation';
|
||||||
|
import { parameterize } from '@/utility/string';
|
||||||
|
|
||||||
// Core paths
|
// Core paths
|
||||||
export const PATH_ROOT = '/';
|
export const PATH_ROOT = '/';
|
||||||
@ -24,7 +21,7 @@ export const PREFIX_FILM_SIMULATION = '/film';
|
|||||||
// Dynamic paths
|
// Dynamic paths
|
||||||
const PATH_PHOTO_DYNAMIC = `${PREFIX_PHOTO}/[photoId]`;
|
const PATH_PHOTO_DYNAMIC = `${PREFIX_PHOTO}/[photoId]`;
|
||||||
const PATH_TAG_DYNAMIC = `${PREFIX_TAG}/[tag]`;
|
const PATH_TAG_DYNAMIC = `${PREFIX_TAG}/[tag]`;
|
||||||
const PATH_CAMERA_DYNAMIC = `${PREFIX_CAMERA}/[camera]`;
|
const PATH_CAMERA_DYNAMIC = `${PREFIX_CAMERA}/[make]/[model]`;
|
||||||
const PATH_FILM_SIMULATION_DYNAMIC = `${PREFIX_FILM_SIMULATION}/[simulation]`;
|
const PATH_FILM_SIMULATION_DYNAMIC = `${PREFIX_FILM_SIMULATION}/[simulation]`;
|
||||||
|
|
||||||
// Admin paths
|
// Admin paths
|
||||||
@ -126,8 +123,11 @@ export const pathForTag = (tag: string, next?: number) =>
|
|||||||
export const pathForTagShare = (tag: string) =>
|
export const pathForTagShare = (tag: string) =>
|
||||||
`${pathForTag(tag)}/${SHARE}`;
|
`${pathForTag(tag)}/${SHARE}`;
|
||||||
|
|
||||||
export const pathForCamera = (camera: Camera, next?: number) =>
|
export const pathForCamera = ({ make, model }: Camera, next?: number) =>
|
||||||
pathWithNext(`${PREFIX_CAMERA}/${createCameraKey(camera)}`, next);
|
pathWithNext(
|
||||||
|
`${PREFIX_CAMERA}/${parameterize(make, true)}/${parameterize(model, true)}`,
|
||||||
|
next,
|
||||||
|
);
|
||||||
|
|
||||||
export const pathForCameraShare = (camera: Camera) =>
|
export const pathForCameraShare = (camera: Camera) =>
|
||||||
`${pathForCamera(camera)}/${SHARE}`;
|
`${pathForCamera(camera)}/${SHARE}`;
|
||||||
@ -196,22 +196,22 @@ export const isPathTagPhoto = (pathname = '') =>
|
|||||||
export const isPathTagPhotoShare = (pathname = '') =>
|
export const isPathTagPhotoShare = (pathname = '') =>
|
||||||
new RegExp(`^${PREFIX_TAG}/[^/]+/[^/]+/${SHARE}/?$`).test(pathname);
|
new RegExp(`^${PREFIX_TAG}/[^/]+/[^/]+/${SHARE}/?$`).test(pathname);
|
||||||
|
|
||||||
// shot-on/[camera]
|
// shot-on/[make]/[model]
|
||||||
export const isPathCamera = (pathname = '') =>
|
export const isPathCamera = (pathname = '') =>
|
||||||
new RegExp(`^${PREFIX_CAMERA}/[^/]+/?$`).test(pathname);
|
|
||||||
|
|
||||||
// shot-on/[camera]/share
|
|
||||||
export const isPathCameraShare = (pathname = '') =>
|
|
||||||
new RegExp(`^${PREFIX_CAMERA}/[^/]+/${SHARE}/?$`).test(pathname);
|
|
||||||
|
|
||||||
// shot-on/[camera]/[photoId]
|
|
||||||
export const isPathCameraPhoto = (pathname = '') =>
|
|
||||||
new RegExp(`^${PREFIX_CAMERA}/[^/]+/[^/]+/?$`).test(pathname);
|
new RegExp(`^${PREFIX_CAMERA}/[^/]+/[^/]+/?$`).test(pathname);
|
||||||
|
|
||||||
// shot-on/[camera]/[photoId]/share
|
// shot-on/[make]/[model]/share
|
||||||
export const isPathCameraPhotoShare = (pathname = '') =>
|
export const isPathCameraShare = (pathname = '') =>
|
||||||
new RegExp(`^${PREFIX_CAMERA}/[^/]+/[^/]+/${SHARE}/?$`).test(pathname);
|
new RegExp(`^${PREFIX_CAMERA}/[^/]+/[^/]+/${SHARE}/?$`).test(pathname);
|
||||||
|
|
||||||
|
// shot-on/[make]/[model]/[photoId]
|
||||||
|
export const isPathCameraPhoto = (pathname = '') =>
|
||||||
|
new RegExp(`^${PREFIX_CAMERA}/[^/]+/[^/]+/[^/]+/?$`).test(pathname);
|
||||||
|
|
||||||
|
// shot-on/[make]/[model]/[photoId]/share
|
||||||
|
export const isPathCameraPhotoShare = (pathname = '') =>
|
||||||
|
new RegExp(`^${PREFIX_CAMERA}/[^/]+/[^/]+/[^/]+/${SHARE}/?$`).test(pathname);
|
||||||
|
|
||||||
// film/[simulation]
|
// film/[simulation]
|
||||||
export const isPathFilmSimulation = (pathname = '') =>
|
export const isPathFilmSimulation = (pathname = '') =>
|
||||||
new RegExp(`^${PREFIX_FILM_SIMULATION}/[^/]+/?$`).test(pathname);
|
new RegExp(`^${PREFIX_FILM_SIMULATION}/[^/]+/?$`).test(pathname);
|
||||||
@ -258,18 +258,20 @@ export const getPathComponents = (pathname = ''): {
|
|||||||
const photoIdFromTag = pathname.match(
|
const photoIdFromTag = pathname.match(
|
||||||
new RegExp(`^${PREFIX_TAG}/[^/]+/((?!${SHARE})[^/]+)`))?.[1];
|
new RegExp(`^${PREFIX_TAG}/[^/]+/((?!${SHARE})[^/]+)`))?.[1];
|
||||||
const photoIdFromCamera = pathname.match(
|
const photoIdFromCamera = pathname.match(
|
||||||
new RegExp(`^${PREFIX_CAMERA}/[^/]+/((?!${SHARE})[^/]+)`))?.[1];
|
new RegExp(`^${PREFIX_CAMERA}/[^/]+/[^/]+/((?!${SHARE})[^/]+)`))?.[1];
|
||||||
const photoIdFromFilmSimulation = pathname.match(
|
const photoIdFromFilmSimulation = pathname.match(
|
||||||
new RegExp(`^${PREFIX_FILM_SIMULATION}/[^/]+/((?!${SHARE})[^/]+)`))?.[1];
|
new RegExp(`^${PREFIX_FILM_SIMULATION}/[^/]+/((?!${SHARE})[^/]+)`))?.[1];
|
||||||
const tag = pathname.match(
|
const tag = pathname.match(
|
||||||
new RegExp(`^${PREFIX_TAG}/([^/]+)`))?.[1];
|
new RegExp(`^${PREFIX_TAG}/([^/]+)`))?.[1];
|
||||||
const cameraString = pathname.match(
|
const cameraMake = pathname.match(
|
||||||
new RegExp(`^${PREFIX_CAMERA}/([^/]+)`))?.[1];
|
new RegExp(`^${PREFIX_CAMERA}/([^/]+)`))?.[1];
|
||||||
|
const cameraModel = pathname.match(
|
||||||
|
new RegExp(`^${PREFIX_CAMERA}/[^/]+/([^/]+)`))?.[1];
|
||||||
const simulation = pathname.match(
|
const simulation = pathname.match(
|
||||||
new RegExp(`^${PREFIX_FILM_SIMULATION}/([^/]+)`))?.[1] as FilmSimulation;
|
new RegExp(`^${PREFIX_FILM_SIMULATION}/([^/]+)`))?.[1] as FilmSimulation;
|
||||||
|
|
||||||
const camera = cameraString
|
const camera = cameraMake && cameraModel
|
||||||
? getCameraFromKey(cameraString)
|
? { make: cameraMake, model: cameraModel }
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user