add request exception handling and toast notifications for error
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Logs from "../components/Logs"
|
import Logs from "../components/Logs"
|
||||||
|
import Toast from "../components/Toast";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {
|
import {
|
||||||
Typography,
|
Typography,
|
||||||
@@ -23,13 +24,17 @@ function UploadPage() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { socket, isConnected } = useWebSocket();
|
const { socket, isConnected } = useWebSocket();
|
||||||
const { setMediaFile, setResponse, setLogs } = useMediaContext();
|
const { setMediaFile, setResponse, setLogs, setToastOpen, setToastMessage } = useMediaContext();
|
||||||
const [file, setFile] = useState<File | null>(null);
|
const [file, setFile] = useState<File | null>(null);
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
const [fileError, setFileError] = useState("");
|
|
||||||
const [upload, setUpload] = useState(false);
|
const [upload, setUpload] = useState(false);
|
||||||
const [inputEnabled, setInputEnabled] = useState(false);
|
const [inputEnabled, setInputEnabled] = useState(false);
|
||||||
|
|
||||||
|
const showErrorToast = (message: string) => {
|
||||||
|
setToastMessage(message);
|
||||||
|
setToastOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const startLogs = async () => {
|
const startLogs = async () => {
|
||||||
setLogs([formatLogMessage("Initializing freqsplit")]);
|
setLogs([formatLogMessage("Initializing freqsplit")]);
|
||||||
@@ -102,7 +107,6 @@ function UploadPage() {
|
|||||||
|
|
||||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setUpload(false);
|
setUpload(false);
|
||||||
setFileError("");
|
|
||||||
setResponse({
|
setResponse({
|
||||||
audio_class: "",
|
audio_class: "",
|
||||||
file_uuid: "",
|
file_uuid: "",
|
||||||
@@ -115,7 +119,7 @@ function UploadPage() {
|
|||||||
|
|
||||||
if (selectedFile) {
|
if (selectedFile) {
|
||||||
if (selectedFile.size > maxSize) {
|
if (selectedFile.size > maxSize) {
|
||||||
setFileError("Max file size is 100MB!");
|
showErrorToast("Max file size is 100MB!");
|
||||||
setFile(null);
|
setFile(null);
|
||||||
setUpload(false);
|
setUpload(false);
|
||||||
e.target.value = "";
|
e.target.value = "";
|
||||||
@@ -128,13 +132,11 @@ function UploadPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const validateAndSetFile = (file: File | null) => {
|
const validateAndSetFile = (file: File | null) => {
|
||||||
setFileError("");
|
|
||||||
|
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
const fileType = file.type;
|
const fileType = file.type;
|
||||||
if (!fileType.includes("audio") && !fileType.includes("video")) {
|
if (!fileType.includes("audio") && !fileType.includes("video")) {
|
||||||
setFileError("Please upload only audio or video files.");
|
showErrorToast("Please upload only audio or video files.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +153,7 @@ function UploadPage() {
|
|||||||
}); //
|
}); //
|
||||||
navigate('/preview');
|
navigate('/preview');
|
||||||
} else {
|
} else {
|
||||||
setFileError("Please upload a file to continue.");
|
showErrorToast("Please upload a file to continue");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -198,6 +200,16 @@ function UploadPage() {
|
|||||||
setLogs((prevLogs) => [...prevLogs, formatLogMessage(`freqsplit/input: audio_class: ${res.data.audio_class}`)])
|
setLogs((prevLogs) => [...prevLogs, formatLogMessage(`freqsplit/input: audio_class: ${res.data.audio_class}`)])
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
showErrorToast("Failed to upload file");
|
||||||
|
setUpload(false);
|
||||||
|
setResponse({
|
||||||
|
audio_class: "",
|
||||||
|
file_uuid: "",
|
||||||
|
sr: 0,
|
||||||
|
spectrogram: "",
|
||||||
|
spec_sr: 0
|
||||||
|
});
|
||||||
|
setFile(null);
|
||||||
console.error("Upload failed:", error);
|
console.error("Upload failed:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -255,12 +267,6 @@ function UploadPage() {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{fileError && (
|
|
||||||
<Typography variant="body2" color="error" sx={{ mt: 1 }}>
|
|
||||||
{fileError}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Box sx={{ mt: 4, display: "flex", justifyContent: "space-between" }}>
|
<Box sx={{ mt: 4, display: "flex", justifyContent: "space-between" }}>
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
@@ -280,6 +286,7 @@ function UploadPage() {
|
|||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
<Logs />
|
<Logs />
|
||||||
|
<Toast />
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Snackbar, Alert } from "@mui/material";
|
||||||
|
import { useMediaContext } from "../contexts/MediaContext";
|
||||||
|
|
||||||
|
const Toast: React.FC = () => {
|
||||||
|
const { toastOpen, setToastOpen, toastMessage } = useMediaContext();
|
||||||
|
return (
|
||||||
|
<Snackbar
|
||||||
|
open={toastOpen}
|
||||||
|
autoHideDuration={4000}
|
||||||
|
onClose={() => {
|
||||||
|
setToastOpen(false);
|
||||||
|
}}
|
||||||
|
anchorOrigin={{ vertical: "top", horizontal: "right" }}
|
||||||
|
>
|
||||||
|
<Alert
|
||||||
|
onClose={() => setToastOpen(false)}
|
||||||
|
severity="error"
|
||||||
|
sx={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
{toastMessage}
|
||||||
|
</Alert>
|
||||||
|
</Snackbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Toast
|
||||||
@@ -13,6 +13,10 @@ interface MediaContextType {
|
|||||||
setDownloadedFileSpectrogram: (spectrogram: {spectrogram: string, spec_sr: number}) => void;
|
setDownloadedFileSpectrogram: (spectrogram: {spectrogram: string, spec_sr: number}) => void;
|
||||||
logs: string[];
|
logs: string[];
|
||||||
setLogs: React.Dispatch<React.SetStateAction<string[]>>;
|
setLogs: React.Dispatch<React.SetStateAction<string[]>>;
|
||||||
|
toastOpen: boolean;
|
||||||
|
setToastOpen: ( value: boolean) => void;
|
||||||
|
toastMessage: string;
|
||||||
|
setToastMessage: ( message: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -34,9 +38,11 @@ export const MediaProvider: React.FC<{ children: React.ReactNode }> = ({ childre
|
|||||||
spec_sr: 0
|
spec_sr: 0
|
||||||
});
|
});
|
||||||
const [logs, setLogs] = useState<MediaContextType["logs"]>([""]);
|
const [logs, setLogs] = useState<MediaContextType["logs"]>([""]);
|
||||||
|
const [toastOpen, setToastOpen] = useState<MediaContextType["toastOpen"]>(false);
|
||||||
|
const [toastMessage, setToastMessage] = useState<MediaContextType["toastMessage"]>("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MediaContext.Provider value={{ mediaFile, setMediaFile, response, setResponse, extractedFiles, setExtractedFiles, downloadedFileURL, setDownloadedFileURL, downloadedFileSpectrogram, setDownloadedFileSpectrogram, logs, setLogs }}>
|
<MediaContext.Provider value={{ mediaFile, setMediaFile, response, setResponse, extractedFiles, setExtractedFiles, downloadedFileURL, setDownloadedFileURL, downloadedFileSpectrogram, setDownloadedFileSpectrogram, logs, setLogs, toastOpen, setToastOpen, toastMessage, setToastMessage }}>
|
||||||
{children}
|
{children}
|
||||||
</MediaContext.Provider>
|
</MediaContext.Provider>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user