I am having a file upload component, that takes in a list of files to be uploaded. I The wau I implemented, each of these files have thir timers run in parallel without affecting others. Progress bar are attached to each file and they are run to completion parallely. What I want is once I select files, I want each file to run its progress bar in sequential manner instead all progress bars at once. Like take a single file, run its progress and then onc eits done ,go to the next one
Can someone help
https://codesandbox.io/s/updated-file-upload-4vrnks?file=/src/Upload.tsxfile=/src/Upload.tsx:0-3474
import * as React from "react";
import { Stack, Button, ListItem } from "@material-ui/core";
import { useEffect, useRef } from "react";
import { Progress } from "./Progress";
export interface FileType {
file: File;
isDeleted: boolean;
uploadStatus: number;
uploadError: string;
uploadAbort: boolean;
}
interface FileUploaderProps {
selectedFiles: FileType[];
setSelectedFiles: React.Dispatch<React.SetStateAction<FileType[]>>;
file: FileType;
}
const UploadFile = ({ file, setSelectedFiles }: FileUploaderProps) => {
const timerRef = useRef<ReturnType<typeof setInterval> | undefined>();
const pollRef = useRef<number>();
pollRef.current = file.uploadStatus;
const onFileUpload = () => {
timerRef.current = setInterval(() => {
if (pollRef.current === 100) {
clearInterval(timerRef?.current);
return pollRef?.current;
}
const diff = Math.random() * 15;
let currentProgess = file.uploadStatus;
setSelectedFiles((prevState) => {
return prevState.map((current: FileType) => {
if (current.file.name === file.file.name) {
currentProgess = Math.min(current.uploadStatus + diff, 100);
return {
...current,
uploadStatus: currentProgess
};
}
return current;
});
});
return currentProgess;
}, 100 * Math.floor(Math.random() * 6) + 5 * 50);
};
useEffect(() => {
onFileUpload();
return () => {
clearInterval(timerRef.current);
};
}, []);
const cancelTimer = (e: React.MouseEvent<HTMLSpanElement>) => {
e.stopPropagation();
setSelectedFiles((prevState) => {
return prevState.map((current: FileType) => {
if (current.file.name === file.file.name) {
return {
...current,
uploadAbort: true,
uploadStatus: 0,
uploadError: "File Upload cancelled"
};
}
return current;
});
});
clearInterval(timerRef.current);
};
return (
<ListItem key={file.file.name} className={"file-name"}>
<span style={{ padding: "10px" }}>{file.file.name}</span>
{file.uploadStatus !== 100 ? (
file.uploadError || file.uploadAbort ? (
<div className={"upload-error"}>
<span>{file.file.name}</span>
<span style={{ padding: "10px" }}>{file.uploadError}</span>
</div>
) : (
<>
<span>Uploading...</span>
<Stack sx={{ width: "80px", padding: "20px" }} spacing={2}>
<Progress progress={file.uploadStatus} />
</Stack>
<Button variant="contained" color="error" onClick={cancelTimer}>
Cancel
</Button>
</>
)
) : (
<>
<span className="primary">{file.file.name}</span>
</>
)}
{file.uploadStatus === 100 && (
<Button
variant="contained"
color="error"
className="mgmt-Delete-icon"
style={{ padding: "10px" }}
onClick={(e: React.MouseEvent<HTMLSpanElement>) => {
e.stopPropagation();
setSelectedFiles((prevState) => {
return prevState.map((current: FileType) => {
if (current.file.name === file.file.name) {
return {
...current,
isDeleted: true
};
}
return current;
});
});
}}
>
Delete
</Button>
)}
</ListItem>
);
};
export default UploadFile;