import { useEffect, useRef, useState } from 'react' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import type { FeedVideoDto } from '../api/client' import { deleteDownload, 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() // Once we start tracking a download (it was already active on load, or the // user just clicked "Скачать"), the query stays enabled for good -- // refetchInterval alone stops the ticking once the status is terminal. // Disabling the query on completion used to make the button fall back to // the *stale* `video` prop instead of the query's own fresh cache, which // showed "Скачать" again until the page was manually reloaded. const [tracking, setTracking] = useState(ACTIVE_STATUSES.includes(video.local.status)) const statusQuery = useQuery({ queryKey: ['download-status', video.youtube_video_id], queryFn: () => getDownloadStatus(video.youtube_video_id), enabled: tracking, refetchInterval: (query) => query.state.data && ACTIVE_STATUSES.includes(query.state.data.status) ? 2000 : false, }) const downloadMutation = useMutation({ mutationFn: () => downloadVideo(video.youtube_video_id), onSuccess: (data) => { queryClient.setQueryData(['download-status', video.youtube_video_id], data) setTracking(true) }, }) const deleteMutation = useMutation({ mutationFn: () => deleteDownload(video.youtube_video_id), onSuccess: (data) => { queryClient.setQueryData(['download-status', video.youtube_video_id], data) }, }) const status = statusQuery.data?.status ?? video.local.status const percent = statusQuery.data?.progress_percent ?? video.local.progress_percent const prevStatus = useRef(status) useEffect(() => { if (prevStatus.current !== status) { prevStatus.current = status if (status === 'completed' || status === 'failed' || status === 'deleted') { queryClient.invalidateQueries({ queryKey: ['feed'] }) queryClient.invalidateQueries({ queryKey: ['video', video.youtube_video_id] }) } } }, [status, queryClient, video.youtube_video_id]) 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