fix: properly cancel downloads

This commit is contained in:
Adrian Castro
2024-03-26 21:12:58 +01:00
parent a86b1a0ea3
commit b9f83c3f4f

View File

@@ -68,7 +68,7 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
useDownloadHistoryStore.setState({ downloads }); useDownloadHistoryStore.setState({ downloads });
}, [downloads]); }, [downloads]);
const cancellationFlags: Record<string, boolean> = {}; const cancellationFlags = useState<Record<string, boolean>>({})[0];
const setCancellationFlag = (downloadId: string, flag: boolean): void => { const setCancellationFlag = (downloadId: string, flag: boolean): void => {
cancellationFlags[downloadId] = flag; cancellationFlags[downloadId] = flag;
@@ -226,26 +226,28 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
for (const [index, segment] of segments.entries()) { for (const [index, segment] of segments.entries()) {
if (getCancellationFlag(downloadId)) { if (getCancellationFlag(downloadId)) {
await FileSystem.deleteAsync(segmentDir, { idempotent: true }); await cleanupDownload(segmentDir, downloadId);
break; return;
} }
const segmentFile = `${segmentDir}${index}.ts`; const segmentFile = `${segmentDir}${index}.ts`;
localSegmentPaths.push(segmentFile); localSegmentPaths.push(segmentFile);
const downloadResumable = FileSystem.createDownloadResumable(
segment,
segmentFile,
{ headers },
);
try { try {
await downloadResumable.downloadAsync(); await downloadSegment(segment, segmentFile, headers);
if (getCancellationFlag(downloadId)) {
await cleanupDownload(segmentDir, downloadId);
return;
}
segmentsDownloaded++; segmentsDownloaded++;
updateProgress(); updateProgress();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
if (getCancellationFlag(downloadId)) { if (getCancellationFlag(downloadId)) {
break; await cleanupDownload(segmentDir, downloadId);
return;
} }
} }
} }
@@ -266,6 +268,24 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
return asset; return asset;
}; };
const downloadSegment = async (
segmentUrl: string,
segmentFile: string,
headers: Record<string, string>,
) => {
const downloadResumable = FileSystem.createDownloadResumable(
segmentUrl,
segmentFile,
{ headers },
);
await downloadResumable.downloadAsync();
};
const cleanupDownload = async (segmentDir: string, downloadId: string) => {
await FileSystem.deleteAsync(segmentDir, { idempotent: true });
removeDownload(downloadId);
};
async function ensureDirExists(dir: string) { async function ensureDirExists(dir: string) {
await FileSystem.deleteAsync(dir, { idempotent: true }); await FileSystem.deleteAsync(dir, { idempotent: true });
await FileSystem.makeDirectoryAsync(dir, { intermediates: true }); await FileSystem.makeDirectoryAsync(dir, { intermediates: true });