From 1f99d450e9ac0318150887c67892807323175a73 Mon Sep 17 00:00:00 2001 From: bicochan Date: Thu, 10 Apr 2025 14:39:19 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20tus=20=EC=97=85=EB=A1=9C=EB=93=9C?= =?UTF-8?q?=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/image/lib/utils.ts | 61 --------------------- apps/cs/src/pages/image/ui/image-form.tsx | 32 ++++++------ apps/cs/src/shared/lib/use-tus.ts | 64 +++++++++++++++++++++++ 3 files changed, 79 insertions(+), 78 deletions(-) delete mode 100644 apps/cs/src/pages/image/lib/utils.ts create mode 100644 apps/cs/src/shared/lib/use-tus.ts diff --git a/apps/cs/src/pages/image/lib/utils.ts b/apps/cs/src/pages/image/lib/utils.ts deleted file mode 100644 index c6c8ca101..000000000 --- a/apps/cs/src/pages/image/lib/utils.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Upload, type HttpResponse } from "tus-js-client"; -import { getCookie, setCookie } from "@/shared/lib"; -import { AUTH_USER_ID, CLAIM_NAME, ENDPOINT } from "@/shared/config"; - -type UploadOptions = { - handleUploadStart?: (upload: Upload) => void; - handleProgress?: (percentage: string) => void; - handleSuccess?: (upload: Upload) => void; - handleResponse?: (res: HttpResponse) => void; -}; - -export const handleUpload = (files: FileList, options?: UploadOptions) => { - let metadata = {}; - - const file = files.item(0); - if (!file) return; - metadata = { - filename: file.name, - filetype: file.type, - }; - - const atflCd = getCookie("atfl-cd-key"); - if (atflCd) { - metadata = { - ...metadata, - atflCd, - }; - } - - const upload = 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) { - console.error(`Failed because: ${error}`); - }, - onProgress(bytesUploaded, bytesTotal) { - const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2); - options?.handleProgress?.(percentage); - }, - onAfterResponse(req, res) { - const fileInfo = res.getHeader("X-File-Info"); - if (fileInfo === undefined || fileInfo === null) return; - - setCookie("atfl-cd-key", JSON.parse(fileInfo)?.atflCd ?? ""); - options?.handleResponse?.(res); - }, - onSuccess() { - options?.handleSuccess?.(upload); - }, - }); - - upload.start(); - options?.handleUploadStart?.(upload); - - console.log("upload start >>>>>", upload); -}; diff --git a/apps/cs/src/pages/image/ui/image-form.tsx b/apps/cs/src/pages/image/ui/image-form.tsx index 10c6fee6b..4a768811b 100644 --- a/apps/cs/src/pages/image/ui/image-form.tsx +++ b/apps/cs/src/pages/image/ui/image-form.tsx @@ -4,7 +4,7 @@ import Image from "next/image"; import { useEffect, useState } from "react"; import { useQuery } from "@tanstack/react-query"; import type { UseFormReturn } from "react-hook-form"; -import type { HttpResponse, Upload } from "tus-js-client"; +import type { HttpResponse } from "tus-js-client"; import { FileUploader, Input, @@ -22,10 +22,9 @@ import { FormWrapper } from "@/widgets/form-wrapper"; import { CodeSelect } from "@/entities/code"; import { AttachmentApi } from "@/entities/attachment"; import { ENDPOINT } from "@/shared/config"; -import { setCookie } from "@/shared/lib/cookie"; +import { useTus } from "@/shared/lib/use-tus"; import { FormControl, FormField, FormItem } from "@/shared/ui/form"; import type { ImageFormData } from "../model/image-interface"; -import { handleUpload } from "../lib/utils"; type ImageFormProps = { form: UseFormReturn; @@ -38,9 +37,13 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { const atflYn = form.watch("atflYn"); const atflCd = form.watch("atflCd"); + const { + file: uploadFile, + response: uploadResponse, + progress, + setFile, + } = useTus(); const [imageUrl, setImageUrl] = useState(""); - const [upload, setUpload] = useState(null); - const [progress, setProgress] = useState(0); const { data: attachmentData } = useQuery({ queryKey: [ENDPOINT.ATTACH_SERVICE.ATTACHMENTS, atflCd], @@ -49,10 +52,6 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { enabled: !!atflCd, }); - const handleProgress = (percentage: string) => { - setProgress(Number(percentage)); - }; - const handleUploadResponse = async (res: HttpResponse) => { const fileInfo = res.getHeader("X-File-Info"); if (fileInfo === undefined || fileInfo === null) return; @@ -64,6 +63,11 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { await AttachmentApi.deleteAttachmentByAtflCd(attachmentData.atflCd); }; + useEffect(() => { + if (!uploadResponse) return; + handleUploadResponse(uploadResponse); + }, [uploadResponse]); + useEffect(() => { (async () => { setImageUrl( @@ -197,13 +201,7 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { onUpload={(e) => { const files = e.target.files; if (!files) return; - setCookie("atfl-cd-key", ""); - handleUpload(files, { - handleUploadStart: setUpload, - handleProgress, - handleSuccess: setUpload, - handleResponse: handleUploadResponse, - }); + setFile(files[0] ?? null); }} customPreview={ <> @@ -220,7 +218,7 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { )}

- {(upload?.file as File)?.name} + {uploadFile?.name}

{ + 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 metadata = { + filename: file?.name ?? "", + filetype: file?.type ?? "", + atflCd: attachmentFileCode, + }; + + 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(Number(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; + + const upload = createUpload(); + upload.start(); + setUpload(upload); + }, [file]); + + return { + file, + upload, + response, + progress, + setFile, + }; +};