mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 16:53:25 +00:00
feat: cancel downloads
This commit is contained in:
@@ -23,12 +23,14 @@ export interface DownloadItem {
|
|||||||
statusText?: string;
|
statusText?: string;
|
||||||
asset?: Asset;
|
asset?: Asset;
|
||||||
isHLS?: boolean;
|
isHLS?: boolean;
|
||||||
|
downloadResumable?: FileSystem.DownloadResumable;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DownloadManagerContextType {
|
interface DownloadManagerContextType {
|
||||||
downloads: DownloadItem[];
|
downloads: DownloadItem[];
|
||||||
startDownload: (url: string, type: "mp4" | "hls") => Promise<Asset | void>;
|
startDownload: (url: string, type: "mp4" | "hls") => Promise<Asset | void>;
|
||||||
removeDownload: (id: string) => void;
|
removeDownload: (id: string) => void;
|
||||||
|
cancelDownload: (id: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DownloadManagerContext = createContext<
|
const DownloadManagerContext = createContext<
|
||||||
@@ -66,6 +68,24 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
useDownloadHistoryStore.setState({ downloads });
|
useDownloadHistoryStore.setState({ downloads });
|
||||||
}, [downloads]);
|
}, [downloads]);
|
||||||
|
|
||||||
|
const cancellationFlags: Record<string, boolean> = {};
|
||||||
|
|
||||||
|
const setCancellationFlag = (downloadId: string, flag: boolean): void => {
|
||||||
|
cancellationFlags[downloadId] = flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCancellationFlag = (downloadId: string): boolean => {
|
||||||
|
return cancellationFlags[downloadId] ?? false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelDownload = async (downloadId: string): Promise<void> => {
|
||||||
|
setCancellationFlag(downloadId, true);
|
||||||
|
const downloadItem = downloads.find((d) => d.id === downloadId);
|
||||||
|
if (downloadItem?.downloadResumable) {
|
||||||
|
await downloadItem.downloadResumable.cancelAsync();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const startDownload = async (
|
const startDownload = async (
|
||||||
url: string,
|
url: string,
|
||||||
type: "mp4" | "hls",
|
type: "mp4" | "hls",
|
||||||
@@ -154,6 +174,7 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
{ headers },
|
{ headers },
|
||||||
callback,
|
callback,
|
||||||
);
|
);
|
||||||
|
updateDownloadItem(downloadId, { downloadResumable });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await downloadResumable.downloadAsync();
|
const result = await downloadResumable.downloadAsync();
|
||||||
@@ -199,6 +220,11 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
const localSegmentPaths = [];
|
const localSegmentPaths = [];
|
||||||
|
|
||||||
for (const [index, segment] of segments.entries()) {
|
for (const [index, segment] of segments.entries()) {
|
||||||
|
if (getCancellationFlag(downloadId)) {
|
||||||
|
await FileSystem.deleteAsync(segmentDir, { idempotent: true });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const segmentFile = `${segmentDir}${index}.ts`;
|
const segmentFile = `${segmentDir}${index}.ts`;
|
||||||
localSegmentPaths.push(segmentFile);
|
localSegmentPaths.push(segmentFile);
|
||||||
const downloadResumable = FileSystem.createDownloadResumable(
|
const downloadResumable = FileSystem.createDownloadResumable(
|
||||||
@@ -213,9 +239,16 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
updateProgress();
|
updateProgress();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
if (getCancellationFlag(downloadId)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getCancellationFlag(downloadId)) {
|
||||||
|
return removeDownload(downloadId);
|
||||||
|
}
|
||||||
|
|
||||||
updateDownloadItem(downloadId, { statusText: "Merging" });
|
updateDownloadItem(downloadId, { statusText: "Merging" });
|
||||||
const uri = await VideoManager.mergeVideos(
|
const uri = await VideoManager.mergeVideos(
|
||||||
localSegmentPaths,
|
localSegmentPaths,
|
||||||
@@ -278,7 +311,7 @@ export const DownloadManagerProvider: React.FC<{ children: ReactNode }> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<DownloadManagerContext.Provider
|
<DownloadManagerContext.Provider
|
||||||
value={{ downloads, startDownload, removeDownload }}
|
value={{ downloads, startDownload, removeDownload, cancelDownload }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</DownloadManagerContext.Provider>
|
</DownloadManagerContext.Provider>
|
||||||
|
Reference in New Issue
Block a user