Generalize film type and labeling strategy
This commit is contained in:
parent
087a5e223c
commit
f9db50e41a
@ -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,
|
||||
]);
|
||||
|
||||
@ -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:
|
||||
</div>
|
||||
<PhotoFilm
|
||||
film={FILM_SIMULATION_FORM_INPUT_OPTIONS[index].value}
|
||||
film={FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS[index].value}
|
||||
type="icon-first"
|
||||
/>
|
||||
<div className="mt-4 text-dim relative">
|
||||
|
||||
@ -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 (
|
||||
<div className="space-y-1 my-12">
|
||||
{FILM_SIMULATION_FORM_INPUT_OPTIONS.map(({ value }) =>
|
||||
{FUJIFILM_SIMULATION_FORM_INPUT_OPTIONS.map(({ value }) =>
|
||||
<div key={value}>
|
||||
<PhotoFilm
|
||||
film={value}
|
||||
|
||||
@ -11,7 +11,6 @@ import {
|
||||
absolutePathForPhotoImage,
|
||||
} from '@/app/paths';
|
||||
import PhotoDetailPage from '@/photo/PhotoDetailPage';
|
||||
import { FilmSimulation } from '@/film';
|
||||
import {
|
||||
getPhotosMetaCached,
|
||||
getPhotosNearIdCached,
|
||||
@ -20,7 +19,7 @@ import { cache } from 'react';
|
||||
|
||||
const getPhotosNearIdCachedCached = cache((
|
||||
photoId: string,
|
||||
film: FilmSimulation,
|
||||
film: string,
|
||||
) =>
|
||||
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({
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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({
|
||||
|
||||
@ -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];
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 (
|
||||
<ShareModal
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import { labelForFilm } from '@/platforms/fujifilm/simulation';
|
||||
import PhotoFilmIcon from './PhotoFilmIcon';
|
||||
import { pathForFilm } from '@/app/paths';
|
||||
import { FilmSimulation } from '.';
|
||||
import { FujifilmRecipe } from '@/platforms/fujifilm/recipe';
|
||||
import EntityLink, {
|
||||
EntityLinkExternalProps,
|
||||
} from '@/components/primitives/EntityLink';
|
||||
import clsx from 'clsx/lite';
|
||||
import { labelForFilm } from '.';
|
||||
|
||||
export default function PhotoFilm({
|
||||
film,
|
||||
@ -16,7 +15,7 @@ export default function PhotoFilm({
|
||||
countOnHover,
|
||||
...props
|
||||
}: {
|
||||
film: FilmSimulation
|
||||
film: string
|
||||
countOnHover?: number
|
||||
recipe?: FujifilmRecipe
|
||||
} & EntityLinkExternalProps) {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/* eslint-disable max-len */
|
||||
import { labelForFilm } from '@/platforms/fujifilm/simulation';
|
||||
import { CSSProperties, useMemo } from 'react';
|
||||
import { FilmSimulation } from '.';
|
||||
import { labelForFilm } from '.';
|
||||
|
||||
const INTRINSIC_WIDTH = 28;
|
||||
const INTRINSIC_WIDTH_FALLBACK = 16;
|
||||
@ -17,7 +16,7 @@ export default function PhotoFilmIcon({
|
||||
className,
|
||||
style,
|
||||
}: {
|
||||
film?: FilmSimulation
|
||||
film?: string
|
||||
height?: number
|
||||
className?: string
|
||||
style?: CSSProperties
|
||||
|
||||
@ -2,13 +2,12 @@ import {
|
||||
getPhotosCached,
|
||||
getPhotosMetaCached,
|
||||
} from '@/photo/cache';
|
||||
import { FilmSimulation } from '.';
|
||||
|
||||
export const getPhotosFilmDataCached = ({
|
||||
film,
|
||||
limit,
|
||||
}: {
|
||||
film: FilmSimulation,
|
||||
film: string,
|
||||
limit?: number,
|
||||
}) =>
|
||||
Promise.all([
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 &&
|
||||
<div tw="flex">
|
||||
<PhotoFilmIcon
|
||||
film={film}
|
||||
|
||||
@ -60,7 +60,6 @@ import { convertUploadToPhoto } from './storage';
|
||||
import { UrlAddStatus } from '@/admin/AdminUploadsClient';
|
||||
import { convertStringToArray } from '@/utility/string';
|
||||
import { after } from 'next/server';
|
||||
import { FilmSimulation } from '@/film';
|
||||
|
||||
// Private actions
|
||||
|
||||
@ -315,7 +314,7 @@ export const renamePhotoTagGloballyAction = async (formData: FormData) =>
|
||||
|
||||
export const getPhotosNeedingRecipeTitleCountAction = async (
|
||||
recipeData: string,
|
||||
film: FilmSimulation,
|
||||
film: string,
|
||||
photoIdToExclude?: string,
|
||||
) =>
|
||||
runAuthenticatedAdminServerAction(async () =>
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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<number>();
|
||||
|
||||
@ -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}
|
||||
/>;
|
||||
|
||||
@ -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<keyof PhotoExif, string | undefined>,
|
||||
@ -347,7 +347,7 @@ export const convertFormDataToPhotoDbInsert = (
|
||||
|
||||
return {
|
||||
...(photoForm as PhotoFormData & {
|
||||
film?: FilmSimulation
|
||||
film?: FujifilmSimulation
|
||||
recipeData?: FujifilmRecipe
|
||||
}),
|
||||
...!photoForm.id && { id: generateNanoid() },
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user