diff --git a/src/admin/AdminNav.tsx b/src/admin/AdminNav.tsx
index ecc00562..2185390f 100644
--- a/src/admin/AdminNav.tsx
+++ b/src/admin/AdminNav.tsx
@@ -16,7 +16,7 @@ export default async function AdminNav() {
countPhotos,
countUploads,
countTags,
- mostRecentUpdate,
+ mostRecentPhotoUpdateTime,
] = await Promise.all([
getPhotosCountIncludingHiddenCached().catch(() => 0),
getStorageUploadUrlsNoStore()
@@ -53,6 +53,6 @@ export default async function AdminNav() {
if (countTags > 0) { items.push(navItemTags); }
return (
-
+
);
}
diff --git a/src/admin/AdminNavClient.tsx b/src/admin/AdminNavClient.tsx
index 58348a5e..69709277 100644
--- a/src/admin/AdminNavClient.tsx
+++ b/src/admin/AdminNavClient.tsx
@@ -12,31 +12,43 @@ import { clsx } from 'clsx/lite';
import { differenceInMinutes } from 'date-fns';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
-import { useMemo } from 'react';
+import { useEffect, useMemo, useState } from 'react';
import { BiCog } from 'react-icons/bi';
import { FaRegClock } from 'react-icons/fa';
-const RECENCY_THRESHOLD = 5;
+const areTimesRecent = (dates: Date[]) => dates
+ .some(date => differenceInMinutes(new Date(), date) < 5);
export default function AdminNavClient({
items,
- mostRecentUpdate,
+ mostRecentPhotoUpdateTime,
}: {
items: {
label: string,
href: string,
count: number,
}[]
- mostRecentUpdate?: Date
+ mostRecentPhotoUpdateTime?: Date
}) {
const pathname = usePathname();
- const { adminUpdates = [] } = useAppState();
+ const { adminUpdateTimes = [] } = useAppState();
- const shouldShowBanner = useMemo(() =>
- ((mostRecentUpdate ? [mostRecentUpdate] : []).concat(adminUpdates))
- .some(date => differenceInMinutes(new Date(), date) < RECENCY_THRESHOLD)
- , [mostRecentUpdate, adminUpdates]);
+ const updateTimes = useMemo(() =>
+ (mostRecentPhotoUpdateTime ? [mostRecentPhotoUpdateTime] : [])
+ .concat(adminUpdateTimes)
+ , [mostRecentPhotoUpdateTime, adminUpdateTimes]);
+
+ const [shouldShowBanner, setShouldShowBanner] =
+ useState(areTimesRecent(updateTimes));
+
+ useEffect(() => {
+ // Check every 10 seconds if update times are recent
+ const timeout = setTimeout(() =>
+ setShouldShowBanner(areTimesRecent(updateTimes))
+ , 10_000);
+ return () => clearTimeout(timeout);
+ }, [updateTimes]);
return (
{
revalidatePhoto?.(photo.id, true);
- addAdminUpdate?.();
+ registerAdminUpdate?.();
});
}
},
diff --git a/src/admin/DeleteButton.tsx b/src/admin/DeleteButton.tsx
index 7128c24f..7c570903 100644
--- a/src/admin/DeleteButton.tsx
+++ b/src/admin/DeleteButton.tsx
@@ -17,15 +17,15 @@ export default function DeleteButton (
...rest
} = props;
- const { invalidateSwr, addAdminUpdate } = useAppState();
+ const { invalidateSwr, registerAdminUpdate } = useAppState();
const onFormSubmit = useCallback(() => {
onFormSubmitProps?.();
if (clearLocalState) {
invalidateSwr?.();
- addAdminUpdate?.();
+ registerAdminUpdate?.();
}
- }, [onFormSubmitProps, clearLocalState, invalidateSwr, addAdminUpdate]);
+ }, [onFormSubmitProps, clearLocalState, invalidateSwr, registerAdminUpdate]);
return >
isCommandKOpen?: boolean
setIsCommandKOpen?: Dispatch>
- adminUpdates?: Date[]
- addAdminUpdate?: () => void
+ adminUpdateTimes?: Date[]
+ registerAdminUpdate?: () => void
shouldShowBaselineGrid?: boolean
setShouldShowBaselineGrid?: Dispatch>
clearNextPhotoAnimation?: () => void
diff --git a/src/state/AppStateProvider.tsx b/src/state/AppStateProvider.tsx
index becd004b..ac4ecf5b 100644
--- a/src/state/AppStateProvider.tsx
+++ b/src/state/AppStateProvider.tsx
@@ -26,7 +26,7 @@ export default function AppStateProvider({
useState(true);
const [isCommandKOpen, setIsCommandKOpen] =
useState(false);
- const [adminUpdates, setAdminUpdates] = useState([]);
+ const [adminUpdateTimes, setAdminUpdateTimes] = useState([]);
const [shouldShowBaselineGrid, setShouldShowBaselineGrid] =
useState(false);
@@ -35,8 +35,8 @@ export default function AppStateProvider({
const { data } = useSWR('getCurrentUser', getCurrentUser);
useEffect(() => setUserEmail(data?.email ?? undefined), [data]);
- const addAdminUpdate = useCallback(() =>
- setAdminUpdates(updates => [...updates, new Date()])
+ const registerAdminUpdate = useCallback(() =>
+ setAdminUpdateTimes(updates => [...updates, new Date()])
, []);
useEffect(() => {
@@ -60,8 +60,8 @@ export default function AppStateProvider({
setShouldRespondToKeyboardCommands,
isCommandKOpen,
setIsCommandKOpen,
- adminUpdates,
- addAdminUpdate,
+ adminUpdateTimes,
+ registerAdminUpdate,
shouldShowBaselineGrid,
setShouldShowBaselineGrid,
clearNextPhotoAnimation: () => setNextPhotoAnimation?.(undefined),