Screen photos for missing AI text

This commit is contained in:
Sam Becker 2025-04-18 22:23:46 -05:00
parent 82acdca068
commit 013acacb7b
5 changed files with 37 additions and 19 deletions

View File

@ -21,7 +21,6 @@ import { RevalidatePhoto } from '@/photo/InfinitePhotoScroll';
import { MdOutlineFileDownload } from 'react-icons/md';
import MoreMenuItem from '@/components/more/MoreMenuItem';
import IconGrSync from '@/components/icons/IconGrSync';
import { isPhotoOutdated } from '@/photo/outdated';
import InsightsIndicatorDot from './insights/InsightsIndicatorDot';
import IconFavs from '@/components/icons/IconFavs';
import IconEdit from '@/components/icons/IconEdit';
@ -79,7 +78,7 @@ export default function AdminPhotoMenu({
label: 'Sync',
labelComplex: <span className="inline-flex items-center gap-2">
<span>Sync</span>
{isPhotoOutdated(photo) &&
{photo.needsSync &&
<InsightsIndicatorDot
colorOverride="blue"
className="translate-y-[1.5px]"

View File

@ -24,7 +24,7 @@ import { getWheresFromOptions } from '.';
import { FocalLengths } from '@/focal';
import { Lenses, createLensKey } from '@/lens';
import { migrationForError } from './migration';
import { UPDATED_BEFORE_01, UPDATED_BEFORE_02 } from '../outdated';
import { UPDATED_BEFORE_01, UPDATED_BEFORE_02 } from '../sync';
import { MAKE_FUJIFILM } from '@/platforms/fujifilm';
import { Recipes } from '@/recipe';

View File

@ -23,6 +23,7 @@ import { isBefore } from 'date-fns';
import type { Metadata } from 'next';
import { FujifilmRecipe } from '@/platforms/fujifilm/recipe';
import { FujifilmSimulation } from '@/platforms/fujifilm/simulation';
import { doesPhotoNeedSync } from './sync';
// INFINITE SCROLL: FEED
export const INFINITE_SCROLL_FEED_INITIAL =
@ -109,13 +110,14 @@ export interface Photo extends Omit<PhotoDb, 'recipeData'> {
exposureCompensationFormatted?: string
takenAtNaiveFormatted: string
recipeData?: FujifilmRecipe
needsSync?: boolean
}
export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => {
const photoDb = camelcaseKeys(
photoDbRaw as unknown as Record<string, unknown>,
) as unknown as PhotoDb;
return {
const photo: Photo ={
...photoDb,
tags: photoDb.tags ?? [],
focalLengthFormatted:
@ -130,15 +132,17 @@ export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => {
formatExposureTime(photoDb.exposureTime),
exposureCompensationFormatted:
formatExposureCompensation(photoDb.exposureCompensation),
takenAtNaiveFormatted:
formatDateFromPostgresString(photoDb.takenAtNaive),
recipeData: photoDb.recipeData
// Legacy check on escaped, string-based JSON
? typeof photoDb.recipeData === 'string'
? JSON.parse(photoDb.recipeData)
: photoDb.recipeData
: undefined,
takenAtNaiveFormatted:
formatDateFromPostgresString(photoDb.takenAtNaive),
};
photo.needsSync = doesPhotoNeedSync(photo);
return photo;
};
export const parseCachedPhotoDates = (photo: Photo) => ({

View File

@ -1,13 +0,0 @@
import { MAKE_FUJIFILM } from '@/platforms/fujifilm';
import { Photo } from '.';
export const UPDATED_BEFORE_01 = new Date('2024-06-16');
// UTC 2025-02-24 05:30:00
export const UPDATED_BEFORE_02 = new Date(Date.UTC(2025, 1, 24, 5, 30, 0));
export const isPhotoOutdated = (photo: Photo) => {
return photo.updatedAt < UPDATED_BEFORE_01 || (
photo.updatedAt < UPDATED_BEFORE_02 &&
photo.make === MAKE_FUJIFILM
);
};

28
src/photo/sync.ts Normal file
View File

@ -0,0 +1,28 @@
import { MAKE_FUJIFILM } from '@/platforms/fujifilm';
import { Photo } from '.';
import { AI_TEXT_AUTO_GENERATED_FIELDS } from '@/app/config';
export const UPDATED_BEFORE_01 = new Date('2024-06-16');
// UTC 2025-02-24 05:30:00
export const UPDATED_BEFORE_02 = new Date(Date.UTC(2025, 1, 24, 5, 30, 0));
const isPhotoOutdated = (photo: Photo) =>
photo.updatedAt < UPDATED_BEFORE_01 || (
photo.updatedAt < UPDATED_BEFORE_02 &&
photo.make === MAKE_FUJIFILM
);
const doesPhotoNeedAiText = ({
title,
caption,
tags = [],
semanticDescription,
}: Photo) =>
(AI_TEXT_AUTO_GENERATED_FIELDS.includes('title') && !title) ||
(AI_TEXT_AUTO_GENERATED_FIELDS.includes('caption') && !caption) ||
(AI_TEXT_AUTO_GENERATED_FIELDS.includes('tags') && tags.length === 0) ||
(AI_TEXT_AUTO_GENERATED_FIELDS.includes('semantic') && !semanticDescription);
export const doesPhotoNeedSync = (photo: Photo) =>
isPhotoOutdated(photo) ||
doesPhotoNeedAiText(photo);