From 2e3dc8a47ef4ffc179e72e4a6f2055fd36b362ce Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sun, 10 Sep 2023 16:07:28 -0500 Subject: [PATCH] Add loading indicator to share button --- src/app/(isr)/p/[photoId]/layout.tsx | 2 +- src/components/IconButton.tsx | 10 +++++-- src/photo/PhotoLarge.tsx | 27 ++++++----------- src/photo/SharePhotoButton.tsx | 44 ++++++++++++++++++++++++++++ src/site/SiteChecklistClient.tsx | 2 +- 5 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 src/photo/SharePhotoButton.tsx diff --git a/src/app/(isr)/p/[photoId]/layout.tsx b/src/app/(isr)/p/[photoId]/layout.tsx index fc34b456..53df44ec 100644 --- a/src/app/(isr)/p/[photoId]/layout.tsx +++ b/src/app/(isr)/p/[photoId]/layout.tsx @@ -79,7 +79,7 @@ export default async function PhotoPage({ key={photo.id} photo={photo} priority - showShare + prefetchShare />]} /> void isLoading?: boolean + className?: string }) { return ( - + {!isLoading ? : } diff --git a/src/photo/PhotoLarge.tsx b/src/photo/PhotoLarge.tsx index 16cb1032..6ca27b9c 100644 --- a/src/photo/PhotoLarge.tsx +++ b/src/photo/PhotoLarge.tsx @@ -3,17 +3,17 @@ import SiteGrid from '@/components/SiteGrid'; import ImageLarge from '@/components/ImageLarge'; import { cc } from '@/utility/css'; import Link from 'next/link'; -import { TbPhotoShare } from 'react-icons/tb'; import { routeForPhoto } from '@/site/routes'; +import SharePhotoButton from './SharePhotoButton'; export default function PhotoLarge({ photo, priority, - showShare, + prefetchShare, }: { photo: Photo priority?: boolean - showShare?: boolean + prefetchShare?: boolean }) { const renderMiniGrid = (children: JSX.Element) =>
{photo.takenAtNaiveFormatted}
- {showShare && - - - } +
+ +
)} } /> diff --git a/src/photo/SharePhotoButton.tsx b/src/photo/SharePhotoButton.tsx new file mode 100644 index 00000000..705451cf --- /dev/null +++ b/src/photo/SharePhotoButton.tsx @@ -0,0 +1,44 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import { useEffect, useTransition } from 'react'; +import { Photo } from '.'; +import { routeForPhoto } from '@/site/routes'; +import IconButton from '@/components/IconButton'; +import { TbPhotoShare } from 'react-icons/tb'; +import { cc } from '@/utility/css'; + +export default function SharePhotoButton({ + photo, + prefetch, +}: { + photo: Photo + prefetch?: boolean +}) { + const router = useRouter(); + + const shareRoute = routeForPhoto(photo, true); + + const [isPending, startTransition] = useTransition(); + + useEffect(() => { + if (prefetch) { + router.prefetch(shareRoute); + } + }, [prefetch, router, shareRoute]); + + return ( + startTransition(() => + router.push(shareRoute))} + isLoading={isPending} + className={cc( + 'active:translate-y-[1px]', + 'text-gray-500 active:text-gray-600', + 'dark:text-gray-400 dark:active:text-gray-300', + )} + > + + + ); +} diff --git a/src/site/SiteChecklistClient.tsx b/src/site/SiteChecklistClient.tsx index 6934b186..168e2c17 100644 --- a/src/site/SiteChecklistClient.tsx +++ b/src/site/SiteChecklistClient.tsx @@ -136,7 +136,7 @@ export default function SiteChecklistClient({
{secret} -
+
{ navigator.clipboard.writeText(secret);