Yann
update css, mobile ui
35961be
import React, {
ChangeEvent,
useCallback,
useContext,
useEffect,
useRef,
useState,
} from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { Delete, UploadFile } from "@mui/icons-material";
import {
Card,
Box,
CardContent,
Typography,
CardActions,
Button,
Modal,
CircularProgress,
} from "@mui/material";
import { ThemeSchemeContext, ThemeModeContext } from "../theme";
const AudioUploader = ({ ...props }) => {
const { themeScheme } = useContext(ThemeSchemeContext);
const { themeMode } = useContext(ThemeModeContext);
const light = themeScheme[themeMode];
const navigate = useNavigate();
const [isVisible, setIsVisible] = useState(false);
const [NextCard, setNextCard] = useState(false);
const [isError, setIsError] = useState(false);
const [audioFile, setAudioFile] = useState<File | null>(null);
const [uploadStatus, setUploadStatus] = useState("");
const inputFile = useRef<HTMLInputElement | null>(null);
const [modalOpen, setModalOpen] = useState(false);
const onDragEnter = useCallback(
(e: { stopPropagation: () => void; preventDefault: () => void }) => {
setIsVisible(true);
e.stopPropagation();
e.preventDefault();
return false;
},
[]
);
const onDragOver = useCallback(
(e: { preventDefault: () => void; stopPropagation: () => void }) => {
e.preventDefault();
e.stopPropagation();
return false;
},
[]
);
const onDragLeave = useCallback(
(e: { stopPropagation: () => void; preventDefault: () => void }) => {
setIsVisible(false);
e.stopPropagation();
e.preventDefault();
return false;
},
[]
);
const onDrop = useCallback(
(e: { preventDefault: () => void; dataTransfer: any }) => {
e.preventDefault();
setAudioFile(e.dataTransfer.files[0]);
console.log("Files dropped: ", audioFile?.name);
setNextCard(true);
setIsVisible(false);
return false;
},
[]
);
useEffect(() => {
window.addEventListener("mouseup", onDragLeave);
window.addEventListener("dragenter", onDragEnter);
window.addEventListener("dragover", onDragOver);
window.addEventListener("drop", onDrop);
return () => {
window.removeEventListener("mouseup", onDragLeave);
window.removeEventListener("dragenter", onDragEnter);
window.removeEventListener("dragover", onDragOver);
window.removeEventListener("drop", onDrop);
};
}, [onDragEnter, onDragLeave, onDragOver, onDrop]);
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
setAudioFile(file);
setNextCard(true);
}
};
const handleCloseModal = () => {
setModalOpen(false);
};
const onButtonClick = () => {
// `current` points to the mounted file input element
inputFile?.current?.click();
};
const handleUpload = async () => {
if (audioFile) {
try {
const server = import.meta.env.VITE_API_URL;
const form = new FormData();
if (audioFile) {
setModalOpen(true);
const blob = new Blob([audioFile], {
type: "application/octet-stream",
});
const audio_file = new File([blob], audioFile.name, {
type: blob.type,
});
form.append("file", audio_file);
}
const response = await axios.post(
`${server}/upload/`,
form,
{
headers: { Accept: "multipart/form-data" },
responseType: "blob",
}
);
setUploadStatus("Upload successful. Waiting for generation...");
console.log("Upload successful:", response);
// Extract JSON from the blob
const blobText = await response.data.text();
const jsonFromBlob = JSON.parse(blobText);
// Assuming the 'id' property is part of the JSON
const file_path = jsonFromBlob.file_path;
const csv_file_path = jsonFromBlob.csv_path;
const output_file_path = jsonFromBlob.output_file_path;
// Store the ID in localStorage
localStorage.setItem("file_path", file_path);
// Store the ID in localStorage
localStorage.setItem("csv_file_path", csv_file_path);
// Store the ID in localStorage
localStorage.setItem("output_file_path", output_file_path);
// Start uploading
navigate("/Results");
// setUploadStatus('Generation complete!');
} catch (error) {
console.error("Error:", error);
props.handleClose();
setIsError(true);
setModalOpen(false);
setNextCard(false);
setUploadStatus(`Error: ${error}`);
}
}
};
return (
<>
<Box sx={{ display: "grid", gap: "1vh" }}>
<PaletteSwatch
title={uploadStatus}
titleColor={light.errorContainer}
onTitle={uploadStatus}
onTitleColor={light.onErrorContainer}
visible={isError}
/>
<Card variant={isVisible ? "outlined" : "filled"}>
<Box sx={{ display: NextCard ? "none" : "inherit" }}>
<CardContent sx={{ display: "grid", justifyItems: "center" }}>
<Typography gutterBottom variant="h5" sx={{ pb: 3 }}>
{isVisible
? "Drop here to upload"
: "Drag a file to start inference"}
</Typography>
<UploadFile sx={{ fontSize: "35px", color: "inherit" }} />
</CardContent>
<CardActions sx={{ display: "flex", justifyContent: "flex-end" }}>
<input
type="file"
accept="audio/*"
ref={inputFile}
style={{ display: "none" }}
onChange={handleFileChange}
/>
<Button
variant="filled"
size="small"
onClick={() => onButtonClick()}
>
Upload
</Button>
</CardActions>
</Box>
<Box sx={{ display: NextCard ? "inherit" : "none" }}>
<CardContent
sx={{
display: "flex",
justifyItems: "center",
flexDirection: "column",
alignItems: "flex-end",
gap: "1vh",
}}
>
<Box sx={{ mr: "1" }}>
<Button
variant="text"
sx={{fontSize:"10px", marginTop:-2, marginRight:-1.5}}
onClick={() => {
setNextCard(false);
setIsVisible(false);
}}
>
<Delete />
</Button>
</Box>
<Typography fontFamily={"monospace"} fontSize={"15pt"}>
{audioFile?.name}
</Typography>
</CardContent>
<CardActions sx={{ display: "flex", justifyContent: "center" }}>
<Button
variant="filled"
size="medium"
onClick={() => handleUpload()}
>
Confirm
</Button>
</CardActions>
</Box>
</Card>
<Modal
open={modalOpen}
onClose={handleCloseModal}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style_modal}>
<CircularProgress size={60} thickness={4} />
</Box>
</Modal>
</Box>
</>
);
};
export default AudioUploader;
const PaletteSwatch = ({ onTitle, titleColor, onTitleColor, visible }: any) => {
return (
<Box
sx={{
p: 1.5,
borderRadius: "10px",
bgcolor: onTitleColor,
color: titleColor,
visibility: visible ? "visible" : "collapse",
}}
>
<Typography fontSize={12} fontWeight={"bold"}>
{onTitle}
</Typography>
</Box>
);
};
const style_modal = {
position: "absolute" as "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
color: "inherit",
bgcolor: "background.paper",
p: 4,
borderRadius: "10px",
display: "flex",
justifyContent: "center",
alignTtems: "center",
};