Switch film chooser to tag input
This commit is contained in:
parent
09d7a07722
commit
5f992788f2
@ -1,6 +1,7 @@
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
getPhotoNoStore,
|
||||
getUniqueFilmsCached,
|
||||
getUniqueRecipesCached,
|
||||
getUniqueTagsCached,
|
||||
} from '@/photo/cache';
|
||||
@ -10,7 +11,6 @@ import {
|
||||
AI_TEXT_GENERATION_ENABLED,
|
||||
BLUR_ENABLED,
|
||||
IS_PREVIEW,
|
||||
SHOW_RECIPES,
|
||||
} from '@/app/config';
|
||||
import { blurImageFromUrl, resizeImageFromUrl } from '@/photo/server';
|
||||
import { getNextImageUrlForManipulation } from '@/platforms/next-image';
|
||||
@ -26,11 +26,15 @@ export default async function PhotoEditPage({
|
||||
|
||||
if (!photo) { redirect(PATH_ADMIN); }
|
||||
|
||||
const uniqueTags = await getUniqueTagsCached();
|
||||
|
||||
const uniqueRecipes = SHOW_RECIPES
|
||||
? await getUniqueRecipesCached()
|
||||
: [];
|
||||
const [
|
||||
uniqueTags,
|
||||
uniqueRecipes,
|
||||
uniqueFilms,
|
||||
] = await Promise.all([
|
||||
getUniqueTagsCached(),
|
||||
getUniqueRecipesCached(),
|
||||
getUniqueFilmsCached(),
|
||||
]);
|
||||
|
||||
const hasAiTextGeneration = AI_TEXT_GENERATION_ENABLED;
|
||||
|
||||
@ -52,6 +56,7 @@ export default async function PhotoEditPage({
|
||||
photo,
|
||||
uniqueTags,
|
||||
uniqueRecipes,
|
||||
uniqueFilms,
|
||||
hasAiTextGeneration,
|
||||
imageThumbnailBase64,
|
||||
blurData,
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
import { PATH_ADMIN } from '@/app/paths';
|
||||
import { extractImageDataFromBlobPath } from '@/photo/server';
|
||||
import { redirect } from 'next/navigation';
|
||||
import { getUniqueRecipesCached, getUniqueTagsCached } from '@/photo/cache';
|
||||
import {
|
||||
getUniqueFilmsCached,
|
||||
getUniqueRecipesCached,
|
||||
getUniqueTagsCached,
|
||||
} from '@/photo/cache';
|
||||
import UploadPageClient from '@/photo/UploadPageClient';
|
||||
import {
|
||||
AI_TEXT_AUTO_GENERATED_FIELDS,
|
||||
@ -45,10 +49,12 @@ export default async function UploadPage({ params }: Params) {
|
||||
const [
|
||||
uniqueTags,
|
||||
uniqueRecipes,
|
||||
uniqueFilms,
|
||||
recipeTitle,
|
||||
] = await Promise.all([
|
||||
getUniqueTagsCached(),
|
||||
getUniqueRecipesCached(),
|
||||
getUniqueFilmsCached(),
|
||||
formDataFromExif?.recipeData && formDataFromExif.film
|
||||
? getRecipeTitleForData(
|
||||
formDataFromExif.recipeData,
|
||||
@ -72,6 +78,7 @@ export default async function UploadPage({ params }: Params) {
|
||||
formDataFromExif,
|
||||
uniqueTags,
|
||||
uniqueRecipes,
|
||||
uniqueFilms,
|
||||
hasAiTextGeneration,
|
||||
textFieldsToAutoGenerate,
|
||||
imageThumbnailBase64,
|
||||
|
||||
@ -12,6 +12,8 @@ import {
|
||||
FujifilmSimulation,
|
||||
labelForFilm,
|
||||
} from '@/platforms/fujifilm/simulation';
|
||||
import { formatCount } from '@/utility/string';
|
||||
import { formatCountDescriptive } from '@/utility/string';
|
||||
|
||||
export type FilmSimulation = FujifilmSimulation;
|
||||
|
||||
@ -82,3 +84,11 @@ export const generateMetaForFilm = (
|
||||
|
||||
export const photoHasFilmData = (photo: Photo) =>
|
||||
Boolean(photo.film);
|
||||
|
||||
export const convertFilmsForForm = (films: Films = []) =>
|
||||
sortFilms(films)
|
||||
.map(({ film, count }) => ({
|
||||
value: film,
|
||||
annotation: formatCount(count),
|
||||
annotationAria: formatCountDescriptive(count),
|
||||
}));
|
||||
|
||||
@ -11,11 +11,13 @@ import usePhotoFormParent from './form/usePhotoFormParent';
|
||||
import ExifCaptureButton from '@/admin/ExifCaptureButton';
|
||||
import { useState } from 'react';
|
||||
import { Recipes } from '@/recipe';
|
||||
import { Films } from '@/film';
|
||||
|
||||
export default function PhotoEditPageClient({
|
||||
photo,
|
||||
uniqueTags,
|
||||
uniqueRecipes,
|
||||
uniqueFilms,
|
||||
hasAiTextGeneration,
|
||||
imageThumbnailBase64,
|
||||
blurData,
|
||||
@ -23,6 +25,7 @@ export default function PhotoEditPageClient({
|
||||
photo: Photo
|
||||
uniqueTags: Tags
|
||||
uniqueRecipes: Recipes
|
||||
uniqueFilms: Films
|
||||
hasAiTextGeneration: boolean
|
||||
imageThumbnailBase64: string
|
||||
blurData: string
|
||||
@ -71,6 +74,7 @@ export default function PhotoEditPageClient({
|
||||
updatedBlurData={blurData}
|
||||
uniqueTags={uniqueTags}
|
||||
uniqueRecipes={uniqueRecipes}
|
||||
uniqueFilms={uniqueFilms}
|
||||
aiContent={hasAiTextGeneration ? aiContent : undefined}
|
||||
onTitleChange={setUpdatedTitle}
|
||||
onTextContentChange={setHasTextContent}
|
||||
|
||||
@ -10,12 +10,14 @@ import AiButton from './ai/AiButton';
|
||||
import { AiAutoGeneratedField } from './ai';
|
||||
import { useMemo } from 'react';
|
||||
import { Recipes } from '@/recipe';
|
||||
import { Films } from '@/film';
|
||||
|
||||
export default function UploadPageClient({
|
||||
blobId,
|
||||
formDataFromExif,
|
||||
uniqueTags,
|
||||
uniqueRecipes,
|
||||
uniqueFilms,
|
||||
hasAiTextGeneration,
|
||||
textFieldsToAutoGenerate,
|
||||
imageThumbnailBase64,
|
||||
@ -25,6 +27,7 @@ export default function UploadPageClient({
|
||||
formDataFromExif: Partial<PhotoFormData>
|
||||
uniqueTags: Tags
|
||||
uniqueRecipes: Recipes
|
||||
uniqueFilms: Films
|
||||
hasAiTextGeneration?: boolean
|
||||
textFieldsToAutoGenerate?: AiAutoGeneratedField[],
|
||||
imageThumbnailBase64?: string
|
||||
@ -65,6 +68,7 @@ export default function UploadPageClient({
|
||||
initialPhotoForm={initialPhotoForm}
|
||||
uniqueTags={uniqueTags}
|
||||
uniqueRecipes={uniqueRecipes}
|
||||
uniqueFilms={uniqueFilms}
|
||||
aiContent={hasAiTextGeneration ? aiContent : undefined}
|
||||
shouldStripGpsData={shouldStripGpsData}
|
||||
onTitleChange={setUpdatedTitle}
|
||||
|
||||
@ -41,13 +41,9 @@ import ErrorNote from '@/components/ErrorNote';
|
||||
import { convertRecipesForForm, Recipes } from '@/recipe';
|
||||
import deepEqual from 'fast-deep-equal/es6/react';
|
||||
import ApplyRecipeTitleGloballyCheckbox from './ApplyRecipesGloballyCheckbox';
|
||||
import { FilmSimulation } from '@/film';
|
||||
import { convertFilmsForForm, Films, FilmSimulation } from '@/film';
|
||||
import IconFavs from '@/components/icons/IconFavs';
|
||||
import IconHidden from '@/components/icons/IconHidden';
|
||||
import { MAKE_FUJIFILM } from '@/platforms/fujifilm';
|
||||
import {
|
||||
FILM_SIMULATION_FORM_INPUT_OPTIONS,
|
||||
} from '@/platforms/fujifilm/simulation';
|
||||
|
||||
const THUMBNAIL_SIZE = 300;
|
||||
|
||||
@ -58,6 +54,7 @@ export default function PhotoForm({
|
||||
updatedBlurData,
|
||||
uniqueTags,
|
||||
uniqueRecipes,
|
||||
uniqueFilms,
|
||||
aiContent,
|
||||
shouldStripGpsData,
|
||||
onTitleChange,
|
||||
@ -70,6 +67,7 @@ export default function PhotoForm({
|
||||
updatedBlurData?: string
|
||||
uniqueTags?: Tags
|
||||
uniqueRecipes?: Recipes
|
||||
uniqueFilms?: Films
|
||||
aiContent?: AiContent
|
||||
shouldStripGpsData?: boolean
|
||||
onTitleChange?: (updatedTitle: string) => void
|
||||
@ -330,6 +328,7 @@ export default function PhotoForm({
|
||||
{FORM_METADATA_ENTRIES(
|
||||
convertTagsForForm(uniqueTags),
|
||||
convertRecipesForForm(uniqueRecipes),
|
||||
convertFilmsForForm(uniqueFilms),
|
||||
aiContent !== undefined,
|
||||
shouldStripGpsData,
|
||||
)
|
||||
@ -412,18 +411,6 @@ export default function PhotoForm({
|
||||
};
|
||||
|
||||
switch (key) {
|
||||
case 'film':
|
||||
return formData.make === MAKE_FUJIFILM
|
||||
? <FieldSetWithStatus
|
||||
key={key}
|
||||
{...fieldProps}
|
||||
selectOptions={FILM_SIMULATION_FORM_INPUT_OPTIONS}
|
||||
selectOptionsDefaultLabel="Unknown"
|
||||
/>
|
||||
: <FieldSetWithStatus
|
||||
key={key}
|
||||
{...fieldProps}
|
||||
/>;
|
||||
case 'applyRecipeTitleGlobally':
|
||||
return <ApplyRecipeTitleGloballyCheckbox
|
||||
key={key}
|
||||
|
||||
@ -80,6 +80,7 @@ const STRING_MAX_LENGTH_LONG = 1000;
|
||||
const FORM_METADATA = (
|
||||
tagOptions?: AnnotatedTag[],
|
||||
recipeOptions?: AnnotatedTag[],
|
||||
filmOptions?: AnnotatedTag[],
|
||||
aiTextGeneration?: boolean,
|
||||
shouldStripGpsData?: boolean,
|
||||
): Record<keyof PhotoFormData, FormMeta> => ({
|
||||
@ -121,6 +122,9 @@ const FORM_METADATA = (
|
||||
label: 'film',
|
||||
note: 'Intended for Fujifilm simulations and analog scans',
|
||||
noteShort: 'Fujifilm simulations / analog scans',
|
||||
tagOptions: filmOptions,
|
||||
tagOptionsLimitValidationMessage: 'Photos can only have one film',
|
||||
tagOptionsLimit: 1,
|
||||
shouldNotOverwriteWithNullDataOnSync: true,
|
||||
},
|
||||
recipeTitle: {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user