import { useEffect, useState } from "react"; import { type HttpResponse, Upload } from "tus-js-client"; import { AUTH_USER_ID, CLAIM_NAME, ENDPOINT } from "../config"; import { useAttachmentStore } from "./use-attachment-store"; import { useAlertStore } from "./use-alert-store"; import { getCookie } from "./cookie"; type TusProps = { accept?: string; }; export const useTus = ({ accept }: TusProps = {}) => { const alert = useAlertStore((state) => state.setMessage); const { attachmentFileCode, setAttachmentFileCode } = useAttachmentStore( (state) => state, ); const [file, setFile] = useState(null); const [upload, setUpload] = useState(null); const [response, setResponse] = useState(null); const [progress, setProgress] = useState(0); const [isValid, setIsValid] = useState(false); const metadata = { filename: file?.name ?? "", filetype: file?.type ?? "", atflCd: attachmentFileCode, }; const validFileType = (file: File) => { const allowedExtensions = accept?.split(",") ?? []; const fileName = file.name; const fileExtension = fileName .substring(fileName.lastIndexOf(".")) .toLowerCase(); if (!allowedExtensions.includes(fileExtension)) { alert("파일 형식이 올바르지 않습니다."); setIsValid(false); return false; } setIsValid(true); return true; }; const createUpload = () => { return new Upload(file!, { endpoint: `${ENDPOINT.ATTACH_SERVICE.TUS_UPLOAD}`, chunkSize: 10 * 1024 * 1024, headers: { [CLAIM_NAME]: getCookie(CLAIM_NAME) ?? "", [AUTH_USER_ID]: getCookie(AUTH_USER_ID) ?? "", }, metadata, onError(error) { throw new Error(`Failed because: ${error}`); }, onProgress(bytesUploaded, bytesTotal) { const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2); setProgress(parseInt(percentage)); }, onAfterResponse(req, res) { const fileInfo = res.getHeader("X-File-Info"); if (fileInfo === undefined || fileInfo === null) return; setAttachmentFileCode(JSON.parse(fileInfo)?.atflCd ?? ""); setResponse(res); }, }); }; useEffect(() => { if (!file) return; if (!validFileType(file)) return; const upload = createUpload(); upload.start(); setUpload(upload); }, [file]); return { file, upload, response, progress, isValid, setFile, }; };