import React, { useState, KeyboardEvent } from 'react'; import { FaSearch, FaSpinner, FaTimes } from 'react-icons/fa'; import { getInvidiousSearchURL, INVIDIOUS_BASE_URL } from '../config'; interface InvidiousVideoThumbnail { quality: string; url: string; width: number; height: number; } interface InvidiousResult { type: string; title: string; videoId: string; author: string; videoThumbnails?: InvidiousVideoThumbnail[]; } interface InvidiousSearchModalProps { isOpen: boolean; onClose: () => void; onSelectVideo: (url: string) => void; } const ResultCell: React.FC<{ result: InvidiousResult, onClick: () => void }> = ({ result, onClick, ...props }) => { const thumbnailUrl = (result: InvidiousResult) => { if (!result.videoThumbnails) return '/assets/placeholder.jpg'; const thumbnail = result.videoThumbnails.find(t => t.quality === 'medium'); return thumbnail ? `${INVIDIOUS_BASE_URL}${thumbnail.url}` : '/assets/placeholder.jpg'; }; return (
{result.title}

{result.title}

{result.author}

); }; const InvidiousSearchModal: React.FC = ({ isOpen, onClose, onSelectVideo }) => { const [searchQuery, setSearchQuery] = useState(''); const [results, setResults] = useState([]); const [isLoading, setIsLoading] = useState(false); const handleSearch = async () => { if (!searchQuery.trim()) return; setIsLoading(true); try { const response = await fetch(getInvidiousSearchURL(searchQuery)); const data = await response.json(); const videoResults = data.filter((item: InvidiousResult) => { return item.type === 'video' || item.type === 'playlist' }); setResults(videoResults); } catch (error) { console.error('Failed to search:', error); } finally { setIsLoading(false); } }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter') { handleSearch(); } }; const _onSelectVideo = (url: string) => { setSearchQuery(''); setResults([]); onSelectVideo(url); }; if (!isOpen) return null; return (

Search YouTube (Invidious)

setSearchQuery(e.target.value)} onKeyDown={handleKeyDown} placeholder="Search videos..." className="p-2 rounded-lg border-2 border-violet-500 flex-grow bg-black/20 text-white" />
{isLoading ? (
Searching...
) : (
{results.map((result) => ( _onSelectVideo(`https://www.youtube.com/watch?v=${result.videoId}`)} /> ))}
)}
); }; export default InvidiousSearchModal;