'use client'; import { useEffect, useState, useRef, useCallback } from 'react'; interface SearchLoadingAnimationProps { currentSource?: string; checkedSources?: number; totalSources?: number; isPaused?: boolean; onComplete?: (checkedSources: number, totalSources: number) => void; } export function SearchLoadingAnimation({ currentSource, checkedSources = 0, totalSources = 16, isPaused = false, onComplete, }: SearchLoadingAnimationProps) { const [dots, setDots] = useState(''); const dotIntervalRef = useRef(null); const hasCalledComplete = useRef(false); // Calculate progress (0-100%) const progress = totalSources > 0 ? (checkedSources / totalSources) * 100 : 0; const isComplete = progress >= 100; // Animation pause/resume logic - Optimized interval useEffect(() => { if (isPaused || isComplete) { if (dotIntervalRef.current) { clearInterval(dotIntervalRef.current); dotIntervalRef.current = null; } return; } dotIntervalRef.current = setInterval(() => { setDots((prev) => (prev.length >= 3 ? '' : prev + '.')); }, 600); // Increased from 500ms to 600ms for better performance return () => { if (dotIntervalRef.current) { clearInterval(dotIntervalRef.current); dotIntervalRef.current = null; } }; }, [isPaused, isComplete]); // Call onComplete callback when animation finishes useEffect(() => { if (isComplete && onComplete && !hasCalledComplete.current) { hasCalledComplete.current = true; // Small delay to allow animation to settle const timeout = setTimeout(() => { onComplete(checkedSources, totalSources); }, 100); return () => clearTimeout(timeout); } }, [isComplete, onComplete, checkedSources, totalSources]); const statusText = `${checkedSources}/${totalSources} 个源`; return (
{/* Loading Message with Icon */}
{/* Spinning Icon */} 正在搜索视频源{dots}
{/* Progress Bar - Unified 0-100% */}
{/* Shimmer Effect - Optimized for GPU with contain for better performance */}
{/* Progress Info - Real-time count with pause indicator */}
{statusText} {isPaused && ( 已暂停 )} {isComplete && ( 完成 )} {Math.round(progress)}%
); }