import { Photo } from '@/photo'; import { BASE_URL } from './config'; import { Camera, createCameraKey, getCameraFromKey, } from '@/camera'; // Prefixes export const PREFIX_PHOTO = '/p'; export const PREFIX_TAG = '/tag'; export const PREFIX_CAMERA = '/shot-on'; // Core paths export const PATH_ROOT = '/'; export const PATH_GRID = '/grid'; export const PATH_ADMIN = '/admin'; export const PATH_SIGN_IN = '/sign-in'; export const PATH_OG = '/og'; export const PATH_CHECKLIST = '/checklist'; // Admin paths export const PATH_ADMIN_PHOTOS = `${PATH_ADMIN}/photos`; export const PATH_ADMIN_UPLOADS = `${PATH_ADMIN}/uploads`; export const PATH_ADMIN_TAGS = `${PATH_ADMIN}/tags`; export const PATH_ADMIN_UPLOAD = `${PATH_ADMIN}/uploads`; export const PATH_ADMIN_UPLOAD_BLOB = `${PATH_ADMIN_UPLOAD}/blob`; // Modifiers const SHARE = 'share'; const NEXT = 'next'; const EDIT = 'edit'; // Absolute paths export const ABSOLUTE_PATH_FOR_HOME_IMAGE = `${BASE_URL}/home-image`; const pathWithNext = (path: string, next?: number) => next !== undefined ? `${path}?${NEXT}=${next}` : path; export const pathForRoot = (next?: number) => pathWithNext(PATH_ROOT, next); export const pathForGrid = (next?: number) => pathWithNext(PATH_GRID, next); export const pathForAdminPhotos = (next?: number) => pathWithNext(PATH_ADMIN_PHOTOS, next); export const pathForAdminUploadUrl = (url: string) => `${PATH_ADMIN_UPLOADS}/${encodeURIComponent(url)}`; export const pathForAdminPhotoEdit = (photo: PhotoOrPhotoId) => `${PATH_ADMIN_PHOTOS}/${getPhotoId(photo)}/${EDIT}`; export const pathForAdminTagEdit = (tag: string) => `${PATH_ADMIN_TAGS}/${tag}/${EDIT}`; export const pathForOg = (next?: number) => pathWithNext(PATH_OG, next); type PhotoOrPhotoId = Photo | string; const getPhotoId = (photoOrPhotoId: PhotoOrPhotoId) => typeof photoOrPhotoId === 'string' ? photoOrPhotoId : photoOrPhotoId.id; export const pathForPhoto = ( photo: PhotoOrPhotoId, tag?: string, camera?: Camera, ) => tag ? `${pathForTag(tag)}/${getPhotoId(photo)}` : camera ? `${pathForCamera(camera)}/${getPhotoId(photo)}` : `${PREFIX_PHOTO}/${getPhotoId(photo)}`; export const pathForPhotoShare = ( photo: PhotoOrPhotoId, tag?: string, camera?: Camera, ) => `${pathForPhoto(photo, tag, camera)}/${SHARE}`; export const pathForTag = (tag: string, next?: number) => pathWithNext( `${PREFIX_TAG}/${tag}`, next, ); export const pathForTagShare = (tag: string) => `${pathForTag(tag)}/${SHARE}`; export const pathForCamera = (camera: Camera, next?: number) => pathWithNext(`${PREFIX_CAMERA}/${createCameraKey(camera)}`, next); export const pathForCameraShare = (camera: Camera) => `${pathForCamera(camera)}/${SHARE}`; export const absolutePathForPhoto = ( photo: PhotoOrPhotoId, tag?: string, camera?: Camera, ) => `${BASE_URL}${pathForPhoto(photo, tag, camera)}`; export const absolutePathForTag = (tag: string) => `${BASE_URL}${pathForTag(tag)}`; export const absolutePathForCamera= (camera: Camera) => `${BASE_URL}${pathForCamera(camera)}`; export const absolutePathForPhotoImage = (photo: PhotoOrPhotoId) => `${absolutePathForPhoto(photo)}/image`; export const absolutePathForTagImage = (tag: string) => `${absolutePathForTag(tag)}/image`; export const absolutePathForCameraImage= (camera: Camera) => `${absolutePathForCamera(camera)}/image`; // p/[photoId] export const isPathPhoto = (pathname = '') => new RegExp(`^${PREFIX_PHOTO}/[^/]+/?$`).test(pathname); // p/[photoId]/share export const isPathPhotoShare = (pathname = '') => new RegExp(`^${PREFIX_PHOTO}/[^/]+/${SHARE}/?$`).test(pathname); // tag/[tag] export const isPathTag = (pathname = '') => new RegExp(`^${PREFIX_TAG}/[^/]+/?$`).test(pathname); // tag/[tag]/share export const isPathTagShare = (pathname = '') => new RegExp(`^${PREFIX_TAG}/[^/]+/${SHARE}/?$`).test(pathname); // tag/[tag]/[photoId] export const isPathTagPhoto = (pathname = '') => new RegExp(`^${PREFIX_TAG}/[^/]+/[^/]+/?$`).test(pathname); // tag/[tag]/[photoId]/share export const isPathTagPhotoShare = (pathname = '') => new RegExp(`^${PREFIX_TAG}/[^/]+/[^/]+/${SHARE}/?$`).test(pathname); // shot-on/[camera] 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); // shot-on/[camera]/[photoId]/share export const isPathCameraPhotoShare = (pathname = '') => new RegExp(`^${PREFIX_CAMERA}/[^/]+/[^/]+/${SHARE}/?$`).test(pathname); export const isPathGrid = (pathname = '') => pathname.startsWith(PATH_GRID); export const isPathSignIn = (pathname = '') => pathname.startsWith(PATH_SIGN_IN); export const isPathAdmin = (pathname = '') => pathname.startsWith(PATH_ADMIN); export const isPathProtected = (pathname = '') => pathname.startsWith(PATH_ADMIN) || pathname === PATH_CHECKLIST; export const getPathComponents = (pathname = ''): { photoId?: string tag?: string camera?: Camera } => { const photoIdFromPhoto = pathname.match( new RegExp(`^${PREFIX_PHOTO}/([^/]+)`))?.[1]; const photoIdFromTag = pathname.match( new RegExp(`^${PREFIX_TAG}/[^/]+/((?!${SHARE})[^/]+)`))?.[1]; const photoIdFromCamera = pathname.match( new RegExp(`^${PREFIX_CAMERA}/[^/]+/((?!${SHARE})[^/]+)`))?.[1]; const tag = pathname.match( new RegExp(`^${PREFIX_TAG}/([^/]+)`))?.[1]; const cameraString = pathname.match( new RegExp(`^${PREFIX_CAMERA}/([^/]+)`))?.[1]; const camera = cameraString ? getCameraFromKey(cameraString) : undefined; return { photoId: ( photoIdFromPhoto || photoIdFromTag || photoIdFromCamera ), tag, camera, }; }; export const getEscapePath = (pathname?: string) => { const { photoId, tag, camera } = getPathComponents(pathname); if ( (photoId && isPathPhoto(pathname)) || (tag && isPathTag(pathname)) || (camera && isPathCamera(pathname)) ) { return PATH_GRID; } else if (photoId && isPathTagPhotoShare(pathname)) { return pathForPhoto(photoId, tag); } else if (photoId && isPathCameraPhotoShare(pathname)) { return pathForPhoto(photoId, undefined, camera); } else if (photoId && isPathPhotoShare(pathname)) { return pathForPhoto(photoId); } else if (tag && ( isPathTagPhoto(pathname) || isPathTagShare(pathname) )) { return pathForTag(tag); } else if (camera && ( isPathCameraPhoto(pathname) || isPathCameraShare(pathname) )) { return pathForCamera(camera); } };