From 5c21c9e5ef211a8eab1c24aebdde9fea2995117a Mon Sep 17 00:00:00 2001 From: Seungchan On <62434898+cks3066@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:08:27 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[FE]=20=EC=A0=9C=EC=B6=9C=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20UI=20=EC=88=98=EC=A0=95=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.=20(#632)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [FE] 제출 컴포넌트 UI 수정 --- frontend/src/components/host/Submissions/index.tsx | 7 ++++--- frontend/src/components/host/Submissions/styles.ts | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/host/Submissions/index.tsx b/frontend/src/components/host/Submissions/index.tsx index 4c30e713..4ae1db65 100644 --- a/frontend/src/components/host/Submissions/index.tsx +++ b/frontend/src/components/host/Submissions/index.tsx @@ -1,9 +1,8 @@ +import { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import Button from '@/components/common/Button'; -import emptyFolder from '@/assets/emptyFolder.png'; - import styles from './styles'; const columns = ['제출자', '업무', '제출일자']; @@ -40,6 +39,8 @@ const Submissions: React.FC = ({ submissions, isFullSize = fal navigate('spaceRecord'); }; + const reversedSubmissions = useMemo(() => [...submissions].reverse(), [submissions]); + return (
@@ -62,7 +63,7 @@ const Submissions: React.FC = ({ submissions, isFullSize = fal - {submissions.map(({ submissionId, author, jobName, createdAt }) => ( + {reversedSubmissions.map(({ submissionId, author, jobName, createdAt }) => ( {author} {jobName} diff --git a/frontend/src/components/host/Submissions/styles.ts b/frontend/src/components/host/Submissions/styles.ts index ea8bc0df..0d23eeb7 100644 --- a/frontend/src/components/host/Submissions/styles.ts +++ b/frontend/src/components/host/Submissions/styles.ts @@ -8,12 +8,12 @@ const layout = ({ isFullSize }: { isFullSize: boolean }) => css` border-radius: 8px; font-size: 16px; box-shadow: 2px 2px 2px 2px ${theme.colors.shadow10}; - height: 360px; + padding-bottom: 24px; ${isFullSize && css` margin-top: 5rem; - height: 520px; + height: calc(50vh + 10em); `} @media screen and (min-width: 1024px) { @@ -62,7 +62,7 @@ const table = ({ isFullSize }: { isFullSize: boolean }) => css` display: flex; flex-direction: column; justify-content: start; - height: 100%; + width: 100%; overflow-y: ${isFullSize ? 'scroll' : 'hidden'}; height: ${isFullSize ? '50vh' : '12.5em'}; From b981e7ec9cce2f061b11d00785debaf33fb1dae6 Mon Sep 17 00:00:00 2001 From: Seungchan On <62434898+cks3066@users.noreply.github.com> Date: Thu, 20 Oct 2022 11:10:23 +0900 Subject: [PATCH 02/11] =?UTF-8?q?[FE]=20=ED=83=80=EC=9E=85=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=98=B5=EC=85=98=EC=9D=84=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=EC=97=90=20=EB=A7=9E?= =?UTF-8?q?=EA=B2=8C=20=EC=88=98=EC=A0=95=ED=95=9C=EB=8B=A4.=20(#635)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: tsconfig 옵션 변경 * feat: 누락된 옵션 추가 --- frontend/tsconfig.json | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 171d2d4e..787d2f16 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -1,33 +1,22 @@ { "compilerOptions": { "target": "es2016", - "composite": true, + "composite": false, "jsx": "react-jsx", "jsxImportSource": "@emotion/react", "module": "esnext", "moduleResolution": "node", - "resolveJsonModule": true, - "allowJs": true, - "noEmit": true, "isolatedModules": true, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, "strict": true, - "strictNullChecks": true, - "noImplicitThis": true, - "useUnknownInCatchVariables": true, "exactOptionalPropertyTypes": true, - "noImplicitReturns": true, + "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "allowUnreachableCode": false, "skipLibCheck": true, "baseUrl": ".", "paths": { "@/*": ["src/*"] - }, - "types": ["cypress", "node"] + } }, - "include": ["src", "cypress"], - "exclude": ["**/*.cy.ts"] + "include": ["src"] } From b48aba6145a7166f4e919b4f95bef2b280c23d62 Mon Sep 17 00:00:00 2001 From: Seungchan On <62434898+cks3066@users.noreply.github.com> Date: Thu, 20 Oct 2022 11:34:48 +0900 Subject: [PATCH 03/11] =?UTF-8?q?[FE]=20=EC=9E=91=EB=8F=99=EC=9D=B4=20?= =?UTF-8?q?=EC=97=86=EC=96=B4=EC=84=9C=20=EC=9B=B9=EC=86=8C=EC=BC=93=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=EC=9D=B4=20=EC=A2=85=EB=A3=8C=EB=90=98?= =?UTF-8?q?=EC=97=88=EC=9D=84=EB=95=8C,=20=EC=9E=AC=EC=97=B0=EA=B2=B0?= =?UTF-8?q?=EC=9D=84=20=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20=ED=95=9C=EB=8B=A4.=20(#637)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: reconnect_delay를 1초로 설정한다. --- frontend/frontend-security | 2 +- frontend/src/pages/user/TaskList/useTaskList.tsx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/frontend-security b/frontend/frontend-security index dc5dc992..b7c008c7 160000 --- a/frontend/frontend-security +++ b/frontend/frontend-security @@ -1 +1 @@ -Subproject commit dc5dc992222c55f2eb0dce9d618885ed928bc022 +Subproject commit b7c008c73445d0106d8786199b5f183283b59859 diff --git a/frontend/src/pages/user/TaskList/useTaskList.tsx b/frontend/src/pages/user/TaskList/useTaskList.tsx index ebd4c69b..18dec950 100644 --- a/frontend/src/pages/user/TaskList/useTaskList.tsx +++ b/frontend/src/pages/user/TaskList/useTaskList.tsx @@ -86,6 +86,8 @@ const useTaskList = () => { useEffect(() => { stomp.current = Stomp.client(`${process.env.REACT_APP_WS_URL}/ws-connect`); + stomp.current.reconnect_delay = 1000; + stomp.current.connect({}, () => { stomp.current.subscribe(`/topic/jobs/${jobId}`, (data: any) => { setSectionsData(JSON.parse(data.body)); From 91c56d177ef9b4db4126d38c729c43be4e009ed9 Mon Sep 17 00:00:00 2001 From: Seungchan On <62434898+cks3066@users.noreply.github.com> Date: Thu, 20 Oct 2022 21:03:13 +0900 Subject: [PATCH 04/11] =?UTF-8?q?[FE]=20=EC=9B=B9=EC=86=8C=EC=BC=93=20?= =?UTF-8?q?=EC=BB=A4=EB=84=A5=EC=85=98=20=EB=81=8A=EA=B2=BC=EC=9D=84=20?= =?UTF-8?q?=EC=83=81=ED=99=A9=EC=97=90=20=EC=9D=B4=EC=A0=84=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.=20(#640)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 장시간 이용없는 소켓 종료 --- .../src/pages/user/TaskList/useTaskList.tsx | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/frontend/src/pages/user/TaskList/useTaskList.tsx b/frontend/src/pages/user/TaskList/useTaskList.tsx index 18dec950..84c91de0 100644 --- a/frontend/src/pages/user/TaskList/useTaskList.tsx +++ b/frontend/src/pages/user/TaskList/useTaskList.tsx @@ -2,7 +2,7 @@ import { Stomp } from '@stomp/stompjs'; import { useEffect, useState } from 'react'; import { useRef } from 'react'; import { useQuery } from 'react-query'; -import { useLocation, useParams } from 'react-router-dom'; +import { useLocation, useNavigate, useParams } from 'react-router-dom'; import DetailInfoModal from '@/components/user/DetailInfoModal'; import NameModal from '@/components/user/NameModal'; @@ -18,6 +18,8 @@ import { ID, SectionType } from '@/types'; import { ApiTaskData } from '@/types/apis'; const useTaskList = () => { + const navigate = useNavigate(); + const { spaceId, jobId } = useParams() as { spaceId: ID; jobId: ID }; const location = useLocation(); @@ -86,22 +88,27 @@ const useTaskList = () => { useEffect(() => { stomp.current = Stomp.client(`${process.env.REACT_APP_WS_URL}/ws-connect`); - stomp.current.reconnect_delay = 1000; - - stomp.current.connect({}, () => { - stomp.current.subscribe(`/topic/jobs/${jobId}`, (data: any) => { - setSectionsData(JSON.parse(data.body)); - }); - - stomp.current.subscribe(`/topic/jobs/${jobId}/complete`, (data: any) => { - closeModal(); - goPreviousPage(); - - isSubmitted.current - ? openToast('SUCCESS', '체크리스트를 제출하였습니다.') - : openToast('ERROR', '해당 체크리스트를 다른 사용자가 제출하였습니다.'); - }); - }); + stomp.current.connect( + {}, + () => { + stomp.current.subscribe(`/topic/jobs/${jobId}`, (data: any) => { + setSectionsData(JSON.parse(data.body)); + }); + + stomp.current.subscribe(`/topic/jobs/${jobId}/complete`, (data: any) => { + closeModal(); + goPreviousPage(); + + isSubmitted.current + ? openToast('SUCCESS', '체크리스트를 제출하였습니다.') + : openToast('ERROR', '해당 체크리스트를 다른 사용자가 제출하였습니다.'); + }); + }, + () => { + openToast('ERROR', '장시간 이용이 없어, 이전 페이지로 이동하였습니다.'); + navigate(-1); + } + ); return () => { stomp.current.disconnect(); From bc420185d4be35ab132bc10136bee778411ad82e Mon Sep 17 00:00:00 2001 From: intae92 <56149367+intae92@users.noreply.github.com> Date: Thu, 20 Oct 2022 21:36:51 +0900 Subject: [PATCH 05/11] =?UTF-8?q?[FE]=20=EC=BB=A4=EB=B0=8B=20=EC=B6=A9?= =?UTF-8?q?=EB=8F=8C=20=ED=95=B4=EA=B2=B0=20(#642)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit release v1.3.1 (#638) * [FE] 제출 컴포넌트 UI 수정한다. (#632) [FE] 제출 컴포넌트 UI 수정 * [FE] 타입스크립트 옵션을 프로젝트에 맞게 수정한다. (#635) * feat: tsconfig 옵션 변경 * feat: 누락된 옵션 추가 * [FE] 작동이 없어서 웹소켓 연결이 종료되었을때, 재연결을 할 수 있도록 한다. (#637) feat: reconnect_delay를 1초로 설정한다. Co-authored-by: Seungchan On <62434898+cks3066@users.noreply.github.com> From e49e82bccebb3787abac28c4e29e7c285e4dea2d Mon Sep 17 00:00:00 2001 From: Seungchan On <62434898+cks3066@users.noreply.github.com> Date: Thu, 20 Oct 2022 22:12:42 +0900 Subject: [PATCH 06/11] =?UTF-8?q?[FE]=20=EC=9B=B9=EC=86=8C=EC=BC=93=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=EB=81=8A=EA=B9=80=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=EB=A5=BC=20=ED=95=B4=EA=B2=B0=ED=95=9C=EB=8B=A4.=20(#643)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 웹소켓 연결끊김 문제 해결 --- .../src/pages/user/TaskList/useTaskList.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/user/TaskList/useTaskList.tsx b/frontend/src/pages/user/TaskList/useTaskList.tsx index 84c91de0..efd323f7 100644 --- a/frontend/src/pages/user/TaskList/useTaskList.tsx +++ b/frontend/src/pages/user/TaskList/useTaskList.tsx @@ -85,9 +85,14 @@ const useTaskList = () => { stomp.current.send(`/app/jobs/${jobId}/sections/checkAll`, {}, JSON.stringify({ sectionId })); }; - useEffect(() => { + const connectSocket = () => { stomp.current = Stomp.client(`${process.env.REACT_APP_WS_URL}/ws-connect`); + stomp.current.reconnect_delay = 1000; + stomp.current.heartbeat.outgoing = 600000; + stomp.current.heartbeat.incoming = 600000; + stomp.current.debug = () => {}; + stomp.current.connect( {}, () => { @@ -105,10 +110,20 @@ const useTaskList = () => { }); }, () => { - openToast('ERROR', '장시간 이용이 없어, 이전 페이지로 이동하였습니다.'); + openToast('ERROR', '연결에 문제가 있습니다.'); navigate(-1); } ); + }; + + useEffect(() => { + connectSocket(); + + stomp.current.onDisconnect = () => { + alert('이전 페이지로 이동하기'); + openToast('ERROR', '장시간 이용이 없어, 이전 페이지로 이동합니다.'); + navigate(-1); + }; return () => { stomp.current.disconnect(); From d9c178f737112879c0113aacb89546e1802ce288 Mon Sep 17 00:00:00 2001 From: Seungchan On <62434898+cks3066@users.noreply.github.com> Date: Fri, 21 Oct 2022 02:06:17 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[FE]=20=EB=92=A4=EB=A1=9C=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EB=B2=84=ED=8A=BC=EC=9C=BC=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EC=A0=84=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=ED=95=98=EC=98=80=EC=9D=84=EB=95=8C,=20=EB=82=98?= =?UTF-8?q?=EC=98=A4=EB=8A=94=20=EC=97=90=EB=9F=AC=EB=A9=94=EC=8B=9C?= =?UTF-8?q?=EC=A7=80=EB=A5=BC=20=EC=A0=9C=EA=B1=B0=ED=95=9C=EB=8B=A4.=20?= =?UTF-8?q?=20(#645)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 웹소켓 연결끊김 문제 해결 * fix: 예기치 못한 disconnect 발생 시 에러 메시지 수정 * feat: useSocket 분리 및 heartbeat 0으로 설정 --- frontend/src/hooks/useSocket.ts | 50 ++++++++++ frontend/src/pages/user/TaskList/index.tsx | 5 +- .../src/pages/user/TaskList/useTaskList.tsx | 91 +++++++++---------- 3 files changed, 93 insertions(+), 53 deletions(-) create mode 100644 frontend/src/hooks/useSocket.ts diff --git a/frontend/src/hooks/useSocket.ts b/frontend/src/hooks/useSocket.ts new file mode 100644 index 00000000..629b29f1 --- /dev/null +++ b/frontend/src/hooks/useSocket.ts @@ -0,0 +1,50 @@ +import { Stomp } from '@stomp/stompjs'; +import { useRef } from 'react'; + +const useSocket = (url: string) => { + const stomp = useRef(null); + const isConnected = useRef(false); + + const checkIsConnect = () => { + return isConnected.current; + }; + const connectSocket = (callbackConnect: () => void, callbackError: () => void, callbackDisconnect: () => void) => { + stomp.current = Stomp.client(url); + isConnected.current = true; + + stomp.current.reconnect_delay = 1000; + stomp.current.heartbeat.outgoing = 0; + stomp.current.heartbeat.incoming = 0; + + if (process.env.NODE_ENV !== 'development') { + stomp.current.debug = () => {}; + } + + stomp.current.connect({}, callbackConnect, callbackError, callbackDisconnect); + }; + + const disconnectSocket = () => { + if (isConnected.current) { + isConnected.current = false; + stomp.current.disconnect(); + } + }; + + const subscribeTopic = (endPoint: string, callback: (data?: unknown) => void) => { + stomp.current.subscribe(endPoint, callback); + }; + + const sendMessage = (endPoint: string, data: unknown) => { + stomp.current.send(endPoint, {}, JSON.stringify(data)); + }; + + return { + checkIsConnect, + connectSocket, + disconnectSocket, + subscribeTopic, + sendMessage, + }; +}; + +export default useSocket; diff --git a/frontend/src/pages/user/TaskList/index.tsx b/frontend/src/pages/user/TaskList/index.tsx index 794d9f56..0295023f 100644 --- a/frontend/src/pages/user/TaskList/index.tsx +++ b/frontend/src/pages/user/TaskList/index.tsx @@ -1,6 +1,5 @@ import useTaskList from './useTaskList'; import { IoIosArrowBack } from '@react-icons/all-files/io/IoIosArrowBack'; -import React from 'react'; import Button from '@/components/common/Button'; import Sticky from '@/components/common/Sticky'; @@ -14,7 +13,7 @@ const TaskList: React.FC = () => { const { spaceData, onSubmit, - goPreviousPage, + onClickGoPreviousPage, totalCount, checkedCount, percent, @@ -31,7 +30,7 @@ const TaskList: React.FC = () => {
- +
diff --git a/frontend/src/pages/user/TaskList/useTaskList.tsx b/frontend/src/pages/user/TaskList/useTaskList.tsx index efd323f7..47764aef 100644 --- a/frontend/src/pages/user/TaskList/useTaskList.tsx +++ b/frontend/src/pages/user/TaskList/useTaskList.tsx @@ -1,8 +1,7 @@ -import { Stomp } from '@stomp/stompjs'; import { useEffect, useState } from 'react'; import { useRef } from 'react'; import { useQuery } from 'react-query'; -import { useLocation, useNavigate, useParams } from 'react-router-dom'; +import { useLocation, useParams } from 'react-router-dom'; import DetailInfoModal from '@/components/user/DetailInfoModal'; import NameModal from '@/components/user/NameModal'; @@ -10,6 +9,7 @@ import NameModal from '@/components/user/NameModal'; import useGoPreviousPage from '@/hooks/useGoPreviousPage'; import useModal from '@/hooks/useModal'; import useSectionCheck from '@/hooks/useSectionCheck'; +import useSocket from '@/hooks/useSocket'; import useToast from '@/hooks/useToast'; import apis from '@/apis'; @@ -18,13 +18,17 @@ import { ID, SectionType } from '@/types'; import { ApiTaskData } from '@/types/apis'; const useTaskList = () => { - const navigate = useNavigate(); + const isSubmitted = useRef(false); const { spaceId, jobId } = useParams() as { spaceId: ID; jobId: ID }; const location = useLocation(); const locationState = location.state as { jobName: string }; + const { connectSocket, disconnectSocket, subscribeTopic, sendMessage } = useSocket( + `${process.env.REACT_APP_WS_URL}/ws-connect` + ); + const { openModal, closeModal } = useModal(); const { openToast } = useToast(); @@ -49,9 +53,6 @@ const useTaskList = () => { sectionsData?.sections || [] ); - const stomp = useRef(null); - const isSubmitted = useRef(false); - const onSubmit = (e: React.FormEvent) => { e.preventDefault(); openModal( @@ -69,64 +70,54 @@ const useTaskList = () => { openModal(); }; + const onClickGoPreviousPage = () => { + disconnectSocket(); + goPreviousPage(); + }; + const completeJobs = (author: string) => { - if (!stomp.current) return; isSubmitted.current = true; - stomp.current.send(`/app/jobs/${jobId}/complete`, {}, JSON.stringify({ author })); + sendMessage(`/app/jobs/${jobId}/complete`, { author }); }; const flipTaskCheck = (taskId: ID) => { - if (!stomp.current) return; - stomp.current.send(`/app/jobs/${jobId}/tasks/flip`, {}, JSON.stringify({ taskId })); + sendMessage(`/app/jobs/${jobId}/tasks/flip`, { taskId }); }; const onClickSectionAllCheck = (sectionId: ID) => { - if (!stomp.current) return; - stomp.current.send(`/app/jobs/${jobId}/sections/checkAll`, {}, JSON.stringify({ sectionId })); + sendMessage(`/app/jobs/${jobId}/sections/checkAll`, { sectionId }); }; - const connectSocket = () => { - stomp.current = Stomp.client(`${process.env.REACT_APP_WS_URL}/ws-connect`); - - stomp.current.reconnect_delay = 1000; - stomp.current.heartbeat.outgoing = 600000; - stomp.current.heartbeat.incoming = 600000; - stomp.current.debug = () => {}; - - stomp.current.connect( - {}, - () => { - stomp.current.subscribe(`/topic/jobs/${jobId}`, (data: any) => { - setSectionsData(JSON.parse(data.body)); - }); - - stomp.current.subscribe(`/topic/jobs/${jobId}/complete`, (data: any) => { - closeModal(); - goPreviousPage(); - - isSubmitted.current - ? openToast('SUCCESS', '체크리스트를 제출하였습니다.') - : openToast('ERROR', '해당 체크리스트를 다른 사용자가 제출하였습니다.'); - }); - }, - () => { - openToast('ERROR', '연결에 문제가 있습니다.'); - navigate(-1); - } - ); + const onConnectSocket = () => { + subscribeTopic(`/topic/jobs/${jobId}`, (data: any) => { + setSectionsData(JSON.parse(data.body)); + }); + + subscribeTopic(`/topic/jobs/${jobId}/complete`, () => { + closeModal(); + goPreviousPage(); + + isSubmitted.current + ? openToast('SUCCESS', '체크리스트를 제출하였습니다.') + : openToast('ERROR', '해당 체크리스트를 다른 사용자가 제출하였습니다.'); + }); }; - useEffect(() => { - connectSocket(); + const onErrorSocket = () => { + openToast('ERROR', '연결에 문제가 있습니다.'); + disconnectSocket(); + goPreviousPage(); + }; - stomp.current.onDisconnect = () => { - alert('이전 페이지로 이동하기'); - openToast('ERROR', '장시간 이용이 없어, 이전 페이지로 이동합니다.'); - navigate(-1); - }; + const onDisconnectSocket = () => { + goPreviousPage(); + }; + + useEffect(() => { + connectSocket(onConnectSocket, onErrorSocket, onDisconnectSocket); return () => { - stomp.current.disconnect(); + disconnectSocket(); }; }, []); @@ -137,7 +128,7 @@ const useTaskList = () => { return { spaceData, onSubmit, - goPreviousPage, + onClickGoPreviousPage, totalCount, checkedCount, percent, From dda6dea7a4b4b2e68c1f8995f0f51dad8e8509d4 Mon Sep 17 00:00:00 2001 From: Seungchan On <62434898+cks3066@users.noreply.github.com> Date: Fri, 21 Oct 2022 02:34:56 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[FE]=20=EC=9E=91=EB=8F=99=EC=9D=B4=20?= =?UTF-8?q?=EC=97=86=EC=96=B4=20=EC=9D=B4=EC=A0=84=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=96=88=EC=9D=84?= =?UTF-8?q?=EB=95=8C=20=EB=A9=94=EC=8B=9C=EC=A7=80=EB=A5=BC=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A4=80=EB=8B=A4.=20(#647)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 작동이 없어 이전 페이지로 이동했을때 메시지를 보여준다. --- frontend/src/hooks/useSocket.ts | 5 +++-- frontend/src/pages/user/TaskList/useTaskList.tsx | 9 +++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/frontend/src/hooks/useSocket.ts b/frontend/src/hooks/useSocket.ts index 629b29f1..e8e09bad 100644 --- a/frontend/src/hooks/useSocket.ts +++ b/frontend/src/hooks/useSocket.ts @@ -5,9 +5,10 @@ const useSocket = (url: string) => { const stomp = useRef(null); const isConnected = useRef(false); - const checkIsConnect = () => { + const checkIsConnected = () => { return isConnected.current; }; + const connectSocket = (callbackConnect: () => void, callbackError: () => void, callbackDisconnect: () => void) => { stomp.current = Stomp.client(url); isConnected.current = true; @@ -39,7 +40,7 @@ const useSocket = (url: string) => { }; return { - checkIsConnect, + checkIsConnected, connectSocket, disconnectSocket, subscribeTopic, diff --git a/frontend/src/pages/user/TaskList/useTaskList.tsx b/frontend/src/pages/user/TaskList/useTaskList.tsx index 47764aef..4cc553df 100644 --- a/frontend/src/pages/user/TaskList/useTaskList.tsx +++ b/frontend/src/pages/user/TaskList/useTaskList.tsx @@ -25,7 +25,7 @@ const useTaskList = () => { const location = useLocation(); const locationState = location.state as { jobName: string }; - const { connectSocket, disconnectSocket, subscribeTopic, sendMessage } = useSocket( + const { checkIsConnected, connectSocket, disconnectSocket, subscribeTopic, sendMessage } = useSocket( `${process.env.REACT_APP_WS_URL}/ws-connect` ); @@ -110,7 +110,12 @@ const useTaskList = () => { }; const onDisconnectSocket = () => { - goPreviousPage(); + const isConnected = checkIsConnected(); + + if (isConnected) { + openToast('ERROR', '장시간 동작이 없어 이전 페이지로 이동합니다.'); + goPreviousPage(); + } }; useEffect(() => { From 73c9778de8c527894e7694ca91197ec4818ad0df Mon Sep 17 00:00:00 2001 From: intae92 <56149367+intae92@users.noreply.github.com> Date: Fri, 21 Oct 2022 11:01:16 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[FE]=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=EC=97=90=EC=84=9C=20=EB=8A=A6=EA=B2=8C=20?= =?UTF-8?q?=EB=B0=9B=EC=95=84=EC=98=A4=EB=8A=94=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=EB=A5=BC=20=EA=B3=84=EC=86=8D=20=ED=98=B8=EC=B6=9C=20?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20LazyImage=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9D=84=20=EA=B0=9C=EC=84=A0=ED=95=B4=EC=95=BC=20?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.=20(#649)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor: LazyImage onLoad, onError 처리 --- .../src/components/common/LazyImage/index.tsx | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/common/LazyImage/index.tsx b/frontend/src/components/common/LazyImage/index.tsx index bfc19ad6..a469a675 100644 --- a/frontend/src/components/common/LazyImage/index.tsx +++ b/frontend/src/components/common/LazyImage/index.tsx @@ -7,16 +7,41 @@ interface LazyImageProps extends React.ImgHTMLAttributes { const LazyImage: React.FC = ({ imageUrl, ...props }) => { const lazyImageRef = useRef(null); const observerRef = useRef(); + const timeId = useRef>(); const intersectionCallBack = (entries: IntersectionObserverEntry[], io: IntersectionObserver) => { entries.forEach(entry => { if (!entry.isIntersecting) return; entry.target.setAttribute('src', imageUrl || ''); + io.unobserve(entry.target); }); }; + const onLoad = () => { + if (timeId.current) { + clearTimeout(timeId.current); + } + }; + + const onError = () => { + if (timeId.current) { + clearTimeout(timeId.current); + } + + if (!imageUrl) return; + + const newTimeId = setTimeout(() => { + if (lazyImageRef.current) { + lazyImageRef.current.src = imageUrl; + clearTimeout(timeId.current); + } + }, 3000); + + timeId.current = newTimeId; + }; + useEffect(() => { if (!observerRef.current) { observerRef.current = new IntersectionObserver(intersectionCallBack); @@ -24,10 +49,13 @@ const LazyImage: React.FC = ({ imageUrl, ...props }) => { lazyImageRef.current && observerRef.current.observe(lazyImageRef.current); - return () => observerRef.current && observerRef.current.disconnect(); + return () => { + observerRef.current && observerRef.current.disconnect(); + clearTimeout(timeId.current); + }; }, []); - return ; + return ; }; export default LazyImage; From 3a434a3d8d2cbedf7c564e6dfa10b99fccfb26e1 Mon Sep 17 00:00:00 2001 From: intae92 <56149367+intae92@users.noreply.github.com> Date: Fri, 21 Oct 2022 11:01:32 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[FE]=20=EC=B2=B4=ED=81=AC=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=EB=B3=B4=EA=B8=B0=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=EC=B0=BD,=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=8A=A4=EC=BC=88=EB=A0=88=ED=86=A4=20UI=EB=A5=BC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=ED=95=B4=EC=95=BC=ED=95=9C=EB=8B=A4.=20(#651)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 스켈레톤UI 적용 --- .../components/user/DetailInfoModal/index.tsx | 15 +++++++-- .../components/user/DetailInfoModal/styles.ts | 31 ++++++++++++++++++- frontend/src/styles/theme.ts | 1 + 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/user/DetailInfoModal/index.tsx b/frontend/src/components/user/DetailInfoModal/index.tsx index 49577dfc..988625b9 100644 --- a/frontend/src/components/user/DetailInfoModal/index.tsx +++ b/frontend/src/components/user/DetailInfoModal/index.tsx @@ -1,6 +1,6 @@ -import Dimmer from '@/components/common/Dimmer'; +import { useState } from 'react'; -import homeCover_fallback from '@/assets/homeCover-fallback.png'; +import Dimmer from '@/components/common/Dimmer'; import ModalPortal from '@/portals/ModalPortal'; @@ -13,12 +13,21 @@ export interface DetailInfoModalProps { } const DetailInfoModal: React.FC = ({ name, imageUrl, description }) => { + const [isLoadImg, setIsLoadImg] = useState(true); + + const onLoad = () => { + setIsLoadImg(false); + }; + return (

{name}

-
{imageUrl !== '' && }
+
+ {imageUrl !== '' && isLoadImg &&
} + {imageUrl !== '' && } +
{description}
diff --git a/frontend/src/components/user/DetailInfoModal/styles.ts b/frontend/src/components/user/DetailInfoModal/styles.ts index e0269ef8..48274572 100644 --- a/frontend/src/components/user/DetailInfoModal/styles.ts +++ b/frontend/src/components/user/DetailInfoModal/styles.ts @@ -35,10 +35,39 @@ const image = css` object-fit: cover; `; +const skeletonImage = css` + ${image} + + background-color: ${theme.colors.gray200}; + position: relative; + border: none; + overflow: hidden; + + @keyframes loading { + 0% { + transform: translateX(0); + } + 100% { + transform: translateX(600px); + } + } + + &:before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 140px; + height: 100%; + background: linear-gradient(to right, ${theme.colors.gray200}, ${theme.colors.gray330}, ${theme.colors.gray200}); + animation: loading 1.4s infinite linear; + } +`; + const description = css` margin: 16px 0; `; -const styles = { container, title, description, imageWrapper, image }; +const styles = { container, title, description, imageWrapper, image, skeletonImage }; export default styles; diff --git a/frontend/src/styles/theme.ts b/frontend/src/styles/theme.ts index 396e981b..d326f28f 100644 --- a/frontend/src/styles/theme.ts +++ b/frontend/src/styles/theme.ts @@ -12,6 +12,7 @@ const theme = Object.freeze({ gray100: '#f9fbfd', gray200: '#f5f5f5', gray300: '#d9d9d9', + gray330: '#EDE4E0', gray350: '#f5f6fa', gray400: '#d1ccc0', gray500: '#84817a', From dd9baccdd105336c56d3c0ddd1916f067146b492 Mon Sep 17 00:00:00 2001 From: Seungchan On <62434898+cks3066@users.noreply.github.com> Date: Fri, 21 Oct 2022 11:41:57 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[FE]=20=EC=B2=B4=ED=81=AC=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20padding-bott?= =?UTF-8?q?om=EC=9D=84=20=EB=8A=98=EB=A6=B0=EB=8B=A4.=20(#653)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 체크리스트 페이지 padding-bottom을 늘린다. --- frontend/src/pages/user/TaskList/styles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/user/TaskList/styles.ts b/frontend/src/pages/user/TaskList/styles.ts index df6acb1f..df881b8d 100644 --- a/frontend/src/pages/user/TaskList/styles.ts +++ b/frontend/src/pages/user/TaskList/styles.ts @@ -8,7 +8,7 @@ const layout = css` width: 100%; align-items: center; font-size: 16px; - padding-bottom: 32px; + padding-bottom: 5em; `; const contents = css`