import { useCallback, useMemo } from "react"; import { useApiHost } from "@/api"; import { getIconForLabel } from "@/utils/iconUtil"; import useSWR from "swr"; import { FrigateConfig } from "@/types/frigateConfig"; import { isIOS, isSafari } from "react-device-detect"; import Chip from "@/components/indicators/Chip"; import useImageLoaded from "@/hooks/use-image-loaded"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; import ImageLoadingIndicator from "../indicators/ImageLoadingIndicator"; import { SearchResult } from "@/types/search"; import { cn } from "@/lib/utils"; import { TooltipPortal } from "@radix-ui/react-tooltip"; import useContextMenu from "@/hooks/use-contextmenu"; import { getTranslatedLabel } from "@/utils/i18n"; type SearchThumbnailProps = { searchResult: SearchResult; onClick: (searchResult: SearchResult, ctrl: boolean, detail: boolean) => void; }; export default function SearchThumbnail({ searchResult, onClick, }: SearchThumbnailProps) { const apiHost = useApiHost(); const { data: config } = useSWR("config"); const [imgRef, imgLoaded, onImgLoad] = useImageLoaded(); // interactions useContextMenu(imgRef, () => { onClick(searchResult, true, false); }); const handleOnClick = useCallback( (e: React.MouseEvent) => { if (e.metaKey) { e.stopPropagation(); onClick(searchResult, true, false); } }, [searchResult, onClick], ); const hasRecognizedPlate = useMemo( () => (searchResult.data.recognized_license_plate?.length || 0) > 0, [searchResult], ); const objectLabel = useMemo(() => { if (!config) { return searchResult.label; } if (!searchResult.sub_label) { return `${searchResult.label}${hasRecognizedPlate ? "-plate" : ""}`; } if ( config.model.attributes_map[searchResult.label]?.includes( searchResult.sub_label, ) ) { return searchResult.sub_label; } return `${searchResult.label}-verified`; }, [config, hasRecognizedPlate, searchResult]); const objectDetail = useMemo(() => { if (!config) { return undefined; } if (!searchResult.sub_label) { if (hasRecognizedPlate) { return `(${searchResult.data.recognized_license_plate})`; } return undefined; } if ( config.model.attributes_map[searchResult.label]?.includes( searchResult.sub_label, ) ) { return ""; } return `(${searchResult.sub_label})`; }, [config, hasRecognizedPlate, searchResult]); return (
onClick(searchResult, false, true)} >
{ onImgLoad(); }} />
onClick(searchResult, false, true)} > {getIconForLabel(objectLabel, "size-3 text-white")} {Math.floor( (searchResult.data.score ?? searchResult.data.top_score ?? searchResult.top_score) * 100, )} % {objectDetail}
{[searchResult.sub_label ?? objectLabel] .filter( (item) => item !== undefined && !item.includes("-verified"), ) .map((text) => getTranslatedLabel(text)) .sort() .join(", ") .replaceAll("-verified", "")}
); }