Add cancel button to filesystem upload queue
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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()
|
||||
}
|
||||
|
Reference in New Issue
Block a user