Improve blur image data generation

This commit is contained in:
Sam Becker 2023-09-22 10:54:51 -05:00
parent 09ed9683dd
commit 1edb480321
3 changed files with 25 additions and 6 deletions

View File

@ -2,6 +2,7 @@
import { LegacyRef } from 'react';
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
import Spinner from './Spinner';
export default function FieldSetWithStatus({
id,
@ -9,6 +10,8 @@ export default function FieldSetWithStatus({
note,
value,
onChange,
placeholder,
loading,
required,
readOnly,
type = 'text',
@ -19,6 +22,8 @@ export default function FieldSetWithStatus({
note?: string
value: string
onChange?: (value: string) => void
placeholder?: string
loading?: boolean
required?: boolean
readOnly?: boolean
type?: 'text' | 'password'
@ -29,7 +34,7 @@ export default function FieldSetWithStatus({
return (
<div className="space-y-1">
<label
className="flex gap-2"
className="flex gap-2 items-center"
htmlFor={id}
>
{label}
@ -41,12 +46,17 @@ export default function FieldSetWithStatus({
<span className="text-gray-400 dark:text-gray-600">
Required
</span>}
{loading &&
<span className="translate-y-[1.5px]">
<Spinner />
</span>}
</label>
<input
ref={inputRef}
id={id}
name={id}
value={value}
placeholder={placeholder}
onChange={e => onChange?.(e.target.value)}
type={type}
autoComplete="off"

View File

@ -37,11 +37,13 @@ export default function PhotoForm({
const url = formData.url ?? '';
useEffect(() => {
let timeout: NodeJS.Timeout;
const image = new Image();
image.crossOrigin = 'anonymous';
image.src = url;
image.onload = () => {
const timeout = setTimeout(() => {
timeout = setTimeout(() => {
const canvas = canvasRef.current;
if (canvas) {
canvas.width = THUMBNAIL_WIDTH * BLUR_SCALE;
@ -72,9 +74,10 @@ export default function PhotoForm({
} else {
console.error('Cannot generate blur data: canvas not found');
}
}, 1000);
return () => clearTimeout(timeout);
}, 2000);
};
return () => clearTimeout(timeout);
}, [url, type]);
const isFormValid = FORM_METADATA_ENTRIES.every(([key, { required }]) =>
@ -110,7 +113,7 @@ export default function PhotoForm({
>
{FORM_METADATA_ENTRIES.map(([
key,
{ label, note, required, readOnly, hideIfEmpty },
{ label, note, required, readOnly, hideIfEmpty, loadingMessage },
]) =>
(!hideIfEmpty || formData[key]) &&
<FieldSetWithStatus
@ -122,6 +125,10 @@ export default function PhotoForm({
onChange={value => setFormData({ ...formData, [key]: value })}
required={required}
readOnly={readOnly}
placeholder={loadingMessage && !formData[key]
? loadingMessage
: undefined}
loading={loadingMessage && !formData[key] ? true : false}
/>)}
<div className="flex gap-4">
{type === 'edit' &&

View File

@ -18,16 +18,18 @@ type FormMeta = {
readOnly?: boolean
hideIfEmpty?: boolean
hideTemporarily?: boolean
loadingMessage?: string
};
const FORM_METADATA: Record<keyof PhotoFormData, FormMeta> = {
title: { label: 'title' },
tags: { label: 'tags', note: 'comma-separated values' },
id: { label: 'id', readOnly: true, hideIfEmpty: true },
// eslint-disable-next-line max-len
blurData: { label: 'blur data', readOnly: true, required: true, loadingMessage: 'Generating blur data ...' },
url: { label: 'url', readOnly: true },
extension: { label: 'extension', readOnly: true },
aspectRatio: { label: 'aspect ratio', readOnly: true },
blurData: { label: 'blur data', readOnly: true, required: true },
make: { label: 'camera make' },
model: { label: 'camera model' },
focalLength: { label: 'focal length' },