diff --git a/package.json b/package.json
index 08b48a4..b551e11 100644
--- a/package.json
+++ b/package.json
@@ -8,10 +8,7 @@
"@fortawesome/free-regular-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
- "@testing-library/jest-dom": "^5.14.1",
- "@testing-library/react": "^12.0.0",
- "@testing-library/user-event": "^13.2.0",
- "http-proxy-middleware": "^2.0.1",
+ "js-file-download": "^0.4.12",
"react": "^17.0.2",
"react-axios": "^2.0.5",
"react-dom": "^17.0.2",
diff --git a/src/App.js b/src/App.js
index 764a057..98fddf0 100644
--- a/src/App.js
+++ b/src/App.js
@@ -5,7 +5,8 @@ import "react-toastify/dist/ReactToastify.css";
//Local Imports
import Stash from "./Stash";
//Constants
-const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1dWlkIjoiYmVjYWNjNjdhNmRjLTBlN2QtMDBlNi1jYmVhLWVhZGNlYmUxIiwiaWF0IjoxNjI3MTcxMDU1LCJleHAiOjE2Mjk3NjMwNTV9.zqiHrYnJlB7ozwjMnpgVUsBAt9vfLHLICFgWB0MguLA"
+const token =
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1dWlkIjoiYmVjYWNjNjdhNmRjLTBlN2QtMDBlNi1jYmVhLWVhZGNlYmUxIiwiaWF0IjoxNjI3MTcxMDU1LCJleHAiOjE2Mjk3NjMwNTV9.zqiHrYnJlB7ozwjMnpgVUsBAt9vfLHLICFgWB0MguLA";
localStorage.setItem("authToken", token);
class App extends React.Component {
render() {
@@ -18,6 +19,7 @@ class App extends React.Component {
newestOnTop={false}
closeOnClick={true}
rtl={false}
+ limit={3}
pauseOnFocusLoss
draggable
pauseOnHover={false}
diff --git a/src/Stash.jsx b/src/Stash.jsx
index cde6c40..094c65b 100644
--- a/src/Stash.jsx
+++ b/src/Stash.jsx
@@ -11,26 +11,32 @@ import "./stash/scss/Stash.scss";
//Constants
const filesUrl = `${serverAddress}/${serverUrls.GET.filesUrl}`;
//Class
-function getConfig() {
- var authToken = localStorage.getItem("authToken");
- console.log({ headers: { authorization: `Bearer ${authToken}` } });
- return {
- headers: { authorization: `Bearer ${authToken}`, withCredentials: true },
- };
-}
-function buildFilebox(file, index) {
- return {
- file,
- selected: false,
- filtered: true,
- position: index,
- };
-}
+const getConfig = () => ({
+ headers: {
+ authorization: `Bearer ${localStorage.getItem("authToken")}`,
+ withCredentials: true,
+ },
+});
+
+const buildFilebox = (file, index) => ({
+ file,
+ selected: false,
+ filtered: true,
+ position: index,
+});
+const buildDownload = (name, total) => ({
+ name,
+ total,
+ completed: 0.01,
+ progress: 0.01,
+});
+
class Stash extends React.Component {
constructor(props) {
super(props);
this.state = {
fileBoxes: {},
+ downloads: {},
contextMenu: null,
};
}
@@ -39,17 +45,13 @@ class Stash extends React.Component {
axios
.get(filesUrl, getConfig())
.then((res) => {
- if (res.status === 401) {
- console.log("Would redirect to login");
- return;
- }
- if (res.data === undefined || res.data.length === undefined) {
- toast.error("Error Loading Files");
- return;
- }
+ if (res.status === 401) return console.log("Would redirect to login");
+ if (res.data === undefined || res.data.length === undefined)
+ return toast.error("Error Loading Files");
+
var fileBoxes = {};
res.data.forEach((file, index) => {
- fileBoxes[file.fileUuid] = buildFilebox(file, index);
+ fileBoxes[file._id] = buildFilebox(file, index);
});
this.setState({ fileBoxes });
})
@@ -76,13 +78,29 @@ class Stash extends React.Component {
addFilebox(file) {
var fileBoxes = this.state.fileBoxes;
- fileBoxes[file.fileUuid] = buildFilebox(
- file,
- Object.keys(fileBoxes).length
- );
+ fileBoxes[file._id] = buildFilebox(file, Object.keys(fileBoxes).length);
this.setState({ fileBoxes });
}
+ startDownload(name, total) {
+ const downloads = this.state.downloads;
+ const key = `${Date.now()}-${name}`;
+ const download = buildDownload(name, total);
+ download.toast = toast.dark(name, {
+ progress: download.progress,
+ position: "bottom-right",
+ });
+ downloads[key] = download;
+ this.setState({ downloads });
+ return key;
+ }
+
+ updateDownload(downloadId, completed, total) {
+ const downloads = this.state.downloads;
+ const progress = completed / total;
+ toast.update(downloads[downloadId].toast, { progress });
+ }
+
removeDriveContextMenu() {
if (this.state.contextMenu !== null) this.setState({ contextMenu: null });
}
@@ -118,9 +136,10 @@ class Stash extends React.Component {
fileBoxes={this.state.fileBoxes}
fileBoxesChanged={this.fileBoxesChanged.bind(this)}
getSelectedBoxes={this.getSelectedBoxes.bind(this)}
+ startDownload={this.startDownload.bind(this)}
+ updateDownload={this.updateDownload.bind(this)}
/>
)}
-
{
- app.use(
- "/api",
- createProxyMiddleware({
- target: serverAddress,
- changeOrigin: true,
- logLevel: "silent",
- })
- );
-};
diff --git a/src/stash/StashContextMenu.jsx b/src/stash/StashContextMenu.jsx
index 9f6e017..d932117 100644
--- a/src/stash/StashContextMenu.jsx
+++ b/src/stash/StashContextMenu.jsx
@@ -2,6 +2,7 @@ import React from "react";
import axios from "axios";
import { toast } from "react-toastify";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import FileDownload from "js-file-download";
import {
faInfoCircle,
faFileDownload,
@@ -16,7 +17,6 @@ import { serverUrls, serverAddress } from "./api.json";
const downloadUrl = `${serverAddress}/${serverUrls.POST.downloadUrl}`;
const deleteUrl = `${serverAddress}/${serverUrls.POST.deleteUrl}`;
const publicUrl = `${serverAddress}/${serverUrls.POST.publicUrl}`;
-const rawUrl = `${serverAddress}/${serverUrls.GET.rawUrl}`;
function getConfig() {
var authToken = localStorage.getItem("authToken");
@@ -26,27 +26,19 @@ function getConfig() {
export default class StashContextMenu extends React.Component {
infoView() {
var selectedCount = this.props.getSelectedBoxes().length;
- if (selectedCount === 1) return "View";
- if (selectedCount > 1) return `${selectedCount} files selected`;
+ if (selectedCount > 0) return `${selectedCount} files selected`;
return "No Files Selected";
}
- infoClick(e) {
- const selectedBoxes = this.props.getSelectedBoxes();
- if (selectedBoxes.length !== 1) return;
- const file = selectedBoxes[0];
- let win = window.open(`${rawUrl}?target=${file}`);
- if (!win || win.closed || typeof win.closed == "undefined") {
- window.location = `${rawUrl}?target=${file}`;
- }
- }
downloadClick() {
const selectedBoxes = this.props.getSelectedBoxes();
//ZIPS ARE NOT SUPPORTED YET
if (selectedBoxes.length > 1)
return toast.error("Downloading multiple files is not yet supported!");
- else
- return this.handleDownload(`${downloadUrl}?target=${selectedBoxes[0]}`);
+ return this.handleDownload(
+ `${downloadUrl}?target=${selectedBoxes[0]}`,
+ this.props.fileBoxes[selectedBoxes[0]].file
+ );
}
deleteClick() {
const selectedBoxes = this.props.getSelectedBoxes();
@@ -69,19 +61,28 @@ export default class StashContextMenu extends React.Component {
toast.error("There was an issue making some files public!");
let fileBoxes = this.props.fileBoxes;
selectedBoxes.forEach((selectedBoxId) => {
- if (!failedFiles.includes(selectedBoxId)) {
+ if (failedFiles.includes(selectedBoxId))
+ fileBoxes[selectedBoxId].selected = true;
+ else
fileBoxes[selectedBoxId].file.public = !fileBoxes[selectedBoxId].file
.public;
- } else {
- fileBoxes[selectedBoxId].selected = true;
- }
});
this.props.fileBoxesChanged(fileBoxes);
}
- handleDownload(url) {
- let win = window.open(url);
- if (!win || win.closed || typeof win.closed == "undefined")
- window.location = url;
+ handleDownload(url, file) {
+ const downloadName = `${file.date}-${file.name}`;
+ const config = getConfig();
+ config.method = "GET";
+ config["Content-Type"] = "application/octet-stream";
+ config.responseType = "blob";
+ const downloadId = this.props.startDownload(file.name);
+ config.onDownloadProgress = (e) =>
+ this.props.updateDownload(downloadId, e.loaded, e.total);
+ axios.request(url, config).then((response) => {
+ if (response.status !== 200)
+ return toast.error("There was an error downloading that!");
+ FileDownload(response.data, downloadName);
+ });
}
/**
* Handles the response from the deleteClick()
@@ -95,11 +96,8 @@ export default class StashContextMenu extends React.Component {
if (res.status !== 200) toast.error("Error Deleting Some Files");
let fileBoxes = this.props.fileBoxes;
selectedBoxes.forEach((selectedBoxId) => {
- if (!failedFiles.includes(selectedBoxId)) {
- delete fileBoxes[selectedBoxId];
- } else {
- fileBoxes[selectedBoxId].selected = true;
- }
+ if (!failedFiles.includes(selectedBoxId)) delete fileBoxes[selectedBoxId];
+ else fileBoxes[selectedBoxId].selected = true;
});
this.props.fileBoxesChanged(fileBoxes);
}
@@ -123,7 +121,7 @@ export default class StashContextMenu extends React.Component {
return (
- -
+
-
{this.infoView()}
diff --git a/src/stash/scss/_global.scss b/src/stash/scss/_global.scss
index 3c3bc04..1e17595 100644
--- a/src/stash/scss/_global.scss
+++ b/src/stash/scss/_global.scss
@@ -1,5 +1,5 @@
@import "global/colors", "global/fonts", "global/measurements",
- "global/animations";
+ "global/animations", "global/zindex";
html,
body {
margin-left: auto;
diff --git a/src/stash/scss/global/_zindex.scss b/src/stash/scss/global/_zindex.scss
new file mode 100644
index 0000000..ff98ce5
--- /dev/null
+++ b/src/stash/scss/global/_zindex.scss
@@ -0,0 +1,4 @@
+$stashbarIndex: 200;
+$contextMenuIndex: 300;
+$fudIndex: 100;
+$downloadsIndex: 100;
diff --git a/src/stash/scss/stash/StashContextMenu.scss b/src/stash/scss/stash/StashContextMenu.scss
index a03b66d..f6d72e3 100644
--- a/src/stash/scss/stash/StashContextMenu.scss
+++ b/src/stash/scss/stash/StashContextMenu.scss
@@ -6,7 +6,7 @@
background: lighten($sectionMenuOptions, 10%);
box-shadow: 1px 3px 2px lighten ($sectionMenuOptions, 5%);
color: $foreground;
- z-index: 300;
+ z-index: $contextMenuIndex;
width: 100%;
max-width: inherit;
font-size: 1rem;
diff --git a/src/stash/scss/stash/StashUploadDialog.scss b/src/stash/scss/stash/StashUploadDialog.scss
index ba49789..b7cb990 100644
--- a/src/stash/scss/stash/StashUploadDialog.scss
+++ b/src/stash/scss/stash/StashUploadDialog.scss
@@ -16,7 +16,7 @@ $actionButtonSize: 25px;
max-height: 250px;
overflow: hidden;
-webkit-transform: translate3d(0, 0, 0);
- z-index: 100;
+ z-index: $fudIndex;
display: block;
visibility: hidden;
}
diff --git a/src/stash/scss/stash/Stashbar.scss b/src/stash/scss/stash/Stashbar.scss
index afd6c2a..540e63a 100644
--- a/src/stash/scss/stash/Stashbar.scss
+++ b/src/stash/scss/stash/Stashbar.scss
@@ -2,7 +2,7 @@
.stashbar {
width: 100%;
- z-index: 200;
+ z-index: $stashbarIndex;
}
.stashbar-menu {
width: 100%;