Dismiss admin banner when times are no longer recent
This commit is contained in:
parent
54cd4de52b
commit
348b2ecc80
@ -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 (
|
||||
<AdminNavClient {...{ items, mostRecentUpdate }} />
|
||||
<AdminNavClient {...{ items, mostRecentPhotoUpdateTime }} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -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 (
|
||||
<SiteGrid
|
||||
|
||||
@ -20,7 +20,7 @@ export default function AdminPhotoMenuClient({
|
||||
photo: Photo
|
||||
revalidatePhoto?: RevalidatePhoto
|
||||
}) {
|
||||
const { isUserSignedIn, addAdminUpdate } = useAppState();
|
||||
const { isUserSignedIn, registerAdminUpdate } = useAppState();
|
||||
|
||||
const isFav = isPhotoFav(photo);
|
||||
const path = usePathname();
|
||||
@ -64,7 +64,7 @@ export default function AdminPhotoMenuClient({
|
||||
shouldRedirectDelete,
|
||||
).then(() => {
|
||||
revalidatePhoto?.(photo.id, true);
|
||||
addAdminUpdate?.();
|
||||
registerAdminUpdate?.();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@ -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 <SubmitButtonWithStatus
|
||||
{...rest}
|
||||
|
||||
@ -16,8 +16,8 @@ export interface AppStateContext {
|
||||
setShouldRespondToKeyboardCommands?: Dispatch<SetStateAction<boolean>>
|
||||
isCommandKOpen?: boolean
|
||||
setIsCommandKOpen?: Dispatch<SetStateAction<boolean>>
|
||||
adminUpdates?: Date[]
|
||||
addAdminUpdate?: () => void
|
||||
adminUpdateTimes?: Date[]
|
||||
registerAdminUpdate?: () => void
|
||||
shouldShowBaselineGrid?: boolean
|
||||
setShouldShowBaselineGrid?: Dispatch<SetStateAction<boolean>>
|
||||
clearNextPhotoAnimation?: () => void
|
||||
|
||||
@ -26,7 +26,7 @@ export default function AppStateProvider({
|
||||
useState(true);
|
||||
const [isCommandKOpen, setIsCommandKOpen] =
|
||||
useState(false);
|
||||
const [adminUpdates, setAdminUpdates] = useState<Date[]>([]);
|
||||
const [adminUpdateTimes, setAdminUpdateTimes] = useState<Date[]>([]);
|
||||
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),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user