more upload changes
This commit is contained in:
@@ -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 (
|
||||
<div className="upload__status">
|
||||
<div className="head__upload">
|
||||
<p>
|
||||
Uploading {uploads.length} {uploads.length === 1 ? "file" : "files"}
|
||||
</p>
|
||||
<div className="hide__upload">
|
||||
<a onClick={() => props.minimizeUploader()}>
|
||||
<img src="/assets/upload_hide.svg" alt="upload__hide" />
|
||||
</a>
|
||||
<a onClick={() => props.cancelAllUploadsEvent()}>
|
||||
<img
|
||||
src="/assets/close-white.svg"
|
||||
style={{ height: "24px" }}
|
||||
alt="upload__hide"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content__upload">
|
||||
{props.uploaderShow
|
||||
? uploads.map((upload) => {
|
||||
return <UploadItem key={upload.id} {...upload} />;
|
||||
})
|
||||
: undefined}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Uploader;
|
||||
@@ -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 <Uploader
|
||||
minimizeUploader={this.minimizeUploader}
|
||||
cancelAllUploadsEvent={this.cancelAllUploadsEvent}
|
||||
ref={this.uploaderWrapper}
|
||||
{...this.props}/>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const connectStateToProp = (state) => ({
|
||||
uploads: state.uploads,
|
||||
uploaderShow: state.main.uploaderShow
|
||||
})
|
||||
|
||||
export default connect(connectStateToProp)(UploaderContainer);
|
||||
@@ -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 (
|
||||
<div className="fixed bottom-0 right-[20px] z-10 bg-white shadow-lg rounded-t-md w-[315px]">
|
||||
<div className="flex flex-row bg-[#3c85ee] justify-between p-4 rounded-t-md">
|
||||
<p className="text-white">{uploadTitle}</p>
|
||||
<div className="flex flex-row items-center justify-center">
|
||||
<a onClick={toggleMinimize}>
|
||||
<MinimizeIcon className="w-[24px] h-[24px] text-white cursor-pointer mr-2" />
|
||||
</a>
|
||||
<a onClick={closeUploader}>
|
||||
<CloseIcon className="w-[24px] h-[24px] text-white" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="overflow-y-scroll animate max-h-[300px]">
|
||||
{!minimized &&
|
||||
uploads.map((upload) => {
|
||||
return <UploadItem key={upload.id} {...upload} />;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Uploader;
|
||||
+25
-19
@@ -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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
type MinimizeIconType = React.SVGAttributes<SVGSVGElement>;
|
||||
|
||||
const MinimizeIcon: React.FC<MinimizeIconType> = (props) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
|
||||
<title>minus</title>
|
||||
<path d="M19,13H5V11H19V13Z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default MinimizeIcon;
|
||||
@@ -22,7 +22,7 @@ const uploaderSlice = createSlice({
|
||||
initialState,
|
||||
reducers: {
|
||||
addUpload(state, action: PayloadAction<UploadItemType>) {
|
||||
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;
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user