diff --git a/src/components/FieldSetWithStatus.tsx b/src/components/FieldSetWithStatus.tsx
index 97aababc..d3ea17d7 100644
--- a/src/components/FieldSetWithStatus.tsx
+++ b/src/components/FieldSetWithStatus.tsx
@@ -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 (
onChange?.(e.target.value)}
type={type}
autoComplete="off"
diff --git a/src/photo/PhotoForm.tsx b/src/photo/PhotoForm.tsx
index e8b78e86..2c68281f 100644
--- a/src/photo/PhotoForm.tsx
+++ b/src/photo/PhotoForm.tsx
@@ -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]) &&
setFormData({ ...formData, [key]: value })}
required={required}
readOnly={readOnly}
+ placeholder={loadingMessage && !formData[key]
+ ? loadingMessage
+ : undefined}
+ loading={loadingMessage && !formData[key] ? true : false}
/>)}
{type === 'edit' &&
diff --git a/src/photo/form.ts b/src/photo/form.ts
index 39ca6c7b..f58a2968 100644
--- a/src/photo/form.ts
+++ b/src/photo/form.ts
@@ -18,16 +18,18 @@ type FormMeta = {
readOnly?: boolean
hideIfEmpty?: boolean
hideTemporarily?: boolean
+ loadingMessage?: string
};
const FORM_METADATA: Record = {
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' },