diff --git a/frontend/src/pages/Watch.jsx b/frontend/src/pages/Watch.jsx index 057b7de..e8dc555 100644 --- a/frontend/src/pages/Watch.jsx +++ b/frontend/src/pages/Watch.jsx @@ -697,24 +697,22 @@ export default function Watch() { .catch(() => { pollTimerRef.current = setTimeout(() => pollForFile(url), 1500); }); }, [fileReady]); + // Only poll once the backend confirms the download is fully written. + // Polling before status==="complete" risks playing a partial file. useEffect(() => { - if (!dlStatus?.file_url || fileReady || !playRequested) return; - pollForFile(dlStatus.file_url); + if (fileReady || !playRequested) return; + const backendDone = dlStatus?.status === "complete" || !!video?.is_downloaded; + const fileUrl = dlStatus?.file_url ?? (video?.is_downloaded ? `/files/${youtubeVideoId}.mp4` : null); + if (!backendDone || !fileUrl) return; + pollForFile(fileUrl); return () => clearTimeout(pollTimerRef.current); - }, [dlStatus?.file_url, fileReady, pollForFile, playRequested]); - - useEffect(() => { - if (!video?.is_downloaded || fileReady || !playRequested) return; - pollForFile(`/files/${youtubeVideoId}.mp4`); - }, [video?.is_downloaded, playRequested]); // eslint-disable-line react-hooks/exhaustive-deps + }, [playRequested, fileReady, dlStatus?.status, dlStatus?.file_url, video?.is_downloaded, youtubeVideoId, pollForFile]); // eslint-disable-line react-hooks/exhaustive-deps const downloadMut = useMutation({ mutationFn: () => createDownload(youtubeVideoId, selectedQuality), onSuccess: (res) => { - const dl = res.data; - setDownloadId(dl.id); + setDownloadId(res.data.id); refetchVideo(); - if (dl.status === "complete" && dl.file_url) pollForFile(dl.file_url); }, });