Add cancel button to filesystem upload queue
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
import { fs_path_url } from "../FilesystemUtil"
|
import { fs_path_url } from "../FilesystemUtil"
|
||||||
|
|
||||||
// code and an error message
|
// 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
|
// Check the file size limit. For free accounts it's 20 GB
|
||||||
if (window.user.subscription.file_size_limit === 0) {
|
if (window.user.subscription.file_size_limit === 0) {
|
||||||
window.user.subscription.file_size_limit = 20e9
|
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);
|
xhr.send(file);
|
||||||
|
|
||||||
|
return xhr
|
||||||
}
|
}
|
||||||
|
@@ -3,21 +3,22 @@ import { createEventDispatcher } from "svelte";
|
|||||||
import { fade } from "svelte/transition";
|
import { fade } from "svelte/transition";
|
||||||
import { upload_file } from "./UploadFunc";
|
import { upload_file } from "./UploadFunc";
|
||||||
import ProgressBar from "../../util/ProgressBar.svelte";
|
import ProgressBar from "../../util/ProgressBar.svelte";
|
||||||
|
import Button from "../../layout/Button.svelte"
|
||||||
|
|
||||||
let dispatch = createEventDispatcher()
|
let dispatch = createEventDispatcher()
|
||||||
export let job = {
|
export let job = {
|
||||||
file: null,
|
file: null,
|
||||||
name: "",
|
name: "",
|
||||||
id: "",
|
|
||||||
status: "",
|
status: "",
|
||||||
}
|
}
|
||||||
export let total = 0
|
export let total = 0
|
||||||
export let loaded = 0
|
export let loaded = 0
|
||||||
let error_code = ""
|
let error_code = ""
|
||||||
let error_message = ""
|
let error_message = ""
|
||||||
|
let xhr = null
|
||||||
|
|
||||||
export const start = () => {
|
export const start = () => {
|
||||||
upload_file(
|
xhr = upload_file(
|
||||||
job.file,
|
job.file,
|
||||||
job.path,
|
job.path,
|
||||||
(prog_loaded, prog_total) => {
|
(prog_loaded, prog_total) => {
|
||||||
@@ -29,22 +30,37 @@ export const start = () => {
|
|||||||
dispatch("finished")
|
dispatch("finished")
|
||||||
},
|
},
|
||||||
(code, message) => {
|
(code, message) => {
|
||||||
|
if (job.status === "finished") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
console.log("Upload error", code, message)
|
console.log("Upload error", code, message)
|
||||||
error_code = code
|
error_code = code
|
||||||
error_message = message
|
error_message = message
|
||||||
job.status = "error"
|
job.status = "error"
|
||||||
|
|
||||||
// Wait with reporting so the user can read the error message
|
// We don't send the finished signal so the user can read the error
|
||||||
setTimeout(() => dispatch("finished"), 60000)
|
// messsage and manually dismiss it through the cancel button
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
job.status = "uploading"
|
job.status = "uploading"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cancel = () => {
|
||||||
|
job.status = "finished"
|
||||||
|
|
||||||
|
if (xhr && xhr.abort) {
|
||||||
|
xhr.abort()
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr = null
|
||||||
|
dispatch("finished")
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="upload_progress" transition:fade={{duration: 200}} class:error={job.status === "error"}>
|
<div class="prog" transition:fade={{duration: 200}} class:error={job.status === "error"}>
|
||||||
|
<div class="bar">
|
||||||
{job.file.name}<br/>
|
{job.file.name}<br/>
|
||||||
{#if error_code !== ""}
|
{#if error_code !== ""}
|
||||||
{error_message}<br/>
|
{error_message}<br/>
|
||||||
@@ -52,14 +68,28 @@ export const start = () => {
|
|||||||
{/if}
|
{/if}
|
||||||
<ProgressBar total={total} used={loaded}/>
|
<ProgressBar total={total} used={loaded}/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cancel">
|
||||||
|
<Button icon="cancel" click={cancel}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.upload_progress {
|
.prog {
|
||||||
display: block;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.bar {
|
||||||
|
flex: 1 1 auto;
|
||||||
padding: 2px 4px 1px 4px;
|
padding: 2px 4px 1px 4px;
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
.cancel {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center; /* Stop stretching the button */
|
||||||
|
}
|
||||||
.error {
|
.error {
|
||||||
background: var(--danger_color);
|
background: var(--danger_color);
|
||||||
color: var(--highlight_text_color);
|
color: var(--highlight_text_color);
|
||||||
|
@@ -80,6 +80,15 @@ let active_uploads = 0
|
|||||||
let state = "idle"
|
let state = "idle"
|
||||||
|
|
||||||
const start_upload = async () => {
|
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++) {
|
for (let i = 0; i < upload_queue.length && active_uploads < 3; i++) {
|
||||||
if (upload_queue[i]) {
|
if (upload_queue[i]) {
|
||||||
if (upload_queue[i].status === "queued") {
|
if (upload_queue[i].status === "queued") {
|
||||||
@@ -92,17 +101,12 @@ const start_upload = async () => {
|
|||||||
|
|
||||||
if (active_uploads === 0) {
|
if (active_uploads === 0) {
|
||||||
state = "finished"
|
state = "finished"
|
||||||
|
dispatch("uploads_finished")
|
||||||
|
|
||||||
let file_ids = []
|
// Empty the queue to free any references to lingering components
|
||||||
upload_queue.forEach(job => {
|
|
||||||
if (job.status === "finished" && job.id !== "") {
|
|
||||||
file_ids.push(job.id)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
dispatch("uploads_finished", file_ids)
|
|
||||||
|
|
||||||
upload_queue = []
|
upload_queue = []
|
||||||
|
|
||||||
|
// In ten seconds we close the popup
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (state === "finished") {
|
if (state === "finished") {
|
||||||
visible = false
|
visible = false
|
||||||
@@ -114,7 +118,7 @@ const start_upload = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const finish_upload = (e) => {
|
const finish_upload = (e) => {
|
||||||
active_uploads--
|
// Update the queue so the status updates are properly rendered
|
||||||
upload_queue = upload_queue
|
upload_queue = upload_queue
|
||||||
start_upload()
|
start_upload()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user