From f9db50e41a4200fa1507721acfb657dd8dc6da8c Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Tue, 1 Apr 2025 21:08:36 -0500 Subject: [PATCH] Generalize film type and labeling strategy --- app/admin/uploads/[uploadPath]/page.tsx | 3 +- app/film-demo/animate/page.tsx | 6 +-- app/film-demo/page.tsx | 4 +- app/film/[film]/[photoId]/page.tsx | 5 +-- app/film/[film]/image/route.tsx | 3 +- app/film/[film]/page.tsx | 4 +- src/app/paths.ts | 9 ++--- src/category/index.ts | 4 +- src/cmdk/CommandKClient.tsx | 2 +- src/film/FilmHeader.tsx | 4 +- src/film/FilmOGTile.tsx | 8 +--- src/film/FilmOverview.tsx | 3 +- src/film/FilmShareModal.tsx | 4 +- src/film/PhotoFilm.tsx | 5 +-- src/film/PhotoFilmIcon.tsx | 5 +-- src/film/data.ts | 3 +- src/film/index.tsx | 38 ++++++++++++------- src/image-response/FilmImageResponse.tsx | 7 +--- src/image-response/RecipeImageResponse.tsx | 6 ++- src/photo/actions.ts | 3 +- src/photo/db/query.ts | 10 ++--- .../form/ApplyRecipesGloballyCheckbox.tsx | 3 +- src/photo/form/PhotoForm.tsx | 4 +- src/photo/form/index.ts | 6 +-- src/photo/index.ts | 5 ++- src/photo/server.ts | 4 +- src/platforms/fujifilm/simulation.ts | 22 +++++------ src/recipe/PhotoRecipeOverlay.tsx | 2 +- src/recipe/index.ts | 5 +-- 29 files changed, 92 insertions(+), 95 deletions(-) diff --git a/app/admin/uploads/[uploadPath]/page.tsx b/app/admin/uploads/[uploadPath]/page.tsx index 055be14e..3bc007e9 100644 --- a/app/admin/uploads/[uploadPath]/page.tsx +++ b/app/admin/uploads/[uploadPath]/page.tsx @@ -14,7 +14,6 @@ import { } from '@/app/config'; import ErrorNote from '@/components/ErrorNote'; import { getRecipeTitleForData } from '@/photo/db/query'; -import { FilmSimulation } from '@/film'; export const maxDuration = 60; @@ -58,7 +57,7 @@ export default async function UploadPage({ params }: Params) { formDataFromExif?.recipeData && formDataFromExif.film ? getRecipeTitleForData( formDataFromExif.recipeData, - formDataFromExif.film as FilmSimulation, + formDataFromExif.film, ) : undefined, ]); diff --git a/app/film-demo/animate/page.tsx b/app/film-demo/animate/page.tsx index 0542cda2..7c8c8d5a 100644 --- a/app/film-demo/animate/page.tsx +++ b/app/film-demo/animate/page.tsx @@ -3,7 +3,7 @@ import AppGrid from '@/components/AppGrid'; import { clsx } from 'clsx/lite'; import { - FILM_SIMULATION_FORM_INPUT_OPTIONS, + FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS, } from '@/platforms/fujifilm/simulation'; import PhotoFilm from '@/film/PhotoFilm'; import { useEffect, useState } from 'react'; @@ -13,7 +13,7 @@ export default function FilmPage() { useEffect(() => { const interval = setInterval(() => { - setIndex((index + 1) % FILM_SIMULATION_FORM_INPUT_OPTIONS.length); + setIndex((index + 1) % FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS.length); }, 200); return () => clearInterval(interval); }); @@ -28,7 +28,7 @@ export default function FilmPage() { Film Simulation:
diff --git a/app/film-demo/page.tsx b/app/film-demo/page.tsx index 972e4143..4bb841d0 100644 --- a/app/film-demo/page.tsx +++ b/app/film-demo/page.tsx @@ -1,12 +1,12 @@ import { - FILM_SIMULATION_FORM_INPUT_OPTIONS, + FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS, } from '@/platforms/fujifilm/simulation'; import PhotoFilm from '@/film/PhotoFilm'; export default function FilmPage() { return (
- {FILM_SIMULATION_FORM_INPUT_OPTIONS.map(({ value }) => + {FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS.map(({ value }) =>
getPhotosNearIdCached( photoId, @@ -28,7 +27,7 @@ const getPhotosNearIdCachedCached = cache(( )); interface PhotoFilmProps { - params: Promise<{ photoId: string, film: FilmSimulation }> + params: Promise<{ photoId: string, film: string }> } export async function generateMetadata({ diff --git a/app/film/[film]/image/route.tsx b/app/film/[film]/image/route.tsx index 83a77b22..330d0355 100644 --- a/app/film/[film]/image/route.tsx +++ b/app/film/[film]/image/route.tsx @@ -5,7 +5,6 @@ import { } from '@/image-response'; import FilmImageResponse from '@/image-response/FilmImageResponse'; -import { FilmSimulation } from '@/film'; import { getIBMPlexMono } from '@/app/font'; import { ImageResponse } from 'next/og'; import { getImageResponseCacheControlHeaders } from '@/image-response/cache'; @@ -21,7 +20,7 @@ export const generateStaticParams = staticallyGenerateCategoryIfConfigured( export async function GET( _: Request, - context: { params: Promise<{ film: FilmSimulation }> }, + context: { params: Promise<{ film: string }> }, ) { const { film } = await context.params; diff --git a/app/film/[film]/page.tsx b/app/film/[film]/page.tsx index 2fdff053..c521a4ea 100644 --- a/app/film/[film]/page.tsx +++ b/app/film/[film]/page.tsx @@ -1,6 +1,6 @@ import { INFINITE_SCROLL_GRID_INITIAL } from '@/photo'; import { getUniqueFilms } from '@/photo/db/query'; -import { FilmSimulation, generateMetaForFilm } from '@/film'; +import { generateMetaForFilm } from '@/film'; import FilmOverview from '@/film/FilmOverview'; import { getPhotosFilmDataCached } from '@/film/data'; import { Metadata } from 'next/types'; @@ -20,7 +20,7 @@ export const generateStaticParams = staticallyGenerateCategoryIfConfigured( ); interface FilmProps { - params: Promise<{ film: FilmSimulation }> + params: Promise<{ film: string }> } export async function generateMetadata({ diff --git a/src/app/paths.ts b/src/app/paths.ts index 311f1da8..b275a832 100644 --- a/src/app/paths.ts +++ b/src/app/paths.ts @@ -2,7 +2,6 @@ import { Photo } from '@/photo'; import { PhotoSetCategory } from '@/category'; import { BASE_URL, GRID_HOMEPAGE_ENABLED } from './config'; import { Camera } from '@/camera'; -import { FilmSimulation } from '@/film'; import { parameterize } from '@/utility/string'; import { TAG_HIDDEN } from '@/tag'; import { Lens } from '@/lens'; @@ -151,7 +150,7 @@ export const pathForTag = (tag: string) => export const pathForCamera = ({ make, model }: Camera) => `${PREFIX_CAMERA}/${parameterize(make)}/${parameterize(model)}`; -export const pathForFilm = (film: FilmSimulation) => +export const pathForFilm = (film: string) => `${PREFIX_FILM}/${film}`; export const pathForLens = ({ make, model }: Lens) => @@ -177,7 +176,7 @@ export const absolutePathForCamera= (camera: Camera) => export const absolutePathForLens= (lens: Lens) => `${BASE_URL}${pathForLens(lens)}`; -export const absolutePathForFilm = (film: FilmSimulation) => +export const absolutePathForFilm = (film: string) => `${BASE_URL}${pathForFilm(film)}`; export const absolutePathForRecipe = (recipe: string) => @@ -198,7 +197,7 @@ export const absolutePathForCameraImage= (camera: Camera) => export const absolutePathForLensImage= (lens: Lens) => `${absolutePathForLens(lens)}/image`; -export const absolutePathForFilmImage = (film: FilmSimulation) => +export const absolutePathForFilmImage = (film: string) => `${absolutePathForFilm(film)}/image`; export const absolutePathForRecipeImage = (recipe: string) => @@ -308,7 +307,7 @@ export const getPathComponents = (pathname = ''): { const cameraModel = pathname.match( new RegExp(`^${PREFIX_CAMERA}/[^/]+/([^/]+)`))?.[1]; const film = pathname.match( - new RegExp(`^${PREFIX_FILM}/([^/]+)`))?.[1] as FilmSimulation; + new RegExp(`^${PREFIX_FILM}/([^/]+)`))?.[1] as string; const focalString = pathname.match( new RegExp(`^${PREFIX_FOCAL_LENGTH}/([0-9]+)mm`))?.[1]; diff --git a/src/category/index.ts b/src/category/index.ts index 698330cc..4c70238a 100644 --- a/src/category/index.ts +++ b/src/category/index.ts @@ -1,7 +1,7 @@ import { Photo } from '../photo'; import { Camera, Cameras } from '@/camera'; import { PhotoDateRange } from '../photo'; -import { FilmSimulation, Films } from '@/film'; +import { Films } from '@/film'; import { Lens, Lenses } from '@/lens'; import { Tags } from '@/tag'; import { FocalLengths } from '@/focal'; @@ -39,7 +39,7 @@ export interface PhotoSetCategory { lens?: Lens tag?: string recipe?: string - film?: FilmSimulation + film?: string focal?: number } diff --git a/src/cmdk/CommandKClient.tsx b/src/cmdk/CommandKClient.tsx index aaddd55d..42fd5501 100644 --- a/src/cmdk/CommandKClient.tsx +++ b/src/cmdk/CommandKClient.tsx @@ -59,7 +59,6 @@ import * as VisuallyHidden from '@radix-ui/react-visually-hidden'; import InsightsIndicatorDot from '@/admin/insights/InsightsIndicatorDot'; import { PhotoSetCategories } from '@/category'; import { formatCameraText } from '@/camera'; -import { labelForFilm } from '@/platforms/fujifilm/simulation'; import { formatFocalLength } from '@/focal'; import { formatRecipe } from '@/recipe'; import IconLens from '../components/icons/IconLens'; @@ -73,6 +72,7 @@ import IconFilm from '../components/icons/IconFilm'; import IconLock from '../components/icons/IconLock'; import useVisualViewportHeight from '@/utility/useVisualViewport'; import useMaskedScroll from '../components/useMaskedScroll'; +import { labelForFilm } from '@/film'; const DIALOG_TITLE = 'Global Command-K Menu'; const DIALOG_DESCRIPTION = 'For searching photos, views, and settings'; diff --git a/src/film/FilmHeader.tsx b/src/film/FilmHeader.tsx index ee2b14f6..5e101df8 100644 --- a/src/film/FilmHeader.tsx +++ b/src/film/FilmHeader.tsx @@ -1,5 +1,5 @@ import { Photo, PhotoDateRange } from '@/photo'; -import { FilmSimulation, descriptionForFilmPhotos } from '.'; +import { descriptionForFilmPhotos } from '.'; import PhotoHeader from '@/photo/PhotoHeader'; import PhotoFilm from '@/film/PhotoFilm'; @@ -11,7 +11,7 @@ export default function FilmHeader({ count, dateRange, }: { - film: FilmSimulation + film: string photos: Photo[] selectedPhoto?: Photo indexNumber?: number diff --git a/src/film/FilmOGTile.tsx b/src/film/FilmOGTile.tsx index 19f7843a..399f7d08 100644 --- a/src/film/FilmOGTile.tsx +++ b/src/film/FilmOGTile.tsx @@ -4,11 +4,7 @@ import { pathForFilm, } from '@/app/paths'; import OGTile from '@/components/OGTile'; -import { - FilmSimulation, - descriptionForFilmPhotos, - titleForFilm, -} from '.'; +import { descriptionForFilmPhotos, titleForFilm } from '.'; export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed'; @@ -23,7 +19,7 @@ export default function FilmOGTile({ count, dateRange, }: { - film: FilmSimulation + film: string photos: Photo[] loadingState?: OGLoadingState onLoad?: () => void diff --git a/src/film/FilmOverview.tsx b/src/film/FilmOverview.tsx index 1ff9e59a..6f5f579d 100644 --- a/src/film/FilmOverview.tsx +++ b/src/film/FilmOverview.tsx @@ -1,6 +1,5 @@ import { Photo, PhotoDateRange } from '@/photo'; import FilmHeader from './FilmHeader'; -import { FilmSimulation } from '.'; import PhotoGridContainer from '@/photo/PhotoGridContainer'; export default function FilmOverview({ @@ -10,7 +9,7 @@ export default function FilmOverview({ dateRange, animateOnFirstLoadOnly, }: { - film: FilmSimulation, + film: string, photos: Photo[], count: number, dateRange?: PhotoDateRange, diff --git a/src/film/FilmShareModal.tsx b/src/film/FilmShareModal.tsx index 1c5b3a3c..9fdff02c 100644 --- a/src/film/FilmShareModal.tsx +++ b/src/film/FilmShareModal.tsx @@ -2,7 +2,7 @@ import { absolutePathForFilm } from '@/app/paths'; import { PhotoSetAttributes } from '../category'; import ShareModal from '@/share/ShareModal'; import FilmOGTile from './FilmOGTile'; -import { FilmSimulation, shareTextForFilm } from '.'; +import { shareTextForFilm } from '.'; export default function FilmShareModal({ film, @@ -10,7 +10,7 @@ export default function FilmShareModal({ count, dateRange, }: { - film: FilmSimulation + film: string } & PhotoSetAttributes) { return ( Promise.all([ diff --git a/src/film/index.tsx b/src/film/index.tsx index 3433e99d..30426df7 100644 --- a/src/film/index.tsx +++ b/src/film/index.tsx @@ -9,24 +9,36 @@ import { absolutePathForFilmImage, } from '@/app/paths'; import { - FILM_SIMULATION_FORM_INPUT_OPTIONS, - FujifilmSimulation, - labelForFilm, + FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS, + labelForFujifilmSimulation, } from '@/platforms/fujifilm/simulation'; -import { formatCount } from '@/utility/string'; +import { deparameterize, formatCount } from '@/utility/string'; import { formatCountDescriptive } from '@/utility/string'; import { AnnotatedTag } from '@/photo/form'; import PhotoFilmIcon from './PhotoFilmIcon'; -export type FilmSimulation = FujifilmSimulation; - export type FilmWithCount = { - film: FilmSimulation + film: string count: number } export type Films = FilmWithCount[] +export const labelForFilm = (film: string) => { + // Use Fujifilm simulation text when recognized + const simulationLabel = labelForFujifilmSimulation(film as any); + if (simulationLabel) { + return simulationLabel; + } else { + const filmFormatted = deparameterize(film); + return { + small: filmFormatted, + medium: filmFormatted, + large: filmFormatted, + }; + } +}; + export const sortFilms = ( films: Films, ) => films.sort(sortFilmsWithCount); @@ -41,7 +53,7 @@ export const sortFilmsWithCount = ( }; export const titleForFilm = ( - film: FilmSimulation, + film: string, photos: Photo[], explicitCount?: number, ) => [ @@ -50,9 +62,9 @@ export const titleForFilm = ( ].join(' '); export const shareTextForFilm = ( - film: FilmSimulation, + film: string, ) => - `Photos shot on Fujifilm ${labelForFilm(film).large}`; + `Photos shot on ${labelForFilm(film).large}`; export const descriptionForFilmPhotos = ( photos: Photo[], @@ -69,7 +81,7 @@ export const descriptionForFilmPhotos = ( ); export const generateMetaForFilm = ( - film: FilmSimulation, + film: string, photos: Photo[], explicitCount?: number, explicitDateRange?: PhotoDateRange, @@ -93,13 +105,13 @@ export const convertFilmsForForm = ( includeAllFujifilmSimulations?: boolean, ): AnnotatedTag[] => { const films = includeAllFujifilmSimulations - ? FILM_SIMULATION_FORM_INPUT_OPTIONS + ? FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS .map(({ value }) => ({ value } as AnnotatedTag)) : []; _films.forEach(({ film, count }) => { const index = films.findIndex(f => f.value === film); - const fujifilmSimulation = FILM_SIMULATION_FORM_INPUT_OPTIONS + const fujifilmSimulation = FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS .find(f => f.value === film); const meta = { annotation: formatCount(count), diff --git a/src/image-response/FilmImageResponse.tsx b/src/image-response/FilmImageResponse.tsx index 68bb0cf5..2eb76d7c 100644 --- a/src/image-response/FilmImageResponse.tsx +++ b/src/image-response/FilmImageResponse.tsx @@ -2,13 +2,10 @@ import { Photo } from '../photo'; import ImageCaption from './components/ImageCaption'; import ImagePhotoGrid from './components/ImagePhotoGrid'; import ImageContainer from './components/ImageContainer'; -import { - labelForFilm, -} from '@/platforms/fujifilm/simulation'; import PhotoFilmIcon from '@/film/PhotoFilmIcon'; -import { FilmSimulation } from '@/film'; import { NextImageSize } from '@/platforms/next-image'; +import { labelForFilm } from '@/film'; export default function FilmImageResponse({ film, @@ -17,7 +14,7 @@ export default function FilmImageResponse({ height, fontFamily, }: { - film: FilmSimulation, + film: string, photos: Photo[] width: NextImageSize height: number diff --git a/src/image-response/RecipeImageResponse.tsx b/src/image-response/RecipeImageResponse.tsx index c666839e..a2af4863 100644 --- a/src/image-response/RecipeImageResponse.tsx +++ b/src/image-response/RecipeImageResponse.tsx @@ -6,7 +6,9 @@ import type { NextImageSize } from '@/platforms/next-image'; import { formatTag } from '@/tag'; import { generateRecipeText, getPhotoWithRecipeFromPhotos } from '@/recipe'; import PhotoFilmIcon from '@/film/PhotoFilmIcon'; -import { isStringFilmSimulationLabel } from '@/platforms/fujifilm/simulation'; +import { + isStringFujifilmSimulationLabel, +} from '@/platforms/fujifilm/simulation'; import IconRecipe from '@/components/icons/IconRecipe'; const MAX_RECIPE_LINES = 8; @@ -109,7 +111,7 @@ export default function RecipeImageResponse({ flexGrow: 1, }}> {text} - {isStringFilmSimulationLabel(text) && film && + {isStringFujifilmSimulationLabel(text) && film &&
export const getPhotosNeedingRecipeTitleCountAction = async ( recipeData: string, - film: FilmSimulation, + film: string, photoIdToExclude?: string, ) => runAuthenticatedAdminServerAction(async () => diff --git a/src/photo/db/query.ts b/src/photo/db/query.ts index d6f5ad0f..cf5ff252 100644 --- a/src/photo/db/query.ts +++ b/src/photo/db/query.ts @@ -13,7 +13,7 @@ import { } from '@/photo'; import { Cameras, createCameraKey } from '@/camera'; import { Tags } from '@/tag'; -import { FilmSimulation, Films } from '@/film'; +import { Films } from '@/film'; import { ADMIN_SQL_DEBUG_ENABLED } from '@/app/config'; import { GetPhotosOptions, @@ -380,7 +380,7 @@ export const getUniqueRecipes = async () => export const getRecipeTitleForData = async ( data: string | object, - film: FilmSimulation, + film: string, ) => // Includes legacy check on pre-stringified JSON safelyQueryPhotos(() => sql` @@ -395,7 +395,7 @@ export const getRecipeTitleForData = async ( export const getPhotosNeedingRecipeTitleCount = async ( data: string, - film: FilmSimulation, + film: string, photoIdToExclude?: string, ) => safelyQueryPhotos(() => sql` @@ -411,7 +411,7 @@ export const getPhotosNeedingRecipeTitleCount = async ( export const updateAllMatchingRecipeTitles = ( title: string, data: string, - film: FilmSimulation, + film: string, ) => safelyQueryPhotos(() => sql` UPDATE photos @@ -430,7 +430,7 @@ export const getUniqueFilms = async () => ORDER BY film ASC `.then(({ rows }): Films => rows .map(({ film, count }) => ({ - film: film as FilmSimulation, + film, count: parseInt(count, 10), }))) , 'getUniqueFilms'); diff --git a/src/photo/form/ApplyRecipesGloballyCheckbox.tsx b/src/photo/form/ApplyRecipesGloballyCheckbox.tsx index 6bd5f7ce..38754a77 100644 --- a/src/photo/form/ApplyRecipesGloballyCheckbox.tsx +++ b/src/photo/form/ApplyRecipesGloballyCheckbox.tsx @@ -1,7 +1,6 @@ import FieldSetWithStatus from '@/components/FieldSetWithStatus'; import { ComponentProps, useEffect, useState } from 'react'; import { getPhotosNeedingRecipeTitleCountAction } from '../actions'; -import { FilmSimulation } from '@/film'; export default function ApplyRecipeTitleGloballyCheckbox({ photoId, @@ -16,7 +15,7 @@ export default function ApplyRecipeTitleGloballyCheckbox({ recipeTitle?: string hasRecipeTitleChanged?: boolean recipeData?: string - film?: FilmSimulation + film?: string onMatchResults: (didFindMatchingPhotos: boolean) => void }) { const [matchingPhotosCount, setMatchingPhotosCount] = useState(); diff --git a/src/photo/form/PhotoForm.tsx b/src/photo/form/PhotoForm.tsx index 65444b96..75ce5d8c 100644 --- a/src/photo/form/PhotoForm.tsx +++ b/src/photo/form/PhotoForm.tsx @@ -41,7 +41,7 @@ import ErrorNote from '@/components/ErrorNote'; import { convertRecipesForForm, Recipes } from '@/recipe'; import deepEqual from 'fast-deep-equal/es6/react'; import ApplyRecipeTitleGloballyCheckbox from './ApplyRecipesGloballyCheckbox'; -import { convertFilmsForForm, Films, FilmSimulation } from '@/film'; +import { convertFilmsForForm, Films } from '@/film'; import IconFavs from '@/components/icons/IconFavs'; import IconHidden from '@/components/icons/IconHidden'; import { isMakeFujifilm } from '@/platforms/fujifilm'; @@ -431,7 +431,7 @@ export default function PhotoForm({ hasRecipeTitleChanged={ changedFormKeys.includes('recipeTitle')} recipeData={formData.recipeData} - film={formData.film as FilmSimulation} + film={formData.film} onMatchResults={onMatchResults} {...fieldProps} />; diff --git a/src/photo/form/index.ts b/src/photo/form/index.ts index 716fd1bb..3b4f1633 100644 --- a/src/photo/form/index.ts +++ b/src/photo/form/index.ts @@ -16,12 +16,12 @@ import { import { roundToNumber } from '@/utility/number'; import { convertStringToArray, parameterize } from '@/utility/string'; import { generateNanoid } from '@/utility/nanoid'; -import { FilmSimulation } from '@/film'; import { GEO_PRIVACY_ENABLED } from '@/app/config'; import { TAG_FAVS, getValidationMessageForTags } from '@/tag'; import { MAKE_FUJIFILM } from '@/platforms/fujifilm'; import { FujifilmRecipe } from '@/platforms/fujifilm/recipe'; import { ReactNode } from 'react'; +import { FujifilmSimulation } from '@/platforms/fujifilm/simulation'; type VirtualFields = 'favorite' | @@ -276,7 +276,7 @@ export const convertPhotoToFormData = (photo: Photo): PhotoFormData => { export const convertExifToFormData = ( data: ExifData, - film?: FilmSimulation, + film?: FujifilmSimulation, recipeData?: FujifilmRecipe, ): Omit< Record, @@ -347,7 +347,7 @@ export const convertFormDataToPhotoDbInsert = ( return { ...(photoForm as PhotoFormData & { - film?: FilmSimulation + film?: FujifilmSimulation recipeData?: FujifilmRecipe }), ...!photoForm.id && { id: generateNanoid() }, diff --git a/src/photo/index.ts b/src/photo/index.ts index 1b0d6a33..3e25eb9d 100644 --- a/src/photo/index.ts +++ b/src/photo/index.ts @@ -1,6 +1,6 @@ import { formatFocalLength } from '@/focal'; import { getNextImageUrlForRequest } from '@/platforms/next-image'; -import { FilmSimulation, photoHasFilmData } from '@/film'; +import { photoHasFilmData } from '@/film'; import { HIGH_DENSITY_GRID, IS_PREVIEW, @@ -22,6 +22,7 @@ import camelcaseKeys from 'camelcase-keys'; import { isBefore } from 'date-fns'; import type { Metadata } from 'next'; import { FujifilmRecipe } from '@/platforms/fujifilm/recipe'; +import { FujifilmSimulation } from '@/platforms/fujifilm/simulation'; // INFINITE SCROLL: FEED export const INFINITE_SCROLL_FEED_INITIAL = @@ -65,7 +66,7 @@ export interface PhotoExif { exposureCompensation?: number latitude?: number longitude?: number - film?: FilmSimulation + film?: FujifilmSimulation recipeData?: string takenAt?: string takenAtNaive?: string diff --git a/src/photo/server.ts b/src/photo/server.ts index 22ab8376..b09a50fa 100644 --- a/src/photo/server.ts +++ b/src/photo/server.ts @@ -7,11 +7,11 @@ import { convertFormDataToPhotoDbInsert, } from '@/photo/form'; import { + FujifilmSimulation, getFujifilmSimulationFromMakerNote, } from '@/platforms/fujifilm/simulation'; import { ExifData, ExifParserFactory } from 'ts-exif-parser'; import { PhotoFormData } from './form'; -import { FilmSimulation } from '@/film'; import sharp, { Sharp } from 'sharp'; import { GEO_PRIVACY_ENABLED, @@ -58,7 +58,7 @@ export const extractImageDataFromBlobPath = async ( const extension = getExtensionFromStorageUrl(url); let exifData: ExifData | undefined; - let film: FilmSimulation | undefined; + let film: FujifilmSimulation | undefined; let recipe: FujifilmRecipe | undefined; let blurData: string | undefined; let imageResizedBase64: string | undefined; diff --git a/src/platforms/fujifilm/simulation.ts b/src/platforms/fujifilm/simulation.ts index 59b82035..ae6d1026 100644 --- a/src/platforms/fujifilm/simulation.ts +++ b/src/platforms/fujifilm/simulation.ts @@ -80,7 +80,7 @@ interface FujifilmSimulationLabel { large: string } -const FILM_SIMULATION_LABELS: Record< +const FUJIFILM_SIMULATION_LABELS: Record< FujifilmSimulation, FujifilmSimulationLabel > = { @@ -206,30 +206,30 @@ const FILM_SIMULATION_LABELS: Record< }, }; -export const FILM_SIMULATION_FORM_INPUT_OPTIONS = Object - .entries(FILM_SIMULATION_LABELS) +export const FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS = Object + .entries(FUJIFILM_SIMULATION_LABELS) .map(([value, label]) => ( { value, label: label.large } as { value: FujifilmSimulation, label: string } )) .sort((a, b) => a.label.localeCompare(b.label)); -const ALL_POSSIBLE_FILM_SIMULATION_LABELS = Object - .values(FILM_SIMULATION_LABELS) +const ALL_POSSIBLE_FUJIFILM_SIMULATION_LABELS = Object + .values(FUJIFILM_SIMULATION_LABELS) .flatMap(({ small, medium, large }) => [ small.toLocaleLowerCase(), medium.toLocaleLowerCase(), large.toLocaleLowerCase(), ]); -export const isStringFilmSimulation = (film?: string) => - film && Object.keys(FILM_SIMULATION_LABELS).includes(film); +export const isStringFujifilmSimulation = (film?: string) => + film && Object.keys(FUJIFILM_SIMULATION_LABELS).includes(film); -export const isStringFilmSimulationLabel = (film: string) => - ALL_POSSIBLE_FILM_SIMULATION_LABELS.includes(film.toLocaleLowerCase()); +export const isStringFujifilmSimulationLabel = (film: string) => + ALL_POSSIBLE_FUJIFILM_SIMULATION_LABELS.includes(film.toLocaleLowerCase()); -export const labelForFilm = (film: FujifilmSimulation) => - FILM_SIMULATION_LABELS[film]; +export const labelForFujifilmSimulation = (film: FujifilmSimulation) => + FUJIFILM_SIMULATION_LABELS[film]; export const getFujifilmSimulationFromMakerNote = ( bytes: Buffer, diff --git a/src/recipe/PhotoRecipeOverlay.tsx b/src/recipe/PhotoRecipeOverlay.tsx index 1a140874..e3c02eb8 100644 --- a/src/recipe/PhotoRecipeOverlay.tsx +++ b/src/recipe/PhotoRecipeOverlay.tsx @@ -15,11 +15,11 @@ import { generateRecipeText, RecipeProps, } from '.'; -import { labelForFilm } from '@/platforms/fujifilm/simulation'; import { TbChecklist } from 'react-icons/tb'; import CopyButton from '@/components/CopyButton'; import { pathForRecipe } from '@/app/paths'; import LinkWithStatus from '@/components/LinkWithStatus'; +import { labelForFilm } from '@/film'; export default function PhotoRecipeOverlay({ ref, diff --git a/src/recipe/index.ts b/src/recipe/index.ts index 0d6f102d..616e1849 100644 --- a/src/recipe/index.ts +++ b/src/recipe/index.ts @@ -7,8 +7,7 @@ import { formatCountDescriptive, } from '@/utility/string'; import { FujifilmRecipe } from '@/platforms/fujifilm/recipe'; -import { FilmSimulation } from '@/film'; -import { labelForFilm } from '@/platforms/fujifilm/simulation'; +import { labelForFilm } from '@/film'; export type RecipeWithCount = { recipe: string @@ -20,7 +19,7 @@ export type Recipes = RecipeWithCount[] export interface RecipeProps { title?: string recipe: FujifilmRecipe - film: FilmSimulation + film: string iso?: string exposure?: string }