import { useEffect, useState } from 'react' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import type { FeedVideoDto } from '../api/client' import { downloadVideo, getDownloadStatus } from '../api/client' const ACTIVE_STATUSES = ['queued', 'downloading', 'postprocessing'] const STATUS_LABELS: Record = { queued: 'В очереди...', postprocessing: 'Обработка...', } interface Props { video: FeedVideoDto } function DownloadButton({ video }: Props) { const queryClient = useQueryClient() const [polling, setPolling] = useState(ACTIVE_STATUSES.includes(video.local.status)) const statusQuery = useQuery({ queryKey: ['download-status', video.youtube_video_id], queryFn: () => getDownloadStatus(video.youtube_video_id), enabled: polling, refetchInterval: (query) => (query.state.data && ACTIVE_STATUSES.includes(query.state.data.status) ? 2000 : false), initialData: polling ? { status: video.local.status, progress_percent: video.local.progress_percent, media_url: video.local.media_url, error_message: null, } : undefined, }) const downloadMutation = useMutation({ mutationFn: () => downloadVideo(video.youtube_video_id), onSuccess: (data) => { queryClient.setQueryData(['download-status', video.youtube_video_id], data) setPolling(true) }, }) const current = polling ? statusQuery.data : undefined const status = current?.status ?? video.local.status const percent = current?.progress_percent ?? video.local.progress_percent useEffect(() => { if (current && !ACTIVE_STATUSES.includes(current.status)) { setPolling(false) if (current.status === 'completed' || current.status === 'failed') { queryClient.invalidateQueries({ queryKey: ['feed'] }) } } }, [current?.status, queryClient]) if (status === 'completed') { return ✓ На сервере } if (status === 'downloading') { return {percent ?? 0}% } if (status === 'queued' || status === 'postprocessing') { return {STATUS_LABELS[status]} } if (status === 'failed') { return ( Ошибка ) } return ( ) } export default DownloadButton