From 324c31a7ddc5ab1c1f774d8489635005f5654a78 Mon Sep 17 00:00:00 2001 From: hwangjungmin Date: Fri, 21 Oct 2022 12:07:11 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=EC=97=90=20=EB=8C=80=ED=95=9C=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/ErrorMessage.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/constants/ErrorMessage.ts b/frontend/src/constants/ErrorMessage.ts index f50c40bd2..3bb3f99b2 100644 --- a/frontend/src/constants/ErrorMessage.ts +++ b/frontend/src/constants/ErrorMessage.ts @@ -35,5 +35,7 @@ export const ErrorMessage = { '5008': '투표 내역이 존재하지 않습니다.', '5009': '투표항목은 2개이상 5개 이하로 등록해주세요.', + '7001': '지원하지 않는 형식입니다.', + '9999': '런타임 에러입니다. 코드를 확인해주세요', }; From baf4b5f927dc30d1a7c6b4d9c8292c1e9cb2493f Mon Sep 17 00:00:00 2001 From: hwangjungmin Date: Fri, 21 Oct 2022 12:08:17 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20useToastImageConverter=EB=A5=BC=20?= =?UTF-8?q?=ED=86=B5=ED=95=98=EC=97=AC=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit blockThrowError가 true일때는 에러바운더리에 도달하지 않도록 설정 --- frontend/src/api/image.ts | 6 +-- .../src/hooks/common/useThrowCustomError.tsx | 9 +++- .../hooks/common/useToastImageConverter.tsx | 45 +++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 frontend/src/hooks/common/useToastImageConverter.tsx diff --git a/frontend/src/api/image.ts b/frontend/src/api/image.ts index 407de9161..589c57726 100644 --- a/frontend/src/api/image.ts +++ b/frontend/src/api/image.ts @@ -3,15 +3,13 @@ import axios from 'axios'; import { ACCESSTOKEN_KEY } from '@/constants'; import { HOME_URL } from '@/constants/apiUrl'; -export const postImageUrlConverter = async (formData: FormData) => { +export const postImageUrlConverter = (formData: FormData) => { const accessToken = localStorage.getItem(ACCESSTOKEN_KEY); - const response = await axios.post(`${HOME_URL}/api/images`, formData, { + return axios.post(`${HOME_URL}/api/images`, formData, { headers: { 'Content-Type': 'multipart/form-data', Authorization: `Bearer ${accessToken}`, }, }); - - return response.data.url; }; diff --git a/frontend/src/hooks/common/useThrowCustomError.tsx b/frontend/src/hooks/common/useThrowCustomError.tsx index d2ddb4ba1..6f089af24 100644 --- a/frontend/src/hooks/common/useThrowCustomError.tsx +++ b/frontend/src/hooks/common/useThrowCustomError.tsx @@ -1,5 +1,5 @@ import { AxiosError } from 'axios'; -import { useEffect } from 'react'; +import { Dispatch, SetStateAction, useEffect } from 'react'; import CustomError from '@/components/@helper/errorBoundary/CustomError'; import { ErrorMessage } from '@/constants/ErrorMessage'; @@ -10,8 +10,15 @@ const useThrowCustomError = ( errorCode: keyof typeof ErrorMessage; message: string; }> | null, + blockThrowError?: boolean, + setBlockThrowError?: Dispatch>, ) => { useEffect(() => { + if (blockThrowError && setBlockThrowError) { + setBlockThrowError(false); + return; + } + if (isError && error) { if (!error.response || typeof error.response.data === 'undefined') { throw new CustomError('0000', '네트워크에 문제가 발생하였습니다.'); diff --git a/frontend/src/hooks/common/useToastImageConverter.tsx b/frontend/src/hooks/common/useToastImageConverter.tsx new file mode 100644 index 000000000..b415768d2 --- /dev/null +++ b/frontend/src/hooks/common/useToastImageConverter.tsx @@ -0,0 +1,45 @@ +import useThrowCustomError from './useThrowCustomError'; +import { AxiosError, AxiosResponse } from 'axios'; +import { MutableRefObject, useEffect, useState } from 'react'; +import { useMutation } from 'react-query'; + +import { postImageUrlConverter } from '@/api/image'; +import { ErrorMessage } from '@/constants/ErrorMessage'; +import useSnackBar from '@/hooks/common/useSnackBar'; +import { Editor } from '@toast-ui/react-editor'; + +const useToastImageConverter = (content: MutableRefObject) => { + const { showSnackBar } = useSnackBar(); + const [blockThrowError, setBlockThrowError] = useState(false); + const { isError, error, mutateAsync } = useMutation< + AxiosResponse<{ url: string }>, + AxiosError<{ errorCode: keyof typeof ErrorMessage; message: string }>, + FormData + >(postImageUrlConverter, { + onError: (error) => { + if (typeof error.response?.data === 'undefined') { + showSnackBar('컨텐츠의 용량이 너무 큽니다.'); + setBlockThrowError(true); + return; + } + }, + }); + + useEffect(() => { + if (content.current) { + content.current.getInstance().removeHook('addImageBlobHook'); + content.current.getInstance().addHook('addImageBlobHook', (blob, callback) => { + (async () => { + const formData = new FormData(); + formData.append('file', blob); + const data = await mutateAsync(formData); + callback(data.data.url, '게시물 이미지'); + })(); + }); + } + }, [content.current]); + + useThrowCustomError(isError, error, blockThrowError, setBlockThrowError); +}; + +export default useToastImageConverter; From 883dc67f4f6e6968b0bc260c286363648c6e4570 Mon Sep 17 00:00:00 2001 From: hwangjungmin Date: Fri, 21 Oct 2022 12:08:30 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20useToastImageConverter=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../useHandleCommentInputModalState.tsx | 8 +++----- frontend/src/pages/UpdateWriting/index.tsx | 14 ++++++-------- frontend/src/pages/WritingArticles/index.tsx | 8 +++----- frontend/src/utils/takeToastImgEditor.ts | 18 ------------------ 4 files changed, 12 insertions(+), 36 deletions(-) delete mode 100644 frontend/src/utils/takeToastImgEditor.ts diff --git a/frontend/src/hooks/comment/useHandleCommentInputModalState.tsx b/frontend/src/hooks/comment/useHandleCommentInputModalState.tsx index 423bfb452..7da15ae46 100644 --- a/frontend/src/hooks/comment/useHandleCommentInputModalState.tsx +++ b/frontend/src/hooks/comment/useHandleCommentInputModalState.tsx @@ -5,8 +5,8 @@ import usePostCommentInputModal from '@/hooks/comment/usePostCommentInputModal'; import usePutCommentInputModal from '@/hooks/comment/usePutCommentInputModal'; import useModal from '@/hooks/common/useModal'; import useSnackBar from '@/hooks/common/useSnackBar'; +import useToastImageConverter from '@/hooks/common/useToastImageConverter'; import { queryClient } from '@/index'; -import { takeToastImgEditor } from '@/utils/takeToastImgEditor'; import { validatedCommentInput } from '@/utils/validateInput'; import { Editor } from '@toast-ui/react-editor'; @@ -31,16 +31,14 @@ const useHandleCommentInputModalState = ({ isSuccess: putIsSuccess, } = usePutCommentInputModal(hideModal); + useToastImageConverter(commentContent); + useEffect(() => { if (postIsSuccess || putIsSuccess) { queryClient.refetchQueries('comments'); } }); - useEffect(() => { - takeToastImgEditor(commentContent); - }, [commentContent]); - useEffect(() => { const commentTempSavedInterval = setInterval(() => { if (commentContent.current !== null) { diff --git a/frontend/src/pages/UpdateWriting/index.tsx b/frontend/src/pages/UpdateWriting/index.tsx index fd8bd0c07..7cf58e29a 100644 --- a/frontend/src/pages/UpdateWriting/index.tsx +++ b/frontend/src/pages/UpdateWriting/index.tsx @@ -6,18 +6,14 @@ import Loading from '@/components/@common/Loading/Loading'; import ToastUiEditor from '@/components/@common/ToastUiEditor/ToastUiEditor'; import HashTag from '@/components/hashTag/HashTag/HashTag'; import usePostWritingArticle from '@/hooks/article/usePostUpdateWritingArticle'; +import useToastImageConverter from '@/hooks/common/useToastImageConverter'; import * as S from '@/pages/WritingArticles/index.styles'; import { WritingCategoryCardStyle, WritingTitleCardStyle } from '@/styles/cardStyle'; -import { takeToastImgEditor } from '@/utils/takeToastImgEditor'; const UpdateWriting = () => { const { id } = useParams(); const { category } = useParams(); - if (id === undefined || category === undefined) { - throw new Error('id와 category 값을 가지고 오지 못하였습니다'); - } - const { isLoading, title, @@ -31,9 +27,11 @@ const UpdateWriting = () => { handleClickUpdateSubmitButton, } = usePostWritingArticle(); - useEffect(() => { - takeToastImgEditor(content); - }, [content]); + useToastImageConverter(content); + + if (id === undefined || category === undefined) { + throw new Error('id와 category 값을 가지고 오지 못하였습니다'); + } if (isLoading) { return ; diff --git a/frontend/src/pages/WritingArticles/index.tsx b/frontend/src/pages/WritingArticles/index.tsx index 46a1e8c4f..4a7b32e44 100644 --- a/frontend/src/pages/WritingArticles/index.tsx +++ b/frontend/src/pages/WritingArticles/index.tsx @@ -8,11 +8,11 @@ import ToastUiEditor from '@/components/@common/ToastUiEditor/ToastUiEditor'; import HashTag from '@/components/hashTag/HashTag/HashTag'; import usePostWritingArticles from '@/hooks/article/usePostWritingArticles'; import useSnackBar from '@/hooks/common/useSnackBar'; +import useToastImageConverter from '@/hooks/common/useToastImageConverter'; import useGetTempDetailArticles from '@/hooks/tempArticle/useGetTempDetailArticles'; import usePostTempArticle from '@/hooks/tempArticle/usePostTempArticle'; import * as S from '@/pages/WritingArticles/index.styles'; import { WritingCategoryCardStyle, WritingTitleCardStyle } from '@/styles/cardStyle'; -import { takeToastImgEditor } from '@/utils/takeToastImgEditor'; const WritingArticles = ({ tempId = '' }: { tempId?: '' | number }) => { const { category } = useParams(); @@ -35,6 +35,8 @@ const WritingArticles = ({ tempId = '' }: { tempId?: '' | number }) => { setHashTags, } = usePostWritingArticles({ category, isAnonymous }); + useToastImageConverter(content); + const { saveTempArticleId, isSuccess: isTempArticleSavedSuccess, @@ -84,10 +86,6 @@ const WritingArticles = ({ tempId = '' }: { tempId?: '' | number }) => { } }, [isTempDetailArticleSuccess]); - useEffect(() => { - takeToastImgEditor(content); - }, [content]); - if (isLoading) return ; const handleClickTemporaryStoreButton = () => { diff --git a/frontend/src/utils/takeToastImgEditor.ts b/frontend/src/utils/takeToastImgEditor.ts deleted file mode 100644 index d93899fc3..000000000 --- a/frontend/src/utils/takeToastImgEditor.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { MutableRefObject } from 'react'; - -import { postImageUrlConverter } from '@/api/image'; -import { Editor } from '@toast-ui/react-editor'; - -export const takeToastImgEditor = (content: MutableRefObject) => { - if (content.current) { - content.current.getInstance().removeHook('addImageBlobHook'); - content.current.getInstance().addHook('addImageBlobHook', (blob, callback) => { - (async () => { - const formData = new FormData(); - formData.append('file', blob); - const url = await postImageUrlConverter(formData); - callback(url, 'alt-text'); - })(); - }); - } -}; From 5fdd9ef3f30bd124e3eefc5840b1560712282de1 Mon Sep 17 00:00:00 2001 From: hwangjungmin Date: Fri, 21 Oct 2022 12:09:45 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=EC=A0=88=EB=8C=80=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/common/useToastImageConverter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/hooks/common/useToastImageConverter.tsx b/frontend/src/hooks/common/useToastImageConverter.tsx index b415768d2..b24b5b78e 100644 --- a/frontend/src/hooks/common/useToastImageConverter.tsx +++ b/frontend/src/hooks/common/useToastImageConverter.tsx @@ -1,4 +1,3 @@ -import useThrowCustomError from './useThrowCustomError'; import { AxiosError, AxiosResponse } from 'axios'; import { MutableRefObject, useEffect, useState } from 'react'; import { useMutation } from 'react-query'; @@ -6,6 +5,7 @@ import { useMutation } from 'react-query'; import { postImageUrlConverter } from '@/api/image'; import { ErrorMessage } from '@/constants/ErrorMessage'; import useSnackBar from '@/hooks/common/useSnackBar'; +import useThrowCustomError from '@/hooks/common/useThrowCustomError'; import { Editor } from '@toast-ui/react-editor'; const useToastImageConverter = (content: MutableRefObject) => { From e7c38db1f94454dbb6625d775d5274fd525b60b5 Mon Sep 17 00:00:00 2001 From: hwangjungmin Date: Fri, 21 Oct 2022 12:19:36 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=EA=B0=80=20?= =?UTF-8?q?=EB=82=98=EC=98=AC=20=EA=B2=BD=EC=9A=B0=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=EC=9D=B4=20=EB=8B=AB=ED=9E=88=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/common/useToastImageConverter.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/hooks/common/useToastImageConverter.tsx b/frontend/src/hooks/common/useToastImageConverter.tsx index b24b5b78e..28f8fd0ff 100644 --- a/frontend/src/hooks/common/useToastImageConverter.tsx +++ b/frontend/src/hooks/common/useToastImageConverter.tsx @@ -17,9 +17,13 @@ const useToastImageConverter = (content: MutableRefObject) => { FormData >(postImageUrlConverter, { onError: (error) => { + setBlockThrowError(true); if (typeof error.response?.data === 'undefined') { showSnackBar('컨텐츠의 용량이 너무 큽니다.'); - setBlockThrowError(true); + return; + } + if (error.response.data.errorCode === '7001') { + showSnackBar(ErrorMessage[error.response.data.errorCode]); return; } }, From df20aaa2bd6996f78fe97911043ca2571a947189 Mon Sep 17 00:00:00 2001 From: hwangjungmin Date: Fri, 21 Oct 2022 13:35:03 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/ErrorMessage.ts | 2 +- frontend/src/hooks/common/useToastImageConverter.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/constants/ErrorMessage.ts b/frontend/src/constants/ErrorMessage.ts index 3bb3f99b2..ee77c0d6d 100644 --- a/frontend/src/constants/ErrorMessage.ts +++ b/frontend/src/constants/ErrorMessage.ts @@ -35,7 +35,7 @@ export const ErrorMessage = { '5008': '투표 내역이 존재하지 않습니다.', '5009': '투표항목은 2개이상 5개 이하로 등록해주세요.', - '7001': '지원하지 않는 형식입니다.', + '7002': '지원하지 않는 형식입니다.', '9999': '런타임 에러입니다. 코드를 확인해주세요', }; diff --git a/frontend/src/hooks/common/useToastImageConverter.tsx b/frontend/src/hooks/common/useToastImageConverter.tsx index 28f8fd0ff..cf7bae5fc 100644 --- a/frontend/src/hooks/common/useToastImageConverter.tsx +++ b/frontend/src/hooks/common/useToastImageConverter.tsx @@ -22,7 +22,7 @@ const useToastImageConverter = (content: MutableRefObject) => { showSnackBar('컨텐츠의 용량이 너무 큽니다.'); return; } - if (error.response.data.errorCode === '7001') { + if (error.response.data.errorCode === '7002') { showSnackBar(ErrorMessage[error.response.data.errorCode]); return; }