feat(fetch): add cancel download functionality for download tasks

pull/3834/head
banbxio 2025-04-02 22:26:08 +08:00
parent 37a36a3e40
commit 02609e6e1e
2 changed files with 33 additions and 4 deletions

View File

@ -36,3 +36,12 @@ export async function queryDownloadTask(taskID: string): Promise<DownloadTask> {
const res = await fetchURL(`/api/download/${taskID}`, {}); const res = await fetchURL(`/api/download/${taskID}`, {});
return await res.json(); return await res.json();
} }
export async function cancelDownloadTask(taskID: string): Promise<void> {
const res = await fetchURL(`/api/download/${taskID}`, {
method: "DELETE",
});
if (!res.ok) {
throw new Error("Failed to cancel download task");
}
}

View File

@ -32,7 +32,7 @@
<div class="card-action"> <div class="card-action">
<button <button
class="button button--flat button--grey" class="button button--flat button--grey"
@click="layoutStore.closeHovers" @click="cancel"
:aria-label="t('buttons.cancel')" :aria-label="t('buttons.cancel')"
:title="t('buttons.cancel')" :title="t('buttons.cancel')"
tabindex="4" tabindex="4"
@ -45,12 +45,14 @@
:title="t('buttons.create')" :title="t('buttons.create')"
@click="submit" @click="submit"
tabindex="3" tabindex="3"
:disabled="isDownloading"
> >
{{ t("buttons.create") }} {{ t("buttons.create") }}
</button> </button>
</div> </div>
<div v-if="isDownloading || isFailed" class="material-progress-container"> <div
v-if="isDownloading || isFailed || isCanceled"
class="material-progress-container"
>
<div <div
class="material-progress-bar" class="material-progress-bar"
id="downloadProgress" id="downloadProgress"
@ -58,7 +60,7 @@
></div> ></div>
<div <div
class="material-progress-label" class="material-progress-label"
:style="{ color: isFailed ? '#ff4757' : '' }" :style="{ color: isFailed || isCanceled ? '#ff4757' : '' }"
> >
{{ Math.floor(currentTask.progress * 100) + "%" }} {{ Math.floor(currentTask.progress * 100) + "%" }}
</div> </div>
@ -110,6 +112,9 @@ const isDownloading = computed(() => {
const isFailed = computed(() => { const isFailed = computed(() => {
return currentTask.status === "error"; return currentTask.status === "error";
}); });
const isCanceled = computed(() => {
return currentTask.status === "canceled";
});
watch(fetchUrl, (value) => { watch(fetchUrl, (value) => {
try { try {
@ -120,6 +125,21 @@ watch(fetchUrl, (value) => {
} catch (e) {} } catch (e) {}
}); });
const cancel = async () => {
if (!isDownloading.value) {
layoutStore.closeHovers();
taskID.value = "";
return;
}
try {
await api.cancelDownloadTask(taskID.value);
} catch (e) {
if (e instanceof Error) {
$showError(e);
}
}
};
const submit = async (event: Event) => { const submit = async (event: Event) => {
event.preventDefault(); event.preventDefault();
if ( if (