diff --git a/src/admin/AdminPhotoMenuClient.tsx b/src/admin/AdminPhotoMenuClient.tsx index d2b20097..b3b8f318 100644 --- a/src/admin/AdminPhotoMenuClient.tsx +++ b/src/admin/AdminPhotoMenuClient.tsx @@ -10,12 +10,15 @@ import { usePathname } from 'next/navigation'; import { BiTrash } from 'react-icons/bi'; import MoreMenu from '@/components/MoreMenu'; import { useAppState } from '@/state/AppState'; +import { RevalidatePhotos } from '@/photo/InfinitePhotoScroll'; export default function AdminPhotoMenuClient({ photo, + revalidatePhoto, ...props }: Omit, 'items'> & { photo: Photo + revalidatePhoto?: RevalidatePhotos }) { const { isUserSignedIn } = useAppState(); @@ -46,7 +49,7 @@ export default function AdminPhotoMenuClient({ action: () => toggleFavoritePhotoAction( photo.id, shouldRedirectFav, - ), + ).then(() => revalidatePhoto?.()), }, { label: 'Delete', icon: { + revalidatePhoto?.(true); + }); } }, }, diff --git a/src/photo/InfinitePhotoScroll.tsx b/src/photo/InfinitePhotoScroll.tsx index a5084ed4..81a9c6e6 100644 --- a/src/photo/InfinitePhotoScroll.tsx +++ b/src/photo/InfinitePhotoScroll.tsx @@ -8,6 +8,9 @@ import SiteGrid from '@/components/SiteGrid'; import Spinner from '@/components/Spinner'; import { getPhotosAction } from '@/photo/actions'; import { useAppState } from '@/state/AppState'; +import { Photo } from '.'; + +export type RevalidatePhotos = (revalidateRemainingPhotos?: boolean) => void; export default function InfinitePhotoScroll({ key = 'PHOTOS', @@ -15,7 +18,6 @@ export default function InfinitePhotoScroll({ itemsPerPage = 12, prefetch = true, triggerOnView = true, - debug = true, }: { key?: string initialOffset?: number @@ -28,27 +30,25 @@ export default function InfinitePhotoScroll({ const buttonRef = useRef(null); - const fetcher = useCallback((key: string) => { - if (debug) { console.log('Fetching', key); } - const offset = parseInt(key.split('-')[1]); - return getPhotosAction( - initialOffset + offset * itemsPerPage, + const fetcher = useCallback(([_key, size]: [string, number]) => + getPhotosAction( + initialOffset + size * itemsPerPage, itemsPerPage, - key, - ); - }, [initialOffset, itemsPerPage, debug]); + ) + , [initialOffset, itemsPerPage]); - const { data, isLoading, error, mutate, size, setSize } = useSwrInfinite( - (size: number, prev: []) => prev && prev.length === 0 - ? null - :`${key}-${size}`, - fetcher, - { - revalidateOnFocus: isUserSignedIn, - revalidateOnReconnect: isUserSignedIn, - revalidateFirstPage: isUserSignedIn, - }, - ); + const { data, isLoading, error, mutate, size, setSize } = + useSwrInfinite( + (size: number, prev: []) => prev && prev.length === 0 + ? null + : [key, size], + fetcher, + { + revalidateOnFocus: isUserSignedIn, + revalidateOnReconnect: isUserSignedIn, + revalidateFirstPage: isUserSignedIn, + }, + ); const isFinished = useMemo(() => data && data[data.length - 1]?.length < itemsPerPage @@ -56,7 +56,7 @@ export default function InfinitePhotoScroll({ useEffect(() => { if (prefetch) { - preload(`${key}-${size ?? 0 + 1}`, fetcher); + preload([key, size ?? 0 + 1], fetcher); } }, [prefetch, key, size, fetcher]); @@ -81,7 +81,17 @@ export default function InfinitePhotoScroll({ return (
{data &&
- {data.map((photos, i) => )} + {data.map((photos, i) => + { + mutate(data, { + revalidate: (_data: any, [_, size]:[string, number]) => + revalidateRemainingPhotos ? size >= i : size === i, + } as any); + }} + />)}
} {!isFinished &&
- +
diff --git a/src/photo/PhotosLarge.tsx b/src/photo/PhotosLarge.tsx index 1c0f570d..b0a0505c 100644 --- a/src/photo/PhotosLarge.tsx +++ b/src/photo/PhotosLarge.tsx @@ -1,15 +1,18 @@ import AnimateItems from '@/components/AnimateItems'; import { Photo } from '.'; import PhotoLarge from './PhotoLarge'; +import { RevalidatePhotos } from './InfinitePhotoScroll'; export default function PhotosLarge({ photos, animate = true, prefetchFirstPhotoLinks, + revalidatePhotos, }: { photos: Photo[] animate?: boolean prefetchFirstPhotoLinks?: boolean + revalidatePhotos?: RevalidatePhotos }) { return ( )} itemKeys={photos.map(photo => photo.id)} /> diff --git a/src/photo/actions.tsx b/src/photo/actions.tsx index 6f103858..cd4a24bb 100644 --- a/src/photo/actions.tsx +++ b/src/photo/actions.tsx @@ -220,14 +220,5 @@ export async function getPhotoItemsAction(query: string) { : []; } -export const getPhotosAction = async ( - offset: number, - limit: number, - cacheKey: string, -) => - getPhotosCachedCached({ offset, limit }).then(photos => - photos.map(photo => ({ - ...photo, - cacheKey, - })) - ); +export const getPhotosAction = async (offset: number, limit: number) => + getPhotosCachedCached({ offset, limit }); diff --git a/src/photo/index.ts b/src/photo/index.ts index f44d5bbf..a742c079 100644 --- a/src/photo/index.ts +++ b/src/photo/index.ts @@ -83,7 +83,6 @@ export interface Photo extends PhotoDb { exposureTimeFormatted?: string exposureCompensationFormatted?: string takenAtNaiveFormatted: string - cacheKey?: string } export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => {