/* eslint-disable @next/next/no-img-element */ import { useEffect, useRef, useState } from 'react'; import Lightbox from 'yet-another-react-lightbox'; import 'yet-another-react-lightbox/styles.css'; import { Message } from './ChatWindow'; type Image = { url: string; img_src: string; title: string; }; const SearchImages = ({ query, chatHistory, messageId, onImagesLoaded, }: { query: string; chatHistory: Message[]; messageId: string; onImagesLoaded?: (count: number) => void; }) => { const [images, setImages] = useState(null); const [loading, setLoading] = useState(true); const [open, setOpen] = useState(false); const [slides, setSlides] = useState([]); const [displayLimit, setDisplayLimit] = useState(10); // Initially show only 10 images const loadedMessageIdsRef = useRef>(new Set()); // Function to show more images when the Show More button is clicked const handleShowMore = () => { // If we're already showing all images, don't do anything if (images && displayLimit >= images.length) return; // Otherwise, increase the display limit by 10, or show all images setDisplayLimit((prev) => images ? Math.min(prev + 10, images.length) : prev, ); }; useEffect(() => { // Skip fetching if images are already loaded for this message if (loadedMessageIdsRef.current.has(messageId)) { return; } const fetchImages = async () => { // Mark as loaded to prevent refetching loadedMessageIdsRef.current.add(messageId); setLoading(true); const chatModelProvider = localStorage.getItem('chatModelProvider'); const chatModel = localStorage.getItem('chatModel'); const customOpenAIBaseURL = localStorage.getItem('openAIBaseURL'); const customOpenAIKey = localStorage.getItem('openAIApiKey'); const ollamaContextWindow = localStorage.getItem('ollamaContextWindow') || '2048'; try { const res = await fetch(`/api/images`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ query: query, chatHistory: chatHistory, chatModel: { provider: chatModelProvider, model: chatModel, ...(chatModelProvider === 'custom_openai' && { customOpenAIBaseURL: customOpenAIBaseURL, customOpenAIKey: customOpenAIKey, }), ...(chatModelProvider === 'ollama' && { ollamaContextWindow: parseInt(ollamaContextWindow), }), }, }), }); const data = await res.json(); const images = data.images ?? []; setImages(images); setSlides( images.map((image: Image) => { return { src: image.img_src, }; }), ); if (onImagesLoaded && images.length > 0) { onImagesLoaded(images.length); } } catch (error) { console.error('Error fetching images:', error); } finally { setLoading(false); } }; fetchImages(); }, [query, messageId, chatHistory, onImagesLoaded]); return ( <> {loading && (
{[...Array(4)].map((_, i) => (
))}
)} {images !== null && images.length > 0 && ( <>
{images.slice(0, displayLimit).map((image, i) => ( { setOpen(true); setSlides([ slides[i], ...slides.slice(0, i), ...slides.slice(i + 1), ]); }} key={i} src={image.img_src} alt={image.title} className="h-full w-full aspect-video object-cover rounded-lg transition duration-200 active:scale-95 hover:scale-[1.02] cursor-zoom-in" /> ))}
{images.length > displayLimit && (
)} setOpen(false)} slides={slides} /> )} ); }; export default SearchImages;