Merge pull request #95 from sambecker/image-refactor
Refactor image components
This commit is contained in:
commit
5ddb0e7111
@ -3,7 +3,7 @@
|
||||
import { Photo, deleteConfirmationTextForPhoto, titleForPhoto } from '@/photo';
|
||||
import AdminTable from './AdminTable';
|
||||
import { Fragment } from 'react';
|
||||
import PhotoTiny from '@/photo/PhotoTiny';
|
||||
import PhotoSmall from '@/photo/PhotoSmall';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import { pathForAdminPhotoEdit, pathForPhoto } from '@/site/paths';
|
||||
import Link from 'next/link';
|
||||
@ -36,7 +36,7 @@ export default function AdminPhotosTable({
|
||||
<AdminTable>
|
||||
{photos.map((photo, index) =>
|
||||
<Fragment key={photo.id}>
|
||||
<PhotoTiny
|
||||
<PhotoSmall
|
||||
photo={photo}
|
||||
onVisible={index === photos.length - 1
|
||||
? onLastPhotoVisible
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Fragment } from 'react';
|
||||
import AdminTable from './AdminTable';
|
||||
import Link from 'next/link';
|
||||
import ImageTiny from '@/components/ImageTiny';
|
||||
import { StorageListResponse, fileNameForStorageUrl } from '@/services/storage';
|
||||
import FormWithConfirm from '@/components/FormWithConfirm';
|
||||
import { deleteBlobPhotoAction } from '@/photo/actions';
|
||||
@ -10,6 +9,7 @@ import { clsx } from 'clsx/lite';
|
||||
import { pathForAdminUploadUrl } from '@/site/paths';
|
||||
import AddButton from './AddButton';
|
||||
import { formatDate } from 'date-fns';
|
||||
import ImageSmall from '@/components/image/ImageSmall';
|
||||
|
||||
export default function AdminUploadsTable({
|
||||
title,
|
||||
@ -25,7 +25,7 @@ export default function AdminUploadsTable({
|
||||
const uploadFileName = fileNameForStorageUrl(url);
|
||||
return <Fragment key={url}>
|
||||
<Link href={addUploadPath} prefetch={false}>
|
||||
<ImageTiny
|
||||
<ImageSmall
|
||||
alt={`Upload: ${uploadFileName}`}
|
||||
src={url}
|
||||
aspectRatio={3.0 / 2.0}
|
||||
|
||||
@ -36,7 +36,7 @@ import { signOutAndRedirectAction } from '@/auth/actions';
|
||||
import { TbPhoto } from 'react-icons/tb';
|
||||
import { getKeywordsForPhoto, titleForPhoto } from '@/photo';
|
||||
import PhotoDate from '@/photo/PhotoDate';
|
||||
import PhotoTiny from '@/photo/PhotoTiny';
|
||||
import PhotoSmall from '@/photo/PhotoSmall';
|
||||
import { FaCheck } from 'react-icons/fa6';
|
||||
import { TagsWithMeta, addHiddenToTags } from '@/tag';
|
||||
import { FaTag } from 'react-icons/fa';
|
||||
@ -79,12 +79,12 @@ export default function CommandKClient({
|
||||
hiddenPhotosCount,
|
||||
arePhotosMatted,
|
||||
shouldShowBaselineGrid,
|
||||
shouldDebugBlur,
|
||||
shouldDebugImageFallbacks,
|
||||
setIsCommandKOpen: setIsOpen,
|
||||
setShouldRespondToKeyboardCommands,
|
||||
setShouldShowBaselineGrid,
|
||||
setArePhotosMatted,
|
||||
setShouldDebugBlur,
|
||||
setShouldDebugImageFallbacks,
|
||||
} = useAppState();
|
||||
|
||||
const isOpenRef = useRef(isOpen);
|
||||
@ -146,7 +146,7 @@ export default function CommandKClient({
|
||||
label: titleForPhoto(photo),
|
||||
keywords: getKeywordsForPhoto(photo),
|
||||
annotation: <PhotoDate {...{ photo }} />,
|
||||
accessory: <PhotoTiny photo={photo} />,
|
||||
accessory: <PhotoSmall photo={photo} />,
|
||||
path: pathForPhoto(photo),
|
||||
})),
|
||||
}]
|
||||
@ -228,9 +228,11 @@ export default function CommandKClient({
|
||||
action: () => setArePhotosMatted?.(prev => !prev),
|
||||
annotation: arePhotosMatted ? <FaCheck size={12} /> : undefined,
|
||||
}, {
|
||||
label: 'Toggle Blur Debug',
|
||||
action: () => setShouldDebugBlur?.(prev => !prev),
|
||||
annotation: shouldDebugBlur ? <FaCheck size={12} /> : undefined,
|
||||
label: 'Toggle Image Fallbacks',
|
||||
action: () => setShouldDebugImageFallbacks?.(prev => !prev),
|
||||
annotation: shouldDebugImageFallbacks
|
||||
? <FaCheck size={12} />
|
||||
: undefined,
|
||||
}, {
|
||||
label: 'Toggle Baseline Grid',
|
||||
action: () => setShouldShowBaselineGrid?.(prev => !prev),
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
import { IMAGE_LARGE_WIDTH } from '@/site';
|
||||
import ImageBlurFallback from './ImageBlurFallback';
|
||||
|
||||
export default function ImageLarge({
|
||||
className,
|
||||
imgClassName,
|
||||
src,
|
||||
alt,
|
||||
aspectRatio,
|
||||
blurData,
|
||||
blurCompatibilityMode,
|
||||
priority,
|
||||
}: {
|
||||
className?: string
|
||||
imgClassName?: string
|
||||
src: string
|
||||
alt: string
|
||||
aspectRatio: number
|
||||
blurData?: string
|
||||
blurCompatibilityMode?: boolean
|
||||
priority?: boolean
|
||||
}) {
|
||||
return (
|
||||
<ImageBlurFallback {...{
|
||||
className,
|
||||
imgClassName,
|
||||
src,
|
||||
alt,
|
||||
blurDataURL: blurData,
|
||||
blurCompatibilityLevel: blurCompatibilityMode ? 'high' : 'none',
|
||||
priority,
|
||||
width: IMAGE_LARGE_WIDTH,
|
||||
height: Math.round(IMAGE_LARGE_WIDTH / aspectRatio),
|
||||
}} />
|
||||
);
|
||||
};
|
||||
@ -1,33 +0,0 @@
|
||||
import { IMAGE_SMALL_WIDTH } from '@/site';
|
||||
import ImageBlurFallback from './ImageBlurFallback';
|
||||
|
||||
export default function ImageSmall({
|
||||
className,
|
||||
src,
|
||||
alt,
|
||||
aspectRatio,
|
||||
blurData,
|
||||
blurCompatibilityMode,
|
||||
priority,
|
||||
}: {
|
||||
className?: string
|
||||
src: string
|
||||
alt: string
|
||||
aspectRatio: number
|
||||
blurData?: string
|
||||
blurCompatibilityMode?: boolean
|
||||
priority?: boolean
|
||||
}) {
|
||||
return (
|
||||
<ImageBlurFallback {...{
|
||||
className,
|
||||
src,
|
||||
alt,
|
||||
blurDataURL: blurData,
|
||||
blurCompatibilityLevel: blurCompatibilityMode ? 'high' : 'none',
|
||||
priority,
|
||||
width: IMAGE_SMALL_WIDTH,
|
||||
height: Math.round(IMAGE_SMALL_WIDTH / aspectRatio),
|
||||
}} />
|
||||
);
|
||||
};
|
||||
@ -1,30 +0,0 @@
|
||||
import { IMAGE_TINY_WIDTH } from '@/site';
|
||||
import ImageBlurFallback from './ImageBlurFallback';
|
||||
|
||||
export default function ImageTiny({
|
||||
className,
|
||||
src,
|
||||
alt,
|
||||
aspectRatio,
|
||||
blurData,
|
||||
blurCompatibilityMode,
|
||||
}: {
|
||||
className?: string
|
||||
src: string
|
||||
alt: string
|
||||
aspectRatio: number
|
||||
blurData?: string
|
||||
blurCompatibilityMode?: boolean
|
||||
}) {
|
||||
return (
|
||||
<ImageBlurFallback {...{
|
||||
className,
|
||||
src,
|
||||
alt,
|
||||
blurDataURL: blurData,
|
||||
blurCompatibilityLevel: blurCompatibilityMode ? 'high' : 'none',
|
||||
width: IMAGE_TINY_WIDTH,
|
||||
height: Math.round(IMAGE_TINY_WIDTH / aspectRatio),
|
||||
}} />
|
||||
);
|
||||
};
|
||||
@ -24,7 +24,7 @@ export default function ShareButton({
|
||||
'-mx-0.5 translate-x-0.5',
|
||||
'sm:mx-0 sm:translate-x-0',
|
||||
)}
|
||||
icon={<TbPhotoShare size={17} />}
|
||||
icon={<TbPhotoShare size={16} />}
|
||||
spinnerColor="dim"
|
||||
prefetch={prefetch}
|
||||
shouldScroll={shouldScroll}
|
||||
|
||||
18
src/components/image/ImageLarge.tsx
Normal file
18
src/components/image/ImageLarge.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { IMAGE_WIDTH_LARGE, ImageProps } from '.';
|
||||
import ImageWithFallback from './ImageWithFallback';
|
||||
|
||||
export default function ImageLarge(props: ImageProps) {
|
||||
const {
|
||||
aspectRatio,
|
||||
blurCompatibilityMode,
|
||||
...rest
|
||||
} = props;
|
||||
return (
|
||||
<ImageWithFallback {...{
|
||||
...rest,
|
||||
blurCompatibilityLevel: blurCompatibilityMode ? 'high' : 'none',
|
||||
width: IMAGE_WIDTH_LARGE,
|
||||
height: Math.round(IMAGE_WIDTH_LARGE / aspectRatio),
|
||||
}} />
|
||||
);
|
||||
};
|
||||
18
src/components/image/ImageMedium.tsx
Normal file
18
src/components/image/ImageMedium.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { IMAGE_WIDTH_MEDIUM, ImageProps } from '.';
|
||||
import ImageWithFallback from './ImageWithFallback';
|
||||
|
||||
export default function ImageMedium(props: ImageProps) {
|
||||
const {
|
||||
aspectRatio,
|
||||
blurCompatibilityMode,
|
||||
...rest
|
||||
} = props;
|
||||
return (
|
||||
<ImageWithFallback {...{
|
||||
...rest,
|
||||
blurCompatibilityLevel: blurCompatibilityMode ? 'high' : 'none',
|
||||
width: IMAGE_WIDTH_MEDIUM,
|
||||
height: Math.round(IMAGE_WIDTH_MEDIUM / aspectRatio),
|
||||
}} />
|
||||
);
|
||||
};
|
||||
18
src/components/image/ImageSmall.tsx
Normal file
18
src/components/image/ImageSmall.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { IMAGE_WIDTH_SMALL, ImageProps } from '.';
|
||||
import ImageWithFallback from './ImageWithFallback';
|
||||
|
||||
export default function ImageSmall(props: ImageProps) {
|
||||
const {
|
||||
aspectRatio,
|
||||
blurCompatibilityMode,
|
||||
...rest
|
||||
} = props;
|
||||
return (
|
||||
<ImageWithFallback {...{
|
||||
...rest,
|
||||
blurCompatibilityLevel: blurCompatibilityMode ? 'high' : 'none',
|
||||
width: IMAGE_WIDTH_SMALL,
|
||||
height: Math.round(IMAGE_WIDTH_SMALL / aspectRatio),
|
||||
}} />
|
||||
);
|
||||
};
|
||||
@ -7,7 +7,7 @@ import { clsx} from 'clsx/lite';
|
||||
import Image, { ImageProps } from 'next/image';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
export default function ImageBlurFallback(props: ImageProps & {
|
||||
export default function ImageWithFallback(props: ImageProps & {
|
||||
blurCompatibilityLevel?: 'none' | 'low' | 'high'
|
||||
imgClassName?: string
|
||||
}) {
|
||||
@ -20,7 +20,7 @@ export default function ImageBlurFallback(props: ImageProps & {
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const { shouldDebugBlur } = useAppState();
|
||||
const { shouldDebugImageFallbacks } = useAppState();
|
||||
|
||||
const [wasCached, setWasCached] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@ -29,7 +29,7 @@ export default function ImageBlurFallback(props: ImageProps & {
|
||||
const onLoad = useCallback(() => setIsLoading(false), []);
|
||||
const onError = useCallback(() => setDidError(true), []);
|
||||
|
||||
const [hideBlurPlaceholder, setHideBlurPlaceholder] = useState(false);
|
||||
const [hideFallback, setHideFallback] = useState(false);
|
||||
|
||||
const imgRef = useRef<HTMLImageElement>(null);
|
||||
|
||||
@ -44,15 +44,15 @@ export default function ImageBlurFallback(props: ImageProps & {
|
||||
useEffect(() => {
|
||||
if (!isLoading && !didError) {
|
||||
const timeout = setTimeout(() => {
|
||||
setHideBlurPlaceholder(true);
|
||||
setHideFallback(true);
|
||||
}, 1000);
|
||||
return () => clearTimeout(timeout);
|
||||
}
|
||||
}, [isLoading, didError]);
|
||||
|
||||
const showPlaceholder =
|
||||
const showFallback =
|
||||
!wasCached &&
|
||||
!hideBlurPlaceholder;
|
||||
!hideFallback;
|
||||
|
||||
const getBlurClass = () => {
|
||||
switch (blurCompatibilityLevel) {
|
||||
@ -71,16 +71,18 @@ export default function ImageBlurFallback(props: ImageProps & {
|
||||
'flex relative',
|
||||
)}
|
||||
>
|
||||
{(showPlaceholder || shouldDebugBlur) &&
|
||||
{(showFallback || shouldDebugImageFallbacks) &&
|
||||
<div className={clsx(
|
||||
'@container',
|
||||
'absolute inset-0',
|
||||
'overflow-hidden',
|
||||
'transition-opacity duration-300 ease-in',
|
||||
!(BLUR_ENABLED && props.blurDataURL) && 'bg-main',
|
||||
(isLoading || shouldDebugBlur) ? 'opacity-100' : 'opacity-0',
|
||||
!(BLUR_ENABLED && blurDataURL) && 'bg-main',
|
||||
(isLoading || shouldDebugImageFallbacks)
|
||||
? 'opacity-100'
|
||||
: 'opacity-0',
|
||||
)}>
|
||||
{(BLUR_ENABLED && props.blurDataURL)
|
||||
{(BLUR_ENABLED && blurDataURL)
|
||||
? <img {...{
|
||||
...rest,
|
||||
src: blurDataURL,
|
||||
17
src/components/image/index.ts
Normal file
17
src/components/image/index.ts
Normal file
@ -0,0 +1,17 @@
|
||||
// Height determined by intrinsic photo aspect ratio
|
||||
export const IMAGE_WIDTH_SMALL = 50;
|
||||
// Height determined by intrinsic photo aspect ratio
|
||||
export const IMAGE_WIDTH_MEDIUM = 300;
|
||||
// Height determined by intrinsic photo aspect ratio
|
||||
export const IMAGE_WIDTH_LARGE = 1000;
|
||||
|
||||
export interface ImageProps {
|
||||
aspectRatio: number
|
||||
blurCompatibilityMode?: boolean
|
||||
className?: string
|
||||
imgClassName?: string
|
||||
src: string
|
||||
alt: string
|
||||
blurDataURL?: string
|
||||
priority?: boolean
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Photo } from '.';
|
||||
import PhotoSmall from './PhotoSmall';
|
||||
import PhotoMedium from './PhotoMedium';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import AnimateItems from '@/components/AnimateItems';
|
||||
import { Camera } from '@/camera';
|
||||
@ -57,7 +57,7 @@ export default function PhotoGrid({
|
||||
<div
|
||||
key={photo.id}
|
||||
className={GRID_ASPECT_RATIO !== 0
|
||||
? 'aspect-square overflow-hidden'
|
||||
? 'flex relative overflow-hidden'
|
||||
: undefined}
|
||||
style={{
|
||||
...GRID_ASPECT_RATIO !== 0 && {
|
||||
@ -65,17 +65,20 @@ export default function PhotoGrid({
|
||||
},
|
||||
}}
|
||||
>
|
||||
<PhotoSmall {...{
|
||||
photo,
|
||||
tag,
|
||||
camera,
|
||||
simulation,
|
||||
selected: photo.id === selectedPhoto?.id,
|
||||
priority: photoPriority,
|
||||
onVisible: index === photos.length - 1
|
||||
? onLastPhotoVisible
|
||||
: undefined,
|
||||
}} />
|
||||
<PhotoMedium
|
||||
className="flex w-full h-full"
|
||||
{...{
|
||||
photo,
|
||||
tag,
|
||||
camera,
|
||||
simulation,
|
||||
selected: photo.id === selectedPhoto?.id,
|
||||
priority: photoPriority,
|
||||
onVisible: index === photos.length - 1
|
||||
? onLastPhotoVisible
|
||||
: undefined,
|
||||
}}
|
||||
/>
|
||||
</div>).concat(additionalTile ?? [])}
|
||||
itemKeys={photos.map(photo => photo.id)
|
||||
.concat(additionalTile ? ['more'] : [])}
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
shouldShowExifDataForPhoto,
|
||||
} from '.';
|
||||
import SiteGrid from '@/components/SiteGrid';
|
||||
import ImageLarge from '@/components/ImageLarge';
|
||||
import ImageLarge from '@/components/image/ImageLarge';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import Link from 'next/link';
|
||||
import { pathForPhoto, pathForPhotoShare } from '@/site/paths';
|
||||
@ -96,7 +96,7 @@ export default function PhotoLarge({
|
||||
alt={altTextForPhoto(photo)}
|
||||
src={photo.url}
|
||||
aspectRatio={photo.aspectRatio}
|
||||
blurData={photo.blurData}
|
||||
blurDataURL={photo.blurData}
|
||||
blurCompatibilityMode={doesPhotoNeedBlurCompatibility(photo)}
|
||||
priority={priority}
|
||||
/>
|
||||
|
||||
@ -1,25 +1,35 @@
|
||||
'use client';
|
||||
|
||||
import { Photo, altTextForPhoto, doesPhotoNeedBlurCompatibility } from '.';
|
||||
import ImageTiny from '@/components/ImageTiny';
|
||||
import ImageMedium from '@/components/image/ImageMedium';
|
||||
import Link from 'next/link';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import { pathForPhoto } from '@/site/paths';
|
||||
import { Camera } from '@/camera';
|
||||
import { FilmSimulation } from '@/simulation';
|
||||
import { SHOULD_PREFETCH_ALL_LINKS } from '@/site/config';
|
||||
import { useRef } from 'react';
|
||||
import useOnVisible from '@/utility/useOnVisible';
|
||||
|
||||
export default function PhotoTiny({
|
||||
export default function PhotoMedium({
|
||||
photo,
|
||||
tag,
|
||||
camera,
|
||||
simulation,
|
||||
selected,
|
||||
className,
|
||||
priority,
|
||||
prefetch = SHOULD_PREFETCH_ALL_LINKS,
|
||||
className,
|
||||
onVisible,
|
||||
}: {
|
||||
photo: Photo
|
||||
tag?: string
|
||||
camera?: Camera
|
||||
simulation?: FilmSimulation
|
||||
selected?: boolean
|
||||
className?: string
|
||||
priority?: boolean
|
||||
prefetch?: boolean
|
||||
className?: string
|
||||
onVisible?: () => void
|
||||
}) {
|
||||
const ref = useRef<HTMLAnchorElement>(null);
|
||||
@ -29,23 +39,23 @@ export default function PhotoTiny({
|
||||
return (
|
||||
<Link
|
||||
ref={ref}
|
||||
href={pathForPhoto(photo, tag)}
|
||||
href={pathForPhoto(photo, tag, camera, simulation)}
|
||||
className={clsx(
|
||||
className,
|
||||
'active:brightness-75',
|
||||
selected && 'brightness-50',
|
||||
'min-w-[50px]',
|
||||
'rounded-[0.15rem] overflow-hidden',
|
||||
'border border-gray-200 dark:border-gray-800',
|
||||
className,
|
||||
)}
|
||||
prefetch={prefetch}
|
||||
>
|
||||
<ImageTiny
|
||||
<ImageMedium
|
||||
src={photo.url}
|
||||
aspectRatio={photo.aspectRatio}
|
||||
blurData={photo.blurData}
|
||||
blurDataURL={photo.blurData}
|
||||
blurCompatibilityMode={doesPhotoNeedBlurCompatibility(photo)}
|
||||
className="flex object-cover w-full h-full"
|
||||
imgClassName="object-cover w-full h-full"
|
||||
alt={altTextForPhoto(photo)}
|
||||
priority={priority}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
@ -1,12 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Photo, altTextForPhoto, doesPhotoNeedBlurCompatibility } from '.';
|
||||
import ImageSmall from '@/components/ImageSmall';
|
||||
import ImageSmall from '@/components/image/ImageSmall';
|
||||
import Link from 'next/link';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import { pathForPhoto } from '@/site/paths';
|
||||
import { Camera } from '@/camera';
|
||||
import { FilmSimulation } from '@/simulation';
|
||||
import { SHOULD_PREFETCH_ALL_LINKS } from '@/site/config';
|
||||
import { useRef } from 'react';
|
||||
import useOnVisible from '@/utility/useOnVisible';
|
||||
@ -14,19 +10,15 @@ import useOnVisible from '@/utility/useOnVisible';
|
||||
export default function PhotoSmall({
|
||||
photo,
|
||||
tag,
|
||||
camera,
|
||||
simulation,
|
||||
selected,
|
||||
priority,
|
||||
className,
|
||||
prefetch = SHOULD_PREFETCH_ALL_LINKS,
|
||||
onVisible,
|
||||
}: {
|
||||
photo: Photo
|
||||
tag?: string
|
||||
camera?: Camera
|
||||
simulation?: FilmSimulation
|
||||
selected?: boolean
|
||||
priority?: boolean
|
||||
className?: string
|
||||
prefetch?: boolean
|
||||
onVisible?: () => void
|
||||
}) {
|
||||
@ -37,22 +29,23 @@ export default function PhotoSmall({
|
||||
return (
|
||||
<Link
|
||||
ref={ref}
|
||||
href={pathForPhoto(photo, tag, camera, simulation)}
|
||||
href={pathForPhoto(photo, tag)}
|
||||
className={clsx(
|
||||
'flex w-full h-full',
|
||||
className,
|
||||
'active:brightness-75',
|
||||
selected && 'brightness-50',
|
||||
'min-w-[50px]',
|
||||
'rounded-[0.15rem] overflow-hidden',
|
||||
'border border-gray-200 dark:border-gray-800',
|
||||
)}
|
||||
prefetch={prefetch}
|
||||
>
|
||||
<ImageSmall
|
||||
src={photo.url}
|
||||
aspectRatio={photo.aspectRatio}
|
||||
blurData={photo.blurData}
|
||||
blurDataURL={photo.blurData}
|
||||
blurCompatibilityMode={doesPhotoNeedBlurCompatibility(photo)}
|
||||
className="w-full"
|
||||
alt={altTextForPhoto(photo)}
|
||||
priority={priority}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
|
||||
@ -18,7 +18,7 @@ import { clsx } from 'clsx/lite';
|
||||
import { PATH_ADMIN_PHOTOS, PATH_ADMIN_UPLOADS } from '@/site/paths';
|
||||
import { toastSuccess, toastWarning } from '@/toast';
|
||||
import { getDimensionsFromSize } from '@/utility/size';
|
||||
import ImageBlurFallback from '@/components/ImageBlurFallback';
|
||||
import ImageWithFallback from '@/components/image/ImageWithFallback';
|
||||
import { TagsWithMeta, sortTagsObjectWithoutFavs } from '@/tag';
|
||||
import { formatCount, formatCountDescriptive } from '@/utility/string';
|
||||
import { AiContent } from '../ai/useAiImageQueries';
|
||||
@ -59,7 +59,7 @@ export default function PhotoForm({
|
||||
const [formErrors, setFormErrors] =
|
||||
useState(getFormErrors(initialPhotoForm));
|
||||
|
||||
const { invalidateSwr, shouldDebugBlur } = useAppState();
|
||||
const { invalidateSwr, shouldDebugImageFallbacks } = useAppState();
|
||||
|
||||
const changedFormKeys = useMemo(() =>
|
||||
getChangedFormFields(initialPhotoForm, formData),
|
||||
@ -199,7 +199,7 @@ export default function PhotoForm({
|
||||
shouldConfirm={Boolean(formData.semanticDescription)}
|
||||
/>;
|
||||
case 'blurData':
|
||||
return shouldDebugBlur && type === 'edit' && formData.url
|
||||
return shouldDebugImageFallbacks && type === 'edit' && formData.url
|
||||
? <UpdateBlurDataButton
|
||||
photoUrl={getNextImageUrlForManipulation(formData.url)}
|
||||
onUpdatedBlurData={blurData =>
|
||||
@ -219,7 +219,7 @@ export default function PhotoForm({
|
||||
key === 'blurData' &&
|
||||
type === 'create' &&
|
||||
!BLUR_ENABLED &&
|
||||
!shouldDebugBlur
|
||||
!shouldDebugImageFallbacks
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
@ -234,7 +234,7 @@ export default function PhotoForm({
|
||||
<div className="space-y-8 max-w-[38rem] relative">
|
||||
<div className="flex gap-2">
|
||||
<div className="relative">
|
||||
<ImageBlurFallback
|
||||
<ImageWithFallback
|
||||
alt="Upload"
|
||||
src={url}
|
||||
className={clsx(
|
||||
@ -307,9 +307,11 @@ export default function PhotoForm({
|
||||
<FieldSetWithStatus
|
||||
key={key}
|
||||
id={key}
|
||||
label={label + (key === 'blurData' && shouldDebugBlur
|
||||
? ` (${(formData[key] ?? '').length} chars.)`
|
||||
: '')}
|
||||
label={label + (
|
||||
key === 'blurData' && shouldDebugImageFallbacks
|
||||
? ` (${(formData[key] ?? '').length} chars.)`
|
||||
: ''
|
||||
)}
|
||||
note={note}
|
||||
error={formErrors[key]}
|
||||
value={formData[key] ?? ''}
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
// Height determined by intrinsic photo aspect ratio
|
||||
export const IMAGE_TINY_WIDTH = 50;
|
||||
|
||||
// Height determined by intrinsic photo aspect ratio
|
||||
export const IMAGE_SMALL_WIDTH = 300;
|
||||
|
||||
// Height determined by intrinsic photo aspect ratio
|
||||
export const IMAGE_LARGE_WIDTH = 1000;
|
||||
@ -25,8 +25,8 @@ export interface AppStateContext {
|
||||
// DEBUG
|
||||
arePhotosMatted?: boolean
|
||||
setArePhotosMatted?: Dispatch<SetStateAction<boolean>>
|
||||
shouldDebugBlur?: boolean
|
||||
setShouldDebugBlur?: Dispatch<SetStateAction<boolean>>
|
||||
shouldDebugImageFallbacks?: boolean
|
||||
setShouldDebugImageFallbacks?: Dispatch<SetStateAction<boolean>>
|
||||
shouldShowBaselineGrid?: boolean
|
||||
setShouldShowBaselineGrid?: Dispatch<SetStateAction<boolean>>
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ export default function AppStateProvider({
|
||||
// DEBUG
|
||||
const [arePhotosMatted, setArePhotosMatted] =
|
||||
useState(MATTE_PHOTOS);
|
||||
const [shouldDebugBlur, setShouldDebugBlur] =
|
||||
const [shouldDebugImageFallbacks, setShouldDebugImageFallbacks] =
|
||||
useState(false);
|
||||
const [shouldShowBaselineGrid, setShouldShowBaselineGrid] =
|
||||
useState(false);
|
||||
@ -96,10 +96,10 @@ export default function AppStateProvider({
|
||||
// DEBUG
|
||||
arePhotosMatted,
|
||||
setArePhotosMatted,
|
||||
setShouldDebugBlur,
|
||||
setShouldShowBaselineGrid,
|
||||
shouldDebugImageFallbacks,
|
||||
setShouldDebugImageFallbacks,
|
||||
shouldShowBaselineGrid,
|
||||
shouldDebugBlur,
|
||||
setShouldShowBaselineGrid,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user