Add cancel button to filesystem upload queue

This commit is contained in:
2024-06-13 20:08:10 +02:00
parent 1e0a692ca0
commit a5873148d4
3 changed files with 60 additions and 24 deletions

View File

@@ -12,7 +12,7 @@
import { fs_path_url } from "../FilesystemUtil"
// code and an error message
export const upload_file = async (file, path, on_progress, on_success, on_error) => {
export const upload_file = (file, path, on_progress, on_success, on_error) => {
// Check the file size limit. For free accounts it's 20 GB
if (window.user.subscription.file_size_limit === 0) {
window.user.subscription.file_size_limit = 20e9
@@ -70,4 +70,6 @@ export const upload_file = async (file, path, on_progress, on_success, on_error)
};
xhr.send(file);
return xhr
}

View File

@@ -3,21 +3,22 @@ import { createEventDispatcher } from "svelte";
import { fade } from "svelte/transition";
import { upload_file } from "./UploadFunc";
import ProgressBar from "../../util/ProgressBar.svelte";
import Button from "../../layout/Button.svelte"
let dispatch = createEventDispatcher()
export let job = {
file: null,
name: "",
id: "",
status: "",
}
export let total = 0
export let loaded = 0
let error_code = ""
let error_message = ""
let xhr = null
export const start = () => {
upload_file(
xhr = upload_file(
job.file,
job.path,
(prog_loaded, prog_total) => {
@@ -29,37 +30,66 @@ export const start = () => {
dispatch("finished")
},
(code, message) => {
if (job.status === "finished") {
return
}
console.log("Upload error", code, message)
error_code = code
error_message = message
job.status = "error"
// Wait with reporting so the user can read the error message
setTimeout(() => dispatch("finished"), 60000)
// We don't send the finished signal so the user can read the error
// messsage and manually dismiss it through the cancel button
},
)
job.status = "uploading"
}
const cancel = () => {
job.status = "finished"
if (xhr && xhr.abort) {
xhr.abort()
}
xhr = null
dispatch("finished")
}
</script>
<div class="upload_progress" transition:fade={{duration: 200}} class:error={job.status === "error"}>
{job.file.name}<br/>
{#if error_code !== ""}
{error_message}<br/>
{error_code}<br/>
{/if}
<ProgressBar total={total} used={loaded}/>
<div class="prog" transition:fade={{duration: 200}} class:error={job.status === "error"}>
<div class="bar">
{job.file.name}<br/>
{#if error_code !== ""}
{error_message}<br/>
{error_code}<br/>
{/if}
<ProgressBar total={total} used={loaded}/>
</div>
<div class="cancel">
<Button icon="cancel" click={cancel}/>
</div>
</div>
<style>
.upload_progress {
display: block;
.prog {
display: flex;
flex-direction: row;
}
.bar {
flex: 1 1 auto;
padding: 2px 4px 1px 4px;
margin: 4px;
border-radius: 4px;
}
.cancel {
flex: 0 0 auto;
display: flex;
justify-content: center;
align-items: center; /* Stop stretching the button */
}
.error {
background: var(--danger_color);
color: var(--highlight_text_color);

View File

@@ -80,6 +80,15 @@ let active_uploads = 0
let state = "idle"
const start_upload = async () => {
// Count the number of active uploads so we can know how many new uploads we
// can start
active_uploads = upload_queue.reduce((acc, val) => {
if (val.status === "uploading") {
acc++
}
return acc
}, 0)
for (let i = 0; i < upload_queue.length && active_uploads < 3; i++) {
if (upload_queue[i]) {
if (upload_queue[i].status === "queued") {
@@ -92,17 +101,12 @@ const start_upload = async () => {
if (active_uploads === 0) {
state = "finished"
dispatch("uploads_finished")
let file_ids = []
upload_queue.forEach(job => {
if (job.status === "finished" && job.id !== "") {
file_ids.push(job.id)
}
})
dispatch("uploads_finished", file_ids)
// Empty the queue to free any references to lingering components
upload_queue = []
// In ten seconds we close the popup
setTimeout(() => {
if (state === "finished") {
visible = false
@@ -114,7 +118,7 @@ const start_upload = async () => {
}
const finish_upload = (e) => {
active_uploads--
// Update the queue so the status updates are properly rendered
upload_queue = upload_queue
start_upload()
}