/* eslint-disable @next/next/no-img-element */ import { PlayCircle } from 'lucide-react'; import { useEffect, useRef, useState } from 'react'; import Lightbox, { GenericSlide, VideoSlide } from 'yet-another-react-lightbox'; import 'yet-another-react-lightbox/styles.css'; import { Message } from './ChatWindow'; type Video = { url: string; img_src: string; title: string; iframe_src: string; }; declare module 'yet-another-react-lightbox' { export interface VideoSlide extends GenericSlide { type: 'video-slide'; src: string; iframe_src: string; } interface SlideTypes { 'video-slide': VideoSlide; } } const Searchvideos = ({ query, chatHistory, messageId, onVideosLoaded, }: { query: string; chatHistory: Message[]; messageId: string; onVideosLoaded?: (count: number) => void; }) => { const [videos, setVideos] = useState(null); const [loading, setLoading] = useState(true); const [open, setOpen] = useState(false); const [slides, setSlides] = useState([]); const [currentIndex, setCurrentIndex] = useState(0); const videoRefs = useRef<(HTMLIFrameElement | null)[]>([]); const hasLoadedRef = useRef(false); useEffect(() => { // Skip fetching if videos are already loaded for this message if (hasLoadedRef.current) { return; } const fetchVideos = async () => { 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/videos`, { 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 videos = data.videos ?? []; setVideos(videos); setSlides( videos.map((video: Video) => { return { type: 'video-slide', iframe_src: video.iframe_src, src: video.img_src, }; }), ); if (onVideosLoaded && videos.length > 0) { onVideosLoaded(videos.length); } // Mark as loaded to prevent refetching hasLoadedRef.current = true; } catch (error) { console.error('Error fetching videos:', error); } finally { setLoading(false); } }; fetchVideos(); // Reset the loading state when component unmounts return () => { hasLoadedRef.current = false; }; }, [query, messageId]); return ( <> {loading && (
{[...Array(4)].map((_, i) => (
))}
)} {videos !== null && videos.length > 0 && ( <>
{videos.map((video, i) => (
{ setOpen(true); setSlides([ slides[i], ...slides.slice(0, i), ...slides.slice(i + 1), ]); }} className="relative transition duration-200 active:scale-95 hover:scale-[1.02] cursor-pointer" key={i} > {video.title}

Video

))}
setOpen(false)} slides={slides} index={currentIndex} on={{ view: ({ index }) => { const previousIframe = videoRefs.current[currentIndex]; if (previousIframe?.contentWindow) { previousIframe.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*', ); } setCurrentIndex(index); }, }} render={{ slide: ({ slide }) => { const index = slides.findIndex((s) => s === slide); return slide.type === 'video-slide' ? (