Upload cancel

This commit is contained in:
Roman 2021-03-31 13:15:39 +02:00
parent 5a169488af
commit 2d4c2f5aaa
4 changed files with 55 additions and 18 deletions

@ -68,7 +68,7 @@ export default class API {
return this.apiCall("file/getRestrictions"); return this.apiCall("file/getRestrictions");
} }
async upload(file, token = null, parentId = null, onUploadProgress = null) { async upload(file, token = null, parentId = null, cancelToken = null, onUploadProgress = null) {
const csrf_token = this.csrfToken(); const csrf_token = this.csrfToken();
const fd = new FormData(); const fd = new FormData();
@ -79,7 +79,8 @@ export default class API {
let response = await axios.post('/api/file/upload', fd, { let response = await axios.post('/api/file/upload', fd, {
headers: { 'Content-Type': 'multipart/form-data' }, headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: onUploadProgress || function () { } onUploadProgress: onUploadProgress || function () { },
cancelToken : cancelToken.token
}); });
return response.data; return response.data;

@ -47,6 +47,23 @@
cursor: pointer; cursor: pointer;
} }
.uploaded-file > .cancel-button {
position: absolute;
left: 0;
right: 0;
top: 15px;
bottom: 0;
opacity: 0;
}
.uploaded-file:hover > .file-icon {
opacity: 0.5;
}
.uploaded-file:hover > .cancel-button {
opacity: 1.0;
}
.clickable { cursor: pointer; } .clickable { cursor: pointer; }
.token-revoked td { text-decoration: line-through; } .token-revoked td { text-decoration: line-through; }

@ -5,6 +5,7 @@ import Icon from "./icon";
import Alert from "./alert"; import Alert from "./alert";
import {Popup} from "./popup"; import {Popup} from "./popup";
import {useEffect, useState} from "react"; import {useEffect, useState} from "react";
import axios from "axios";
export function FileBrowser(props) { export function FileBrowser(props) {
@ -94,7 +95,7 @@ export function FileBrowser(props) {
icon = "file" + (icon ? ("-" + icon) : icon); icon = "file" + (icon ? ("-" + icon) : icon);
} }
return <Icon icon={icon} type={"far"} className={"p-1 align-middle fa-" + size}/> return <Icon icon={icon} type={"far"} className={"p-1 align-middle file-icon fa-" + size}/>
} }
function formatSize(size) { function formatSize(size) {
@ -273,6 +274,18 @@ export function FileBrowser(props) {
}; };
} }
function onCancelUpload(e, i) {
e.stopPropagation();
e.preventDefault();
const cancelToken = filesToUpload[i].cancelToken;
if (cancelToken) {
cancelToken.cancel("Upload cancelled");
let files = filesToUpload.slice();
files.splice(i, 1);
setFilesToUpload(files);
}
}
if (writePermissions) { if (writePermissions) {
for (let i = 0; i < filesToUpload.length; i++) { for (let i = 0; i < filesToUpload.length; i++) {
@ -284,15 +297,17 @@ export function FileBrowser(props) {
{createFileIcon(file.type, "3x")} {createFileIcon(file.type, "3x")}
<span>{file.name}</span> <span>{file.name}</span>
{!done ? {!done ?
<div className={"progress border border-primary"}> <div className={"progress border border-primary position-relative"}>
<div className={"progress-bar progress-bar-striped progress-bar-animated"} role={"progressbar"} <div className={"progress-bar progress-bar-striped progress-bar-animated"} role={"progressbar"}
aria-valuenow={progress} aria-valuemin={"0"} aria-valuemax={"100"} aria-valuenow={progress} aria-valuemin={"0"} aria-valuemax={"100"}
style={{width: progress + "%"}}> style={{width: progress + "%"}} />
<span className="justify-content-center d-flex position-absolute w-100" style={{top: "7px"}}>
{ progress + "%" } { progress + "%" }
</div> </span>
</div> : <></> </div> : <></>
} }
<Icon icon={done ? "check" : "spinner"} className={"status-icon " + (done ? "text-success" : "text-secondary")} /> <Icon icon={done ? "check" : "spinner"} className={"status-icon " + (done ? "text-success" : "text-secondary")} />
<Icon icon={"times"} className={"text-danger cancel-button fa-2x"} title={"Cancel Upload"} onClick={(e) => onCancelUpload(e, i)}/>
</span> </span>
); );
} }
@ -462,13 +477,6 @@ export function FileBrowser(props) {
}); });
} }
function onRemoveUploadedFile(e, i) {
e.stopPropagation();
let files = filesToUpload.slice();
files.splice(i, 1);
setFilesToUpload(files);
}
function pushAlert(res, title) { function pushAlert(res, title) {
let newAlerts = alerts.slice(); let newAlerts = alerts.slice();
newAlerts.push({type: "danger", message: res.msg, title: title}); newAlerts.push({type: "danger", message: res.msg, title: title});
@ -508,13 +516,24 @@ export function FileBrowser(props) {
let token = (api.loggedIn ? null : tokenObj.value); let token = (api.loggedIn ? null : tokenObj.value);
let parentId = ((!api.loggedIn || popup.directory === 0) ? null : popup.directory); let parentId = ((!api.loggedIn || popup.directory === 0) ? null : popup.directory);
const file = filesToUpload[fileIndex]; const file = filesToUpload[fileIndex];
api.upload(file, token, parentId, (e) => onUploadProgress(e, fileIndex)).then((res) => { const cancelToken = axios.CancelToken.source();
let newFiles = filesToUpload.slice();
newFiles[fileIndex].cancelToken = cancelToken;
newFiles[fileIndex].progress = 0;
setFilesToUpload(newFiles);
api.upload(file, token, parentId, cancelToken, (e) => onUploadProgress(e, fileIndex)).then((res) => {
if (res.success) { if (res.success) {
// setFilesToUpload([]); // setFilesToUpload([]);
fetchFiles(); fetchFiles();
} else { } else {
pushAlert(res); pushAlert(res);
} }
}).catch((reason) => {
if (reason && reason.message !== "Upload cancelled") {
pushAlert({ msg: reason}, "Error uploading files");
}
}); });
} }

6
js/files.min.js vendored

File diff suppressed because one or more lines are too long