diff --git a/src/components/Uploader/Uploader.jsx b/src/components/Uploader/Uploader.jsx
deleted file mode 100644
index 01d5bc4..0000000
--- a/src/components/Uploader/Uploader.jsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { useAppSelector } from "../../hooks/store";
-import UploadItem from "../UploadItem";
-import React from "react";
-
-const Uploader = React.forwardRef((props, ref) => {
- const uploads = useAppSelector((state) => state.uploader.uploads);
-
- return (
-
-
-
- Uploading {uploads.length} {uploads.length === 1 ? "file" : "files"}
-
-
-
-
- {props.uploaderShow
- ? uploads.map((upload) => {
- return ;
- })
- : undefined}
-
-
- );
-});
-
-export default Uploader;
diff --git a/src/components/Uploader/index.jsx b/src/components/Uploader/index.jsx
deleted file mode 100644
index 904254d..0000000
--- a/src/components/Uploader/index.jsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import Uploader from "./Uploader";
-import {showUploader, hideUploader} from "../../actions/main";
-import {startCancelAllUploads} from "../../actions/uploads";
-import {connect} from "react-redux";
-import React from "react";
-
-class UploaderContainer extends React.Component {
-
- constructor(props) {
- super(props);
-
- this.uploaderWrapper = React.createRef()
- this.prevUploadLength = 0;
- }
-
- minimizeUploader = () => {
-
- const uploaderShow = this.props.uploaderShow;
- const dispatch = this.props.dispatch;
-
- if (uploaderShow) {
-
- dispatch(hideUploader())
-
- } else {
-
- dispatch(showUploader())
- }
- }
-
- cancelAllUploadsEvent = () => {
-
- this.props.dispatch(startCancelAllUploads(this.props.uploads))
- }
-
- componentDidUpdate = () => {
-
- if (this.props.uploads.length !== this.prevUploadLength) {
- if (this.uploaderWrapper.current) this.uploaderWrapper.current.scrollTop = 0;
- }
-
- this.prevUploadLength = this.props.uploads.length;
- }
-
- render() {
- return
- }
-
-}
-
-const connectStateToProp = (state) => ({
- uploads: state.uploads,
- uploaderShow: state.main.uploaderShow
-})
-
-export default connect(connectStateToProp)(UploaderContainer);
\ No newline at end of file
diff --git a/src/components/Uploader/index.tsx b/src/components/Uploader/index.tsx
new file mode 100644
index 0000000..b437839
--- /dev/null
+++ b/src/components/Uploader/index.tsx
@@ -0,0 +1,61 @@
+import { useAppDispatch, useAppSelector } from "../../hooks/store";
+import CloseIcon from "../../icons/CloseIcon";
+import MinimizeIcon from "../../icons/MinimizeIcon";
+import { resetUploads } from "../../reducers/uploader";
+import { cancelAllFileUploads } from "../../utils/cancelTokenManager";
+import UploadItem from "../UploadItem";
+import { memo, useMemo, useState } from "react";
+
+const Uploader = memo(() => {
+ const [minimized, setMinimized] = useState(false);
+ const uploads = useAppSelector((state) => state.uploader.uploads);
+ const dispatch = useAppDispatch();
+
+ const toggleMinimize = () => {
+ setMinimized(!minimized);
+ };
+
+ const uploadTitle = useMemo(() => {
+ const uploadedCount = uploads.filter((upload) => upload.completed).length;
+ const currentlyUploadingCount = uploads.filter(
+ (upload) => !upload.completed
+ ).length;
+
+ if (currentlyUploadingCount) {
+ return `Uploading ${currentlyUploadingCount} file${
+ currentlyUploadingCount > 1 ? "s" : ""
+ }`;
+ } else {
+ return `Uploaded ${uploadedCount} file${uploadedCount > 1 ? "s" : ""}`;
+ }
+ }, [uploads]);
+
+ const closeUploader = () => {
+ cancelAllFileUploads();
+ dispatch(resetUploads());
+ };
+
+ return (
+
+
+
+ {!minimized &&
+ uploads.map((upload) => {
+ return ;
+ })}
+
+
+ );
+});
+
+export default Uploader;
diff --git a/src/hooks/files.ts b/src/hooks/files.ts
index 7d83da8..25b1665 100644
--- a/src/hooks/files.ts
+++ b/src/hooks/files.ts
@@ -21,7 +21,10 @@ import { useUtils } from "./utils";
import { FileInterface } from "../types/file";
import { v4 as uuid } from "uuid";
import axiosNonInterceptor from "axios";
-import { addFileUploadCancelToken } from "../utils/cancelTokenManager";
+import {
+ addFileUploadCancelToken,
+ removeFileUploadCancelToken,
+} from "../utils/cancelTokenManager";
import { debounce } from "lodash";
import { addUpload, editUpload } from "../reducers/uploader";
@@ -209,7 +212,7 @@ export const useUploader = () => {
const debounceDispatch = debounce(dispatch, 200);
- const uploadFiles = async (files: FileList) => {
+ const uploadFiles = (files: FileList) => {
for (let i = 0; i < files.length; i++) {
const parent = params.id || "/";
@@ -262,23 +265,26 @@ export const useUploader = () => {
data.append("size", currentFile.size.toString());
data.append("file", currentFile);
- try {
- await uploadFileAPI(data, config);
- dispatch(
- editUpload({
- id: currentID,
- updateData: { completed: true, progress: 100 },
- })
- );
- } catch (e) {
- console.log("Error uploading file", e);
- dispatch(
- editUpload({
- id: currentID,
- updateData: { canceled: true },
- })
- );
- }
+ uploadFileAPI(data, config)
+ .then(() => {
+ dispatch(
+ editUpload({
+ id: currentID,
+ updateData: { completed: true, progress: 100 },
+ })
+ );
+ removeFileUploadCancelToken(currentID);
+ })
+ .catch((e) => {
+ console.log("Error uploading file", e);
+ dispatch(
+ editUpload({
+ id: currentID,
+ updateData: { canceled: true },
+ })
+ );
+ removeFileUploadCancelToken(currentID);
+ });
}
};
diff --git a/src/icons/MinimizeIcon.tsx b/src/icons/MinimizeIcon.tsx
new file mode 100644
index 0000000..6c96276
--- /dev/null
+++ b/src/icons/MinimizeIcon.tsx
@@ -0,0 +1,12 @@
+type MinimizeIconType = React.SVGAttributes;
+
+const MinimizeIcon: React.FC = (props) => {
+ return (
+
+ );
+};
+
+export default MinimizeIcon;
diff --git a/src/reducers/uploader.ts b/src/reducers/uploader.ts
index cf8f87c..7b3242b 100644
--- a/src/reducers/uploader.ts
+++ b/src/reducers/uploader.ts
@@ -22,7 +22,7 @@ const uploaderSlice = createSlice({
initialState,
reducers: {
addUpload(state, action: PayloadAction) {
- state.uploads.push(action.payload);
+ state.uploads.unshift(action.payload);
},
editUpload(
state,
@@ -48,9 +48,12 @@ const uploaderSlice = createSlice({
state.uploads = uploads;
},
+ resetUploads(state) {
+ state.uploads = [];
+ },
},
});
-export const { addUpload, editUpload } = uploaderSlice.actions;
+export const { addUpload, editUpload, resetUploads } = uploaderSlice.actions;
export default uploaderSlice.reducer;
diff --git a/src/utils/cancelTokenManager.ts b/src/utils/cancelTokenManager.ts
index 757e1d1..6c1c759 100644
--- a/src/utils/cancelTokenManager.ts
+++ b/src/utils/cancelTokenManager.ts
@@ -14,6 +14,10 @@ export const addFileUploadCancelToken = (id: string, cancelToken: any) => {
cancelTokens[id] = cancelToken;
};
+export const removeFileUploadCancelToken = (id: string) => {
+ delete cancelTokens[id];
+};
+
export const getCancelToken = (id: string) => {
return cancelTokens[id];
};