mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
update the upload
This commit is contained in:
@@ -1,117 +1,119 @@
|
||||
import { Fragment } from 'react';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
import type { DropzoneState } from 'react-dropzone';
|
||||
import { ChangeEvent, useRef, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
|
||||
import { Box, Button, LinearProgress, Typography, useTheme } from '@mui/material';
|
||||
import type { Theme } from '@mui/material';
|
||||
import UploadIcon from '@mui/icons-material/Upload';
|
||||
import { Box, Button, LinearProgress, Typography } from '@mui/material';
|
||||
|
||||
import type { Progress } from 'alova';
|
||||
import * as SystemApi from 'api/system';
|
||||
|
||||
import { useRequest } from 'alova/client';
|
||||
import RestartMonitor from 'app/status/RestartMonitor';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
const getBorderColor = (theme: Theme, props: DropzoneState) => {
|
||||
if (props.isDragAccept) {
|
||||
return theme.palette.success.main;
|
||||
}
|
||||
if (props.isDragReject) {
|
||||
return theme.palette.error.main;
|
||||
}
|
||||
if (props.isDragActive) {
|
||||
return theme.palette.info.main;
|
||||
}
|
||||
return theme.palette.grey[700];
|
||||
};
|
||||
const SingleUpload = () => {
|
||||
const [md5, setMd5] = useState<string>();
|
||||
const [restarting, setRestarting] = useState<boolean>();
|
||||
|
||||
export interface SingleUploadProps {
|
||||
onDrop: (acceptedFiles: File[]) => void;
|
||||
onCancel: () => void;
|
||||
isUploading: boolean;
|
||||
progress: Progress;
|
||||
}
|
||||
|
||||
const SingleUpload = ({
|
||||
onDrop,
|
||||
onCancel,
|
||||
isUploading,
|
||||
progress
|
||||
}: SingleUploadProps) => {
|
||||
const uploading = isUploading && progress.total > 0;
|
||||
|
||||
const dropzoneState = useDropzone({
|
||||
onDrop,
|
||||
accept: {
|
||||
'application/octet-stream': ['.bin'],
|
||||
'application/json': ['.json'],
|
||||
'text/plain': ['.md5']
|
||||
},
|
||||
disabled: isUploading,
|
||||
multiple: false
|
||||
const {
|
||||
loading: isUploading,
|
||||
uploading: progress,
|
||||
send: sendUpload,
|
||||
abort: cancelUpload
|
||||
} = useRequest(SystemApi.uploadFile, {
|
||||
immediate: false
|
||||
}).onSuccess(({ data }) => {
|
||||
if (data) {
|
||||
setMd5(data.md5 as string);
|
||||
toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL());
|
||||
setFile(undefined);
|
||||
} else {
|
||||
setRestarting(true);
|
||||
}
|
||||
});
|
||||
|
||||
const { getRootProps, getInputProps } = dropzoneState;
|
||||
const theme = useTheme();
|
||||
const [file, setFile] = useState<File>();
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
const progressText = () => {
|
||||
if (uploading) {
|
||||
return (
|
||||
LL.UPLOADING() +
|
||||
': ' +
|
||||
Math.round((progress.loaded * 100) / progress.total) +
|
||||
'%'
|
||||
);
|
||||
console.log(progress); // TODO remove
|
||||
|
||||
const handleUploadClick = () => {
|
||||
inputRef.current?.click();
|
||||
};
|
||||
|
||||
const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
|
||||
if (!e.target.files) {
|
||||
return;
|
||||
}
|
||||
return LL.UPLOAD_DROP_TEXT();
|
||||
|
||||
setFile(e.target.files[0]);
|
||||
|
||||
await sendUpload(e.target.files[0]).catch((error: Error) => {
|
||||
if (error.message === 'The user aborted a request') {
|
||||
toast.warning(LL.UPLOAD() + ' ' + LL.ABORTED());
|
||||
} else if (error.message === 'Network Error') {
|
||||
toast.warning('Invalid file extension or incompatible bin file');
|
||||
} else {
|
||||
toast.error(error.message);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
{...getRootProps({
|
||||
sx: {
|
||||
py: 4,
|
||||
px: 2,
|
||||
borderWidth: 2,
|
||||
borderRadius: 2,
|
||||
borderStyle: 'dashed',
|
||||
color: theme.palette.grey[400],
|
||||
transition: 'border .24s ease-in-out',
|
||||
width: '100%',
|
||||
cursor: uploading ? 'default' : 'pointer',
|
||||
borderColor: getBorderColor(theme, dropzoneState)
|
||||
}
|
||||
})}
|
||||
>
|
||||
<input {...getInputProps()} />
|
||||
<Box flexDirection="column" display="flex" alignItems="center">
|
||||
<CloudUploadIcon fontSize="large" />
|
||||
<Typography variant="h6">{progressText()}</Typography>
|
||||
{uploading && (
|
||||
<Fragment>
|
||||
<Box width="100%" p={2}>
|
||||
<LinearProgress
|
||||
variant="determinate"
|
||||
value={
|
||||
progress.total === 0 || progress.loaded === 0
|
||||
? 0
|
||||
: progress.loaded <= progress.total
|
||||
? Math.round((progress.loaded * 100) / progress.total)
|
||||
: Math.round((progress.total * 100) / progress.loaded)
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={onCancel}
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
</Fragment>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
<>
|
||||
<input
|
||||
type="file"
|
||||
ref={inputRef}
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
|
||||
<Button
|
||||
sx={{ ml: 2 }}
|
||||
startIcon={<UploadIcon />}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={handleUploadClick}
|
||||
>
|
||||
{file ? LL.UPLOADING() + ` ${file.name}` : LL.UPLOAD()}
|
||||
</Button>
|
||||
|
||||
{isUploading && (
|
||||
<>
|
||||
<Box width="100%" p={2}>
|
||||
<LinearProgress
|
||||
variant="determinate"
|
||||
value={
|
||||
progress.total === 0 || progress.loaded === 0
|
||||
? 0
|
||||
: progress.loaded <= progress.total
|
||||
? Math.round((progress.loaded * 100) / progress.total)
|
||||
: Math.round((progress.total * 100) / progress.loaded)
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={cancelUpload}
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{md5 && (
|
||||
<Box mt={2}>
|
||||
<Typography variant="body2">{'MD5: ' + md5}</Typography>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{restarting && <RestartMonitor />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user