diff --git a/web/src/components/overlay/ImagePicker.tsx b/web/src/components/overlay/ImagePicker.tsx index 3dde61f65..b7cc97cbd 100644 --- a/web/src/components/overlay/ImagePicker.tsx +++ b/web/src/components/overlay/ImagePicker.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import useSWR from "swr"; import { @@ -15,11 +15,13 @@ import { cn } from "@/lib/utils"; import { Event } from "@/types/event"; import { useApiHost } from "@/api"; import { isDesktop, isMobile } from "react-device-detect"; +import ActivityIndicator from "../indicators/activity-indicator"; type ImagePickerProps = { selectedImageId?: string; setSelectedImageId?: (id: string) => void; camera: string; + limit?: number; direct?: boolean; className?: string; }; @@ -28,6 +30,7 @@ export default function ImagePicker({ selectedImageId, setSelectedImageId, camera, + limit = 100, direct = false, className, }: ImagePickerProps) { @@ -35,9 +38,10 @@ export default function ImagePicker({ const [open, setOpen] = useState(false); const containerRef = useRef(null); const [searchTerm, setSearchTerm] = useState(""); + const [loadedImages, setLoadedImages] = useState>(new Set()); const { data: events } = useSWR( - `events?camera=${camera}&limit=100`, + `events?camera=${camera}&limit=${limit}`, { revalidateOnFocus: false, }, @@ -74,6 +78,10 @@ export default function ImagePicker({ [setSelectedImageId, direct], ); + const handleImageLoad = useCallback((imageId: string) => { + setLoadedImages((prev) => new Set(prev).add(imageId)); + }, []); + const renderSearchInput = () => ( handleImageSelect(image.id)} + onLoad={() => handleImageLoad(image.id)} + loading="lazy" /> + {!loadedImages.has(image.id) && ( +
+ +
+ )} )) )} ); + // Reset loaded images when images change + useEffect(() => { + setLoadedImages(new Set()); + }, [images]); + if (direct) { return (
@@ -141,15 +161,24 @@ export default function ImagePicker({
- {selectedImage?.label +
+ {selectedImage?.label handleImageLoad(selectedImageId || "")} + loading="lazy" + /> + {selectedImageId && !loadedImages.has(selectedImageId) && ( +
+ +
+ )} +
{selectedImage?.label || selectedImageId} {selectedImage?.sub_label