- {showPlaceholder &&
+ {(showPlaceholder || shouldDebugBlur) &&
{(BLUR_ENABLED && props.blurDataURL)
?
![]()
:
diff --git a/src/components/ImageSmall.tsx b/src/components/ImageSmall.tsx
index d13cb0e7..b03489f5 100644
--- a/src/components/ImageSmall.tsx
+++ b/src/components/ImageSmall.tsx
@@ -7,6 +7,7 @@ export default function ImageSmall({
alt,
aspectRatio,
blurData,
+ blurCompatibilityMode,
priority,
}: {
className?: string
@@ -14,6 +15,7 @@ export default function ImageSmall({
alt: string
aspectRatio: number
blurData?: string
+ blurCompatibilityMode?: boolean
priority?: boolean
}) {
return (
@@ -21,8 +23,9 @@ export default function ImageSmall({
className,
src,
alt,
- priority,
blurDataURL: blurData,
+ blurCompatibilityLevel: blurCompatibilityMode ? 'high' : 'none',
+ priority,
width: IMAGE_SMALL_WIDTH,
height: Math.round(IMAGE_SMALL_WIDTH / aspectRatio),
}} />
diff --git a/src/components/ImageTiny.tsx b/src/components/ImageTiny.tsx
index 5e976775..9b319f50 100644
--- a/src/components/ImageTiny.tsx
+++ b/src/components/ImageTiny.tsx
@@ -7,12 +7,14 @@ export default function ImageTiny({
alt,
aspectRatio,
blurData,
+ blurCompatibilityMode,
}: {
className?: string
src: string
alt: string
aspectRatio: number
blurData?: string
+ blurCompatibilityMode?: boolean
}) {
return (
diff --git a/src/components/PageSpinner.tsx b/src/components/PageSpinner.tsx
index cd4c99af..630f5821 100644
--- a/src/components/PageSpinner.tsx
+++ b/src/components/PageSpinner.tsx
@@ -1,4 +1,4 @@
-import clsx from 'clsx/lite';
+import { clsx } from 'clsx/lite';
import Spinner from './Spinner';
import SiteGrid from './SiteGrid';
diff --git a/src/components/ShareButton.tsx b/src/components/ShareButton.tsx
index 02057aac..b0af3664 100644
--- a/src/components/ShareButton.tsx
+++ b/src/components/ShareButton.tsx
@@ -1,27 +1,33 @@
import { TbPhotoShare } from 'react-icons/tb';
-import IconPathButton from '@/components/IconPathButton';
+import PathLoaderButton from './primitives/PathLoaderButton';
+import clsx from 'clsx';
export default function ShareButton({
path,
prefetch,
shouldScroll,
dim,
+ className,
}: {
path: string
prefetch?: boolean
shouldScroll?: boolean
dim?: boolean
+ className?: string
}) {
return (
-
,
- prefetch,
- shouldScroll,
- shouldReplace: true,
- spinnerColor: 'dim',
- }} />
+
}
+ spinnerColor="dim"
+ prefetch={prefetch}
+ shouldScroll={shouldScroll}
+ shouldReplace
+ styleAsLink
+ />
);
}
diff --git a/src/components/SubmitButtonWithStatus.tsx b/src/components/SubmitButtonWithStatus.tsx
index 514b138d..502abb22 100644
--- a/src/components/SubmitButtonWithStatus.tsx
+++ b/src/components/SubmitButtonWithStatus.tsx
@@ -2,9 +2,10 @@
import { HTMLProps, useEffect, useRef } from 'react';
import { useFormStatus } from 'react-dom';
-import Spinner, { SpinnerColor } from './Spinner';
+import { SpinnerColor } from './Spinner';
import { clsx } from 'clsx/lite';
import { toastSuccess } from '@/toast';
+import LoaderButton from '@/components/primitives/LoaderButton';
interface Props extends HTMLProps
{
icon?: JSX.Element
@@ -49,34 +50,21 @@ export default function SubmitButtonWithStatus({
}, [onFormStatusChange, pending]);
return (
-
+ {children}
+
);
};
diff --git a/src/components/primitives/LoaderButton.tsx b/src/components/primitives/LoaderButton.tsx
new file mode 100644
index 00000000..1abc4993
--- /dev/null
+++ b/src/components/primitives/LoaderButton.tsx
@@ -0,0 +1,56 @@
+import Spinner, { SpinnerColor } from '@/components/Spinner';
+import { clsx } from 'clsx/lite';
+import { ButtonHTMLAttributes, ReactNode } from 'react';
+
+export default function LoaderButton(props: {
+ children?: ReactNode
+ isLoading?: boolean
+ icon?: JSX.Element
+ spinnerColor?: SpinnerColor
+ styleAsLink?: boolean
+} & ButtonHTMLAttributes) {
+ const {
+ children,
+ isLoading,
+ icon,
+ spinnerColor,
+ styleAsLink,
+ type = 'button',
+ disabled,
+ className,
+ ...rest
+ } = props;
+ return (
+
+ );
+}
diff --git a/src/components/IconPathButton.tsx b/src/components/primitives/PathLoaderButton.tsx
similarity index 68%
rename from src/components/IconPathButton.tsx
rename to src/components/primitives/PathLoaderButton.tsx
index 4108d89d..dc61947a 100644
--- a/src/components/IconPathButton.tsx
+++ b/src/components/primitives/PathLoaderButton.tsx
@@ -1,27 +1,32 @@
'use client';
import { useRouter } from 'next/navigation';
-import IconButton from './IconButton';
-import { useEffect, useState, useTransition } from 'react';
-import { clsx } from 'clsx/lite';
-import { SpinnerColor } from './Spinner';
+import { ReactNode, useEffect, useState, useTransition } from 'react';
+import { SpinnerColor } from '../Spinner';
+import LoaderButton from '@/components/primitives/LoaderButton';
-export default function IconPathButton({
- icon,
+export default function PathLoaderButton({
path,
+ icon,
prefetch,
- loaderDelay = 250,
+ loaderDelay = 100,
shouldScroll = true,
shouldReplace,
spinnerColor,
+ styleAsLink,
+ className,
+ children,
}: {
- icon: JSX.Element
path: string
+ icon?: JSX.Element
prefetch?: boolean
loaderDelay?: number
shouldScroll?: boolean
shouldReplace?: boolean
spinnerColor?: SpinnerColor
+ styleAsLink?: boolean
+ className?: string
+ children?: ReactNode
}) {
const router = useRouter();
@@ -47,8 +52,9 @@ export default function IconPathButton({
}, [prefetch, router, path]);
return (
- startTransition(() => {
if (shouldReplace) {
router.replace(path, { scroll: shouldScroll });
@@ -57,13 +63,10 @@ export default function IconPathButton({
}
})}
isLoading={shouldShowLoader}
- className={clsx(
- 'translate-y-[-0.5px]',
- 'active:translate-y-[1px]',
- 'text-medium',
- 'active:text-gray-600 dark:active:text-gray-300',
- )}
- spinnerColor={spinnerColor ?? 'text'}
- />
+ spinnerColor={spinnerColor}
+ styleAsLink={styleAsLink}
+ >
+ {children}
+
);
}
diff --git a/src/photo/PhotoEditPageClient.tsx b/src/photo/PhotoEditPageClient.tsx
index 218d35a4..77b83492 100644
--- a/src/photo/PhotoEditPageClient.tsx
+++ b/src/photo/PhotoEditPageClient.tsx
@@ -21,10 +21,14 @@ export default function PhotoEditPageClient({
photo,
uniqueTags,
hasAiTextGeneration,
+ imageThumbnailBase64,
+ blurData,
}: {
photo: Photo
uniqueTags: TagsWithMeta
hasAiTextGeneration: boolean
+ imageThumbnailBase64: string
+ blurData: string
}) {
const seedExifData = { url: photo.url };
@@ -48,7 +52,10 @@ export default function PhotoEditPageClient({
hasTextContent,
setHasTextContent,
aiContent,
- } = usePhotoFormParent({ photoForm });
+ } = usePhotoFormParent({
+ photoForm,
+ imageThumbnailBase64,
+ });
return (
}
@@ -168,6 +170,10 @@ export default function PhotoLarge({
{photo.takenAtNaiveFormatted}