215 lines
5.9 KiB
TypeScript
215 lines
5.9 KiB
TypeScript
import style from "./style.module.css";
|
||
import { useEffect, useMemo, useRef, useState } from "react";
|
||
import { Close } from "@mui/icons-material";
|
||
import {
|
||
Button,
|
||
Dialog,
|
||
DialogActions,
|
||
DialogContent,
|
||
DialogTitle,
|
||
IconButton,
|
||
} from "@mui/material";
|
||
import fileSize from "filesize";
|
||
import SendIcon from "@mui/icons-material/Send";
|
||
import { inputFile, sendFile, uploadBigFile } from "../../telegram/telegram";
|
||
import { useDispatch } from "react-redux";
|
||
import { addFileOfStorage } from "../../store/fileList";
|
||
|
||
enum Status {
|
||
normal,
|
||
addFile,
|
||
receive,
|
||
}
|
||
|
||
interface Props {
|
||
isSignIn: boolean;
|
||
onNotSignIn: () => void;
|
||
}
|
||
|
||
export function HomeButton(props: Props) {
|
||
let [status, setStatus] = useState(Status.normal);
|
||
let [boxStyle, setBoxStyle] = useState([style.box]);
|
||
let [isReceive, setIsReceive] = useState(false);
|
||
let [waitedFileList, setWaitedFileList] = useState<any[]>([]);
|
||
let [uploadRatio, setUploadRatio] = useState(0);
|
||
let [isFinish, setIsFinish] = useState(false);
|
||
let [startUploadTime, setStartUploadTime] = useState(0);
|
||
|
||
let uploadSpeed = useMemo(() => {
|
||
if (waitedFileList.length === 0) {
|
||
return "0/s";
|
||
}
|
||
let size = waitedFileList[0].size;
|
||
if (uploadRatio === 0) {
|
||
return "0/s";
|
||
}
|
||
return (
|
||
fileSize((size * uploadRatio * 10) / (Date.now() - startUploadTime)) +
|
||
"/s"
|
||
);
|
||
}, [startUploadTime, uploadRatio, waitedFileList]);
|
||
|
||
const dispatch = useDispatch();
|
||
|
||
let onNormal = () => {
|
||
setStatus(Status.normal);
|
||
};
|
||
let onAddFile = () => {
|
||
setStatus(Status.addFile);
|
||
};
|
||
let onReceive = () => {
|
||
setStatus(Status.receive);
|
||
};
|
||
|
||
useEffect(() => {
|
||
switch (status) {
|
||
case Status.normal:
|
||
setBoxStyle([style.box]);
|
||
break;
|
||
case Status.addFile:
|
||
setBoxStyle([style.box, style.boxActivePlus]);
|
||
break;
|
||
case Status.receive:
|
||
setBoxStyle([style.box, style.boxActiveReceive]);
|
||
break;
|
||
}
|
||
}, [status]);
|
||
|
||
let addFileInput = useRef<HTMLInputElement>(null);
|
||
|
||
let OnChangeFileInput = (e: any) => {
|
||
setWaitedFileList(e.target.files);
|
||
};
|
||
|
||
let handleFileUpload = () => {
|
||
setUploadRatio(1);
|
||
setStartUploadTime(Date.now());
|
||
const reader = new FileReader();
|
||
reader.onload = function (event) {
|
||
if (event.target && event.target.result) {
|
||
let bytes = event.target.result;
|
||
uploadBigFile(bytes as ArrayBuffer, setUploadRatio)
|
||
.then((file) => {
|
||
console.log("uploadFile ret:", file);
|
||
sendFile(
|
||
// @ts-ignore
|
||
inputFile(file.file_id, file.total_part, waitedFileList[0].name),
|
||
waitedFileList[0].type
|
||
).then((result) => {
|
||
console.log("sendFile ret:", result);
|
||
result.updates[1].message.media.document.file_name =
|
||
waitedFileList[0].name;
|
||
dispatch(
|
||
addFileOfStorage(result.updates[1].message.media.document)
|
||
);
|
||
setIsFinish(true);
|
||
});
|
||
})
|
||
.catch((error) => {
|
||
console.log("uploadFile error:", error);
|
||
alert(error);
|
||
});
|
||
}
|
||
};
|
||
reader.readAsArrayBuffer(waitedFileList[0]);
|
||
};
|
||
return (
|
||
<div className={boxStyle.join(" ")}>
|
||
{!isReceive ? (
|
||
<>
|
||
<div className={style.plus}>➕</div>
|
||
<div
|
||
className={style.addFile}
|
||
onMouseEnter={onAddFile}
|
||
onMouseLeave={onNormal}
|
||
onClick={() => addFileInput.current?.click()}
|
||
>
|
||
添加文件
|
||
<input
|
||
ref={addFileInput}
|
||
type="file"
|
||
style={{ display: "none" }}
|
||
onChange={OnChangeFileInput}
|
||
/>
|
||
</div>
|
||
<button
|
||
className={style.receive}
|
||
onMouseEnter={onReceive}
|
||
onMouseLeave={onNormal}
|
||
onClick={() => {
|
||
if (props.isSignIn) {
|
||
setIsReceive(true);
|
||
} else {
|
||
props.onNotSignIn();
|
||
}
|
||
}}
|
||
>
|
||
接收文件
|
||
</button>
|
||
</>
|
||
) : (
|
||
<>
|
||
<input
|
||
placeholder={"输入6位传输口令获取文件"}
|
||
style={{}}
|
||
className={isReceive ? style.receiveInput : style.receiveInputNone}
|
||
/>
|
||
<IconButton
|
||
className={style.receiveInputClose}
|
||
aria-label="delete"
|
||
onClick={() => {
|
||
setIsReceive(false);
|
||
}}
|
||
>
|
||
<Close />
|
||
</IconButton>
|
||
</>
|
||
)}
|
||
|
||
<Dialog open={waitedFileList.length !== 0}>
|
||
<DialogTitle>文件上传</DialogTitle>
|
||
<DialogContent sx={{ minWidth: 300 }}>
|
||
是否上传文件?
|
||
<br />
|
||
<br />
|
||
文件名: {waitedFileList.length > 0 ? waitedFileList[0].name : ""}
|
||
<br />
|
||
文件大小:{" "}
|
||
{waitedFileList.length > 0 ? fileSize(waitedFileList[0].size) : ""}
|
||
<br />
|
||
{uploadRatio !== 0 && <>正在上传: {uploadRatio.toFixed(2)}%</>}
|
||
<br />
|
||
{uploadRatio !== 0 && (
|
||
<>已用时间: {(Date.now() - startUploadTime) / 1000}s</>
|
||
)}
|
||
<br />
|
||
{uploadRatio !== 0 && <>上传速度: {uploadSpeed}</>}
|
||
<br />
|
||
{isFinish && <>上传完成</>}
|
||
</DialogContent>
|
||
<DialogActions>
|
||
<Button
|
||
variant="outlined"
|
||
onClick={() => {
|
||
setWaitedFileList([]);
|
||
setUploadRatio(0);
|
||
setIsFinish(false);
|
||
}}
|
||
>
|
||
取消
|
||
</Button>
|
||
{uploadRatio === 0 && (
|
||
<Button
|
||
variant="contained"
|
||
onClick={handleFileUpload}
|
||
endIcon={<SendIcon />}
|
||
>
|
||
上传
|
||
</Button>
|
||
)}
|
||
</DialogActions>
|
||
</Dialog>
|
||
</div>
|
||
);
|
||
}
|