chatty / client /src /hooks /useUpload.jsx
arabdullah's picture
@ARAbdullaSL
a0fda44 verified
import { useState, useEffect } from "react";
import { useDispatch } from "react-redux";
import { chatActions } from "../store/chatSlice";
import { notificationActions } from "../store/notificationSlice";
import useFetch from "./useFetch";
const useUpload = (fn, formatsAllowed) => {
const [base64Format, setBase64Format] = useState();
const [fileType, setFileType] = useState();
const [extraFileData, setExtraFileData] = useState();
const dispatch = useDispatch();
// Convert file to base64
const fileToBase64 = (file) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
setBase64Format(reader.result);
};
};
// Handle file being added to form
const handleFileUpload = (event) => {
// Get file
const file = event.target.files[0];
setExtraFileData(event.target.extraFileData);
// Restrict to only files less than 50mb
const limit = 51200000;
if (file.size > limit) {
dispatch(
notificationActions.addNotification({
message: "File too large",
type: "error",
})
);
return;
}
// Restrict to only allowed formats
if (
!formatsAllowed.some((format) =>
file.type.toLowerCase().startsWith(format.toLowerCase())
)
) {
const errorMessage = formatsAllowed.reduce((finalStr, currStr, index) => {
if (!index) return finalStr;
else {
return finalStr + ` or ${currStr}`;
}
}, `${formatsAllowed[0]}`);
dispatch(
notificationActions.addNotification({
message: `Only ${errorMessage} allowed`,
type: "error",
})
);
return;
}
const fileTypeStr = file.type.split("/")[0].toLowerCase();
setFileType(fileTypeStr);
dispatch(chatActions.setMode({ mode: `${fileTypeStr}Upload` }));
// Convert file
fileToBase64(file);
};
// Upload file to cloud
const { reqFn: uploadToCloud, reqState: fileUploadState } = useFetch(
{ method: "POST", url: "/upload" },
(data) => {
fn({ ...data.data.uploadData, extraFileData });
setBase64Format("");
},
() => {
dispatch(chatActions.resetMode());
}
);
useEffect(() => {
if (base64Format) {
uploadToCloud({
data: base64Format,
fileType: fileType === "audio" ? "video" : fileType,
});
}
}, [base64Format]);
return {
handleFileUpload,
fileUploadState,
uploadToCloud,
};
};
export default useUpload;