import { cn } from "@/src/utils/tailwind"; import { useState } from "react"; import Link from "next/link"; import Image from "next/image"; import { Button } from "@/src/components/ui/button"; import { ImageOff, Maximize2, Minimize2 } from "lucide-react"; import { api } from "@/src/utils/api"; import { Skeleton } from "@/src/components/ui/skeleton"; import { captureException } from "@sentry/nextjs"; import { useSession } from "next-auth/react"; /** * Implemented customLoader as we cannot whitelist user provided image domains * Security risks are taken care of by a validation in api.utilities.validateImgUrl * Fetching image will fail if SSL/TLS certificate is invalid or expired, will be handled by onError * Do not use this customLoader in production if you are not using the above mentioned security measures */ const customLoader = ({ src, width, quality, }: { src: string; width: number; quality?: number; }) => { return src + (width && quality ? `?w=${width}&q=${quality || 75}` : ""); }; const ImageErrorDisplay = ({ src, displayError, }: { src: string; displayError: string; }) => (
{src}
); export const ResizableImage = ({ src, alt, isDefaultVisible = false, shouldValidateImageSource = true, }: { src: string; alt?: string; isDefaultVisible?: boolean; shouldValidateImageSource?: boolean; }) => { const [isZoomedIn, setIsZoomedIn] = useState(true); const [hasFetchError, setHasFetchError] = useState(false); const [isImageVisible, setIsImageVisible] = useState(isDefaultVisible); const session = useSession(); const isValidImage = api.utilities.validateImgUrl.useQuery(src, { enabled: session.status === "authenticated" && isImageVisible && shouldValidateImageSource, initialData: { isValid: true }, }); if (session.status !== "authenticated") { return ( ); } if (isValidImage.isLoading && isImageVisible) { return ( Loading image... ); } const displayError = `Cannot load image. ${src.includes("http") ? "Http images are not rendered in Langfuse for security reasons" : "Invalid image URL"}`; return (
{hasFetchError ? ( ) : (
{isImageVisible && isValidImage.data?.isValid ? ( <> {alt { setHasFetchError(true); captureException(error); }} /> ) : (
{src}
)}
)}
); };