Spaces:
Paused
Paused
| 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; | |