mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-18 10:13:43 +08:00
Implement streaming search API and enhance video availability checks with loading animation
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
interface SearchLoadingAnimationProps {
|
||||
currentSource?: string;
|
||||
checkedSources?: number;
|
||||
totalSources?: number;
|
||||
checkedVideos?: number;
|
||||
totalVideos?: number;
|
||||
stage?: 'searching' | 'checking';
|
||||
}
|
||||
|
||||
export function SearchLoadingAnimation({
|
||||
currentSource,
|
||||
checkedSources = 0,
|
||||
totalSources = 16,
|
||||
checkedVideos = 0,
|
||||
totalVideos = 0,
|
||||
stage = 'searching'
|
||||
}: SearchLoadingAnimationProps) {
|
||||
const [dots, setDots] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const dotInterval = setInterval(() => {
|
||||
setDots((prev) => (prev.length >= 3 ? '' : prev + '.'));
|
||||
}, 500);
|
||||
return () => clearInterval(dotInterval);
|
||||
}, []);
|
||||
|
||||
// Calculate unified progress (0-100%)
|
||||
// Stage 1: Search sources (0-60%)
|
||||
// Stage 2: Check videos (60-100%)
|
||||
let progress = 0;
|
||||
let statusText = '';
|
||||
|
||||
if (stage === 'searching') {
|
||||
progress = totalSources > 0 ? (checkedSources / totalSources) * 60 : 0;
|
||||
statusText = `${checkedSources}/${totalSources} 个源`;
|
||||
} else if (stage === 'checking') {
|
||||
progress = 60 + (totalVideos > 0 ? (checkedVideos / totalVideos) * 40 : 0);
|
||||
statusText = `${checkedVideos}/${totalVideos} 个视频`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full space-y-3 animate-fade-in">
|
||||
{/* Loading Message with Icon */}
|
||||
<div className="flex items-center justify-center gap-3">
|
||||
{/* Spinning Icon */}
|
||||
<svg className="w-5 h-5 animate-spin-slow" viewBox="0 0 24 24">
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
fill="none"
|
||||
stroke="var(--accent-color)"
|
||||
strokeWidth="3"
|
||||
strokeDasharray="60 40"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span className="text-sm font-medium text-[var(--text-color-secondary)]">
|
||||
{stage === 'searching' ? '正在搜索视频源' : '正在检测视频可用性'}{dots}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Progress Bar - Unified 0-100% */}
|
||||
<div className="w-full">
|
||||
<div
|
||||
className="h-1 bg-[color-mix(in_srgb,var(--glass-bg)_50%,transparent)] overflow-hidden"
|
||||
style={{ borderRadius: 'var(--radius-full)' }}
|
||||
>
|
||||
<div
|
||||
className="h-full bg-[var(--accent-color)] transition-all duration-500 ease-out relative"
|
||||
style={{
|
||||
width: `${progress}%`,
|
||||
borderRadius: 'var(--radius-full)'
|
||||
}}
|
||||
>
|
||||
{/* Shimmer Effect */}
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/30 to-transparent animate-shimmer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Progress Info - Real-time count */}
|
||||
<div className="flex items-center justify-between mt-2 text-xs text-[var(--text-color-secondary)]">
|
||||
<span>{statusText}</span>
|
||||
<span className="font-medium">{Math.round(progress)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user