From 5df2417f3ba47b8aa664ca73d094499026471510 Mon Sep 17 00:00:00 2001 From: suhwa Date: Mon, 8 Aug 2022 15:29:19 +0900 Subject: [PATCH 01/20] =?UTF-8?q?feat:=20=EC=95=8C=EB=9E=8C=20=EC=BB=A8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=84=88=20UI=20=EA=B5=AC=ED=98=84,=20?= =?UTF-8?q?=EC=95=8C=EB=9E=8C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20thunk?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=88=EB=9F=AC=EC=98=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/store/ducks/alarm/alarmSlice.ts | 26 ++++++++ src/app/store/ducks/alarm/alarmThunk.d.ts | 21 ++++++ src/app/store/ducks/alarm/alarmThunk.ts | 24 +++++++ src/app/store/store.ts | 2 + src/components/Common/Header/NavItems.tsx | 41 ++++++++++-- src/components/Common/Header/alarm/index.tsx | 68 ++++++++++++++++++++ src/hooks/useOutsideClick.ts | 1 + 7 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 src/app/store/ducks/alarm/alarmSlice.ts create mode 100644 src/app/store/ducks/alarm/alarmThunk.d.ts create mode 100644 src/app/store/ducks/alarm/alarmThunk.ts create mode 100644 src/components/Common/Header/alarm/index.tsx diff --git a/src/app/store/ducks/alarm/alarmSlice.ts b/src/app/store/ducks/alarm/alarmSlice.ts new file mode 100644 index 00000000..1bda5b11 --- /dev/null +++ b/src/app/store/ducks/alarm/alarmSlice.ts @@ -0,0 +1,26 @@ +import { AlarmItem } from "./alarmThunk.d"; +import { createSlice } from "@reduxjs/toolkit"; +import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; +export interface AlarmStateProps { + alarmList: AlarmItem[] | null; +} + +const initialState: AlarmStateProps = { + alarmList: null, +}; + +const alarmSlice = createSlice({ + name: " alarm", + initialState, + reducers: {}, + extraReducers: (build) => { + build // + .addCase(loadAlarmList.fulfilled, (state, action) => { + state.alarmList = action.payload; + }); + }, +}); + +export const alarmAction = alarmSlice.actions; + +export const alarmReducer = alarmSlice.reducer; diff --git a/src/app/store/ducks/alarm/alarmThunk.d.ts b/src/app/store/ducks/alarm/alarmThunk.d.ts new file mode 100644 index 00000000..f77cc203 --- /dev/null +++ b/src/app/store/ducks/alarm/alarmThunk.d.ts @@ -0,0 +1,21 @@ +export interface AlarmItem { + id: number; + type: string; + message: string; + agent: { + id: number; + username: string; + name: string; + image: { + imageUrl: string; + imageType: string; + imageName: string; + imageUUID: string; + }; + hasStory: false; + }; + createdDate: string; + postId: number; + postImageUrl: string; + content: string; +} diff --git a/src/app/store/ducks/alarm/alarmThunk.ts b/src/app/store/ducks/alarm/alarmThunk.ts new file mode 100644 index 00000000..10182675 --- /dev/null +++ b/src/app/store/ducks/alarm/alarmThunk.ts @@ -0,0 +1,24 @@ +import { authorizedCustomAxios } from "customAxios"; +import { AlarmItem } from "./alarmThunk.d"; +import { createAsyncThunk } from "@reduxjs/toolkit"; + +export const loadAlarmList = createAsyncThunk( + "alarm/loadList", + async (payload, ThunkOptions) => { + try { + const config = { + params: { + page: 1, + size: 10, + }, + }; + const { + data: { data }, + } = await authorizedCustomAxios.get(`/alarms`, config); + + return data.content; + } catch (error) { + ThunkOptions.rejectWithValue(error); + } + }, +); diff --git a/src/app/store/store.ts b/src/app/store/store.ts index 1362fd4d..64a67297 100644 --- a/src/app/store/store.ts +++ b/src/app/store/store.ts @@ -1,3 +1,4 @@ +import { alarmReducer } from "./ducks/alarm/alarmSlice"; import { configureStore } from "@reduxjs/toolkit"; import { authReducer } from "app/store/ducks/auth/authSlice"; import { homeReducer } from "app/store/ducks/home/homeSlice"; @@ -18,6 +19,7 @@ export const store = configureStore({ profile: profileReducer, edit: editReducer, common: commonReducer, + alarm: alarmReducer, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ diff --git a/src/components/Common/Header/NavItems.tsx b/src/components/Common/Header/NavItems.tsx index 6ae7cb72..41b509bd 100644 --- a/src/components/Common/Header/NavItems.tsx +++ b/src/components/Common/Header/NavItems.tsx @@ -20,8 +20,10 @@ import { selectView } from "app/store/ducks/direct/DirectSlice"; import { uploadActions } from "app/store/ducks/upload/uploadSlice"; import Upload from "components/Common/Header/Upload"; import SubNav from "./SubNav"; + import { useRef, useState } from "react"; import useOutsideClick from "hooks/useOutsideClick"; +import Alarm from "components/Common/Header/alarm"; const Container = styled.div` flex: 1 0 0%; @@ -71,14 +73,26 @@ const AvatarWrapper = styled(NavItemWrapper)<{ isSubnavModalOn: boolean }>` const NavItems = () => { const [isSubnavModalOn, setIsSubnavMoalOn] = useState(false); + const [isClickAlarm, setIsClickAlarm] = useState(false); + const dispatch = useAppDispatch(); const isUploading = useAppSelector(({ upload }) => upload.isUploading); const userInfo = useAppSelector((state) => state.auth.userInfo); + // setting const navContainerRef = useRef(null); - const subModalControllerRef = useRef(null); + const subModalControllerRef = useRef(null); useOutsideClick(navContainerRef, setIsSubnavMoalOn, subModalControllerRef); + // alarm + const alarmContainerRef = useRef(null); + const alarmModalControllerRef = useRef(null); + useOutsideClick( + alarmContainerRef, + setIsClickAlarm, + alarmModalControllerRef, + ); + const navItems = [ { id: "홈", @@ -127,8 +141,21 @@ const NavItems = () => { { id: "피드 활동", path: "/", - component: , - activeComponent: , + component: ( + + setIsClickAlarm(!isClickAlarm)} /> + + ), + activeComponent: ( + + setIsClickAlarm(!isClickAlarm)} + /> + {isClickAlarm && ( + + )} + + ), }, ]; @@ -144,6 +171,12 @@ const NavItems = () => { ? navItem.activeComponent : navItem.component} + ) : navItem.id === "피드 활동" ? ( + <> + {isClickAlarm + ? navItem.activeComponent + : navItem.component} + ) : ( {navItem.component} @@ -154,7 +187,6 @@ const NavItems = () => {
{ setIsSubnavMoalOn(!isSubnavModalOn); }} @@ -166,6 +198,7 @@ const NavItems = () => { data-testid="user-avatar" draggable="false" src={userInfo?.memberImageUrl} + ref={subModalControllerRef} />
{isSubnavModalOn && ( diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx new file mode 100644 index 00000000..7f0eaf73 --- /dev/null +++ b/src/components/Common/Header/alarm/index.tsx @@ -0,0 +1,68 @@ +import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; +import { useAppDispatch, useAppSelector } from "app/store/Hooks"; +import React, { useEffect } from "react"; +import styled from "styled-components"; + +const Container = styled.div` + position: relative; + height: 1px; + + .pointer { + background-color: #fff; + border: 1px solid #fff; + height: 14px; + transform: rotate(45deg); + box-shadow: rgba(0, 0, 0, 0.098) 0px 0px 5px 1px; + width: 14px; + position: relative; + top: 5px; + left: 5px; + } + + .alarm-container { + display: flex; + flex-direction: column; + width: 485px; + z-index: 200; + position: absolute; + right: -26px; + top: 8px; + background-color: #fff; + box-shadow: rgba(0, 0, 0, 0.098) 0px 0px 5px 1px; + border-radius: 6px; + + .title { + font-weight: 700; + padding: 4px; + display: flex; + justify-content: flex-start; + margin: 8px 0 0 8px; + } + } +`; + +export default function Alarm({ + alarmContainerRef, +}: { + alarmContainerRef: React.RefObject; +}) { + // alarm list 가져오기 <- api 호출 + const dispatch = useAppDispatch(); + const { alarmList } = useAppSelector((state) => state.alarm); + + useEffect(() => { + dispatch(loadAlarmList()); + }, []); + + return ( + +
+
+
+
이전 활동
+
+
+
+ + ); +} diff --git a/src/hooks/useOutsideClick.ts b/src/hooks/useOutsideClick.ts index a93b6298..db42cde2 100644 --- a/src/hooks/useOutsideClick.ts +++ b/src/hooks/useOutsideClick.ts @@ -8,6 +8,7 @@ const useOutsideClick = ( useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (trigger?.current.contains(event.target as Node)) { + // 정리: 클릭버튼을 클릭 시, 여기서 모달이 닫히도록 처리되지만, 컴포넌트에서도 클릭이벤트가 일어나(!false), 모달 안꺼짐 // event 발생시킨 요소가 trigger에 속한다면, 외부에 클릭한 거로 여기지 않음 // 즉, event는 외부클릭 | trigger 클릭으로 나눌 수 있음 // 여기서는 event 외부클릭을 처리하고, From 8303eb7ccd525f9346b5201cee627552bbdbeb25 Mon Sep 17 00:00:00 2001 From: suhwa Date: Mon, 8 Aug 2022 17:20:35 +0900 Subject: [PATCH 02/20] =?UTF-8?q?fix:=20alarm=20list=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=20=ED=83=80=EC=9E=85,=20index.d.ts=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@type/index.d.ts | 24 +++++++++++++++++++++++ src/app/store/ducks/alarm/alarmSlice.ts | 3 +-- src/app/store/ducks/alarm/alarmThunk.d.ts | 21 -------------------- src/app/store/ducks/alarm/alarmThunk.ts | 3 +-- 4 files changed, 26 insertions(+), 25 deletions(-) delete mode 100644 src/app/store/ducks/alarm/alarmThunk.d.ts diff --git a/src/@type/index.d.ts b/src/@type/index.d.ts index 75110411..e1f35960 100644 --- a/src/@type/index.d.ts +++ b/src/@type/index.d.ts @@ -445,3 +445,27 @@ declare module EditType { type modalType = "image" | "gender" | null; } + +declare module Alarm { + interface AlarmItem { + id: number; + type: "COMMENT" | "LIKE_POST" | "MENTION_POST"; + message: string; + agent: { + id: number; + username: string; + name: string; + image: { + imageUrl: string; + imageType: string; + imageName: string; + imageUUID: string; + }; + hasStory: false; + }; + createdDate: string; + postId: number; + postImageUrl: string; + content: string; + } +} diff --git a/src/app/store/ducks/alarm/alarmSlice.ts b/src/app/store/ducks/alarm/alarmSlice.ts index 1bda5b11..b31287a3 100644 --- a/src/app/store/ducks/alarm/alarmSlice.ts +++ b/src/app/store/ducks/alarm/alarmSlice.ts @@ -1,8 +1,7 @@ -import { AlarmItem } from "./alarmThunk.d"; import { createSlice } from "@reduxjs/toolkit"; import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; export interface AlarmStateProps { - alarmList: AlarmItem[] | null; + alarmList: Alarm.AlarmItem[] | null; } const initialState: AlarmStateProps = { diff --git a/src/app/store/ducks/alarm/alarmThunk.d.ts b/src/app/store/ducks/alarm/alarmThunk.d.ts deleted file mode 100644 index f77cc203..00000000 --- a/src/app/store/ducks/alarm/alarmThunk.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export interface AlarmItem { - id: number; - type: string; - message: string; - agent: { - id: number; - username: string; - name: string; - image: { - imageUrl: string; - imageType: string; - imageName: string; - imageUUID: string; - }; - hasStory: false; - }; - createdDate: string; - postId: number; - postImageUrl: string; - content: string; -} diff --git a/src/app/store/ducks/alarm/alarmThunk.ts b/src/app/store/ducks/alarm/alarmThunk.ts index 10182675..864a5bb0 100644 --- a/src/app/store/ducks/alarm/alarmThunk.ts +++ b/src/app/store/ducks/alarm/alarmThunk.ts @@ -1,8 +1,7 @@ import { authorizedCustomAxios } from "customAxios"; -import { AlarmItem } from "./alarmThunk.d"; import { createAsyncThunk } from "@reduxjs/toolkit"; -export const loadAlarmList = createAsyncThunk( +export const loadAlarmList = createAsyncThunk( "alarm/loadList", async (payload, ThunkOptions) => { try { From b771cf5e0d4c04f563a36b9f1d856baff3529f12 Mon Sep 17 00:00:00 2001 From: suhwa Date: Mon, 8 Aug 2022 17:21:35 +0900 Subject: [PATCH 03/20] =?UTF-8?q?feat:=20=EC=95=8C=EB=9E=8C=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=ED=85=9C=20>=20=EC=95=8C=EB=9E=8C=EB=B3=B4=EB=82=B8?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=ED=95=84=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/Header/alarm/alarm_profile.tsx | 26 +++++++++++++ .../Header/alarm/alarm_type/comment.tsx | 5 +++ .../Common/Header/alarm/alarm_type/like.tsx | 5 +++ .../Header/alarm/alarm_type/mention.tsx | 5 +++ src/components/Common/Header/alarm/index.tsx | 38 ++++++++++++++++++- 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/components/Common/Header/alarm/alarm_profile.tsx create mode 100644 src/components/Common/Header/alarm/alarm_type/comment.tsx create mode 100644 src/components/Common/Header/alarm/alarm_type/like.tsx create mode 100644 src/components/Common/Header/alarm/alarm_type/mention.tsx diff --git a/src/components/Common/Header/alarm/alarm_profile.tsx b/src/components/Common/Header/alarm/alarm_profile.tsx new file mode 100644 index 00000000..5539527c --- /dev/null +++ b/src/components/Common/Header/alarm/alarm_profile.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import styled from "styled-components"; + +const Container = styled.div` + img { + height: 44px; + width: 44px; + border-radius: 50%; + } +`; + +export default function AlarmProfile({ + agent, +}: Pick) { + return ( + + + {`${agent.username}님의 + + + ); +} diff --git a/src/components/Common/Header/alarm/alarm_type/comment.tsx b/src/components/Common/Header/alarm/alarm_type/comment.tsx new file mode 100644 index 00000000..a831dd9a --- /dev/null +++ b/src/components/Common/Header/alarm/alarm_type/comment.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export default function Comment({ alarm }: { alarm: Alarm.AlarmItem }) { + return
Comment
; +} diff --git a/src/components/Common/Header/alarm/alarm_type/like.tsx b/src/components/Common/Header/alarm/alarm_type/like.tsx new file mode 100644 index 00000000..ee77d192 --- /dev/null +++ b/src/components/Common/Header/alarm/alarm_type/like.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export default function Like({ alarm }: { alarm: Alarm.AlarmItem }) { + return
Like
; +} diff --git a/src/components/Common/Header/alarm/alarm_type/mention.tsx b/src/components/Common/Header/alarm/alarm_type/mention.tsx new file mode 100644 index 00000000..f7fb2491 --- /dev/null +++ b/src/components/Common/Header/alarm/alarm_type/mention.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export default function Mention({ alarm }: { alarm: Alarm.AlarmItem }) { + return
mention
; +} diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx index 7f0eaf73..75a9b0f9 100644 --- a/src/components/Common/Header/alarm/index.tsx +++ b/src/components/Common/Header/alarm/index.tsx @@ -1,5 +1,9 @@ import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; import { useAppDispatch, useAppSelector } from "app/store/Hooks"; +import AlarmProfile from "components/Common/Header/alarm/alarm_profile"; +import Comment from "components/Common/Header/alarm/alarm_type/comment"; +import Like from "components/Common/Header/alarm/alarm_type/like"; +import Mention from "components/Common/Header/alarm/alarm_type/mention"; import React, { useEffect } from "react"; import styled from "styled-components"; @@ -30,6 +34,8 @@ const Container = styled.div` background-color: #fff; box-shadow: rgba(0, 0, 0, 0.098) 0px 0px 5px 1px; border-radius: 6px; + max-height: 440px; + overflow: auto; .title { font-weight: 700; @@ -38,6 +44,13 @@ const Container = styled.div` justify-content: flex-start; margin: 8px 0 0 8px; } + + .alarm-list { + .alarm-item { + display: flex; + padding: 12px 16px; + } + } } `; @@ -54,6 +67,12 @@ export default function Alarm({ dispatch(loadAlarmList()); }, []); + // const matchComponentAtAlarmType = { + // COMMENT: , + // LIKE_POST: , + // MENTION_POST: , + // }; + return (
@@ -61,7 +80,24 @@ export default function Alarm({
이전 활동
-
+
+ {alarmList + ? alarmList.map((alarm) => { + return ( +
+ + {alarm.type === "COMMENT" ? ( + + ) : alarm.type === "LIKE_POST" ? ( + + ) : ( + + )} +
+ ); + }) + : `알람이 없습니다.`} +
); From d653f62f81bf36b5d500f35403c3a0f8e2f3d355 Mon Sep 17 00:00:00 2001 From: suhwa Date: Wed, 10 Aug 2022 14:51:31 +0900 Subject: [PATCH 04/20] =?UTF-8?q?feat:=20=EC=95=8C=EB=A6=BC=20item=20?= =?UTF-8?q?=ED=95=98=EB=82=98=EB=A1=9C=20=ED=86=B5=EC=9D=BC,=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=EC=B2=98=EB=A6=AC,=20=EC=95=8C=EB=9E=8C=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/Header/alarm/alarm_item.tsx | 66 +++++++++++++++++++ .../Header/alarm/alarm_type/comment.tsx | 5 -- .../Common/Header/alarm/alarm_type/like.tsx | 5 -- .../Header/alarm/alarm_type/mention.tsx | 5 -- src/components/Common/Header/alarm/index.tsx | 50 +++++++------- 5 files changed, 89 insertions(+), 42 deletions(-) create mode 100644 src/components/Common/Header/alarm/alarm_item.tsx delete mode 100644 src/components/Common/Header/alarm/alarm_type/comment.tsx delete mode 100644 src/components/Common/Header/alarm/alarm_type/like.tsx delete mode 100644 src/components/Common/Header/alarm/alarm_type/mention.tsx diff --git a/src/components/Common/Header/alarm/alarm_item.tsx b/src/components/Common/Header/alarm/alarm_item.tsx new file mode 100644 index 00000000..bf5044c9 --- /dev/null +++ b/src/components/Common/Header/alarm/alarm_item.tsx @@ -0,0 +1,66 @@ +import React from "react"; +import styled from "styled-components"; +import AlarmProfile from "components/Common/Header/alarm/alarm_profile"; +import { Link } from "react-router-dom"; +import useGapText from "hooks/useGapText"; + +const Container = styled.div` + display: flex; + + .alarm { + margin: 0 12px; + + a { + text-decoration: none; + + .username { + font-weight: 700; + } + } + + .create-date { + color: ${(props) => props.theme.font.gray}; + } + } + + .relative-image { + display: flex; + flex-direction: column; + justify-content: center; + + img { + height: 40px; + } + } +`; + +const removeRefer = (message: string) => { + return message.replace(/\{[a-z.]+\}/g, ""); +}; + +export default function AlarmItem({ alarm }: { alarm: Alarm.AlarmItem }) { + const alarmMessage = removeRefer(alarm.message); + // content -> @username, #search -> 파란색으로 스타일링..! -> 검색가능해야하는데..? -> #search 프로필페이지 만들어야함 + + // 무한스크롤 + // 컴포넌트 언마운트 -> alarm창 닫도록 + + return ( + + +
+ + {alarm.agent.username} + + {alarmMessage} + {alarm.content}{" "} + + {useGapText(alarm.createdDate)} + +
+
+ {"이미지 +
+
+ ); +} diff --git a/src/components/Common/Header/alarm/alarm_type/comment.tsx b/src/components/Common/Header/alarm/alarm_type/comment.tsx deleted file mode 100644 index a831dd9a..00000000 --- a/src/components/Common/Header/alarm/alarm_type/comment.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import React from "react"; - -export default function Comment({ alarm }: { alarm: Alarm.AlarmItem }) { - return
Comment
; -} diff --git a/src/components/Common/Header/alarm/alarm_type/like.tsx b/src/components/Common/Header/alarm/alarm_type/like.tsx deleted file mode 100644 index ee77d192..00000000 --- a/src/components/Common/Header/alarm/alarm_type/like.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import React from "react"; - -export default function Like({ alarm }: { alarm: Alarm.AlarmItem }) { - return
Like
; -} diff --git a/src/components/Common/Header/alarm/alarm_type/mention.tsx b/src/components/Common/Header/alarm/alarm_type/mention.tsx deleted file mode 100644 index f7fb2491..00000000 --- a/src/components/Common/Header/alarm/alarm_type/mention.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import React from "react"; - -export default function Mention({ alarm }: { alarm: Alarm.AlarmItem }) { - return
mention
; -} diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx index 75a9b0f9..d3285ca0 100644 --- a/src/components/Common/Header/alarm/index.tsx +++ b/src/components/Common/Header/alarm/index.tsx @@ -1,9 +1,7 @@ import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; import { useAppDispatch, useAppSelector } from "app/store/Hooks"; -import AlarmProfile from "components/Common/Header/alarm/alarm_profile"; -import Comment from "components/Common/Header/alarm/alarm_type/comment"; -import Like from "components/Common/Header/alarm/alarm_type/like"; -import Mention from "components/Common/Header/alarm/alarm_type/mention"; +import AlarmItem from "components/Common/Header/alarm/alarm_item"; +import Loading from "components/Common/Loading"; import React, { useEffect } from "react"; import styled from "styled-components"; @@ -35,6 +33,7 @@ const Container = styled.div` box-shadow: rgba(0, 0, 0, 0.098) 0px 0px 5px 1px; border-radius: 6px; max-height: 440px; + min-height: 200px; overflow: auto; .title { @@ -50,6 +49,13 @@ const Container = styled.div` display: flex; padding: 12px 16px; } + + .empty-container { + display: flex; + justify-content: center; + margin: 50px; + font-size: 20px; + } } } `; @@ -59,7 +65,6 @@ export default function Alarm({ }: { alarmContainerRef: React.RefObject; }) { - // alarm list 가져오기 <- api 호출 const dispatch = useAppDispatch(); const { alarmList } = useAppSelector((state) => state.alarm); @@ -67,12 +72,6 @@ export default function Alarm({ dispatch(loadAlarmList()); }, []); - // const matchComponentAtAlarmType = { - // COMMENT: , - // LIKE_POST: , - // MENTION_POST: , - // }; - return (
@@ -81,22 +80,19 @@ export default function Alarm({
이전 활동
- {alarmList - ? alarmList.map((alarm) => { - return ( -
- - {alarm.type === "COMMENT" ? ( - - ) : alarm.type === "LIKE_POST" ? ( - - ) : ( - - )} -
- ); - }) - : `알람이 없습니다.`} + {!alarmList ? ( + + ) : alarmList.length === 0 ? ( +
알람이 없습니다.
+ ) : ( + alarmList.map((alarm) => { + return ( +
+ +
+ ); + }) + )}
From 7b650e7e902ac4acee95f1652d638ffba1c95437 Mon Sep 17 00:00:00 2001 From: suhwa Date: Wed, 10 Aug 2022 14:56:43 +0900 Subject: [PATCH 05/20] =?UTF-8?q?feat:=20=EC=95=8C=EB=9E=8C=20=EB=82=B4=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=8D=B8=EB=84=A4=EC=9D=BC=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=ED=95=B4=EB=8B=B9=20=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EA=B8=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Header/alarm/alarm_item.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Common/Header/alarm/alarm_item.tsx b/src/components/Common/Header/alarm/alarm_item.tsx index bf5044c9..f8fa3212 100644 --- a/src/components/Common/Header/alarm/alarm_item.tsx +++ b/src/components/Common/Header/alarm/alarm_item.tsx @@ -59,7 +59,9 @@ export default function AlarmItem({ alarm }: { alarm: Alarm.AlarmItem }) {
- {"이미지 + + {"이미지 +
); From d5682fea82954391ad62ab1d5c41073960f6acf6 Mon Sep 17 00:00:00 2001 From: suhwa Date: Wed, 10 Aug 2022 15:14:46 +0900 Subject: [PATCH 06/20] =?UTF-8?q?fix:=20=EC=95=8C=EB=9E=8C=20item=20UI=20?= =?UTF-8?q?=EC=9D=BC=EB=B6=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Header/alarm/alarm_item.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Common/Header/alarm/alarm_item.tsx b/src/components/Common/Header/alarm/alarm_item.tsx index f8fa3212..67e3fae5 100644 --- a/src/components/Common/Header/alarm/alarm_item.tsx +++ b/src/components/Common/Header/alarm/alarm_item.tsx @@ -6,9 +6,11 @@ import useGapText from "hooks/useGapText"; const Container = styled.div` display: flex; + flex: 1; .alarm { margin: 0 12px; + flex: 1; a { text-decoration: none; @@ -30,6 +32,7 @@ const Container = styled.div` img { height: 40px; + width: 40px; } } `; @@ -52,8 +55,7 @@ export default function AlarmItem({ alarm }: { alarm: Alarm.AlarmItem }) { {alarm.agent.username} - {alarmMessage} - {alarm.content}{" "} + {alarmMessage} {alarm.content}{" "} {useGapText(alarm.createdDate)} From deb3f1c4cc0e3c24941e0f0faa9af2919c794b41 Mon Sep 17 00:00:00 2001 From: suhwa Date: Thu, 11 Aug 2022 15:26:50 +0900 Subject: [PATCH 07/20] =?UTF-8?q?refactor:=20div=20=EB=8C=80=EC=8B=A0=20ul?= =?UTF-8?q?,li=20=ED=83=9C=EA=B7=B8=20=EC=9D=B4=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Header/alarm/index.tsx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx index d3285ca0..37779b03 100644 --- a/src/components/Common/Header/alarm/index.tsx +++ b/src/components/Common/Header/alarm/index.tsx @@ -79,21 +79,20 @@ export default function Alarm({
이전 활동
-
+
    {!alarmList ? ( ) : alarmList.length === 0 ? (
    알람이 없습니다.
    ) : ( - alarmList.map((alarm) => { - return ( -
    - -
    - ); - }) + alarmList.map((alarm) => ( +
  • + +
  • + )) )} -
+ + {/* 무한스크롤 footer */} ); From 766843e493d2815960c21020f7090407d99c0276 Mon Sep 17 00:00:00 2001 From: suhwa Date: Tue, 30 Aug 2022 22:42:11 +0900 Subject: [PATCH 08/20] =?UTF-8?q?feat:=20hashtag,=20mentions=20=EB=A7=81?= =?UTF-8?q?=ED=81=AC,=EC=8A=A4=ED=83=80=EC=9D=BC=EB=A7=81=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@type/index.d.ts | 25 ++++++++- .../alarm/{ => alarmType}/alarm_item.tsx | 17 ++++--- .../Header/alarm/alarmType/follow_alarm.tsx | 51 +++++++++++++++++++ src/components/Common/Header/alarm/index.tsx | 12 +++-- src/components/Common/Header/alarm/utils.ts | 3 ++ 5 files changed, 95 insertions(+), 13 deletions(-) rename src/components/Common/Header/alarm/{ => alarmType}/alarm_item.tsx (75%) create mode 100644 src/components/Common/Header/alarm/alarmType/follow_alarm.tsx create mode 100644 src/components/Common/Header/alarm/utils.ts diff --git a/src/@type/index.d.ts b/src/@type/index.d.ts index 89846db8..af6fbc7e 100644 --- a/src/@type/index.d.ts +++ b/src/@type/index.d.ts @@ -465,7 +465,8 @@ declare module EditType { } declare module Alarm { - interface AlarmItem { + type AlarmItem = CommonAlarm | FollowAlarm; + interface CommonAlarm { id: number; type: "COMMENT" | "LIKE_POST" | "MENTION_POST"; message: string; @@ -485,5 +486,27 @@ declare module Alarm { postId: number; postImageUrl: string; content: string; + mentionsOfContent: string[]; + hashtagsOfContent: string[]; + } + + interface FollowAlarm { + id: number; + type: "FOLLOW"; + message: string; + agent: { + id: number; + username: string; + name: string; + image: { + imageUrl: string; + imageType: string; + imageName: string; + imageUUID: string; + }; + hasStory: false; + }; + createdDate: string; + following: boolean; } } diff --git a/src/components/Common/Header/alarm/alarm_item.tsx b/src/components/Common/Header/alarm/alarmType/alarm_item.tsx similarity index 75% rename from src/components/Common/Header/alarm/alarm_item.tsx rename to src/components/Common/Header/alarm/alarmType/alarm_item.tsx index 67e3fae5..3d201bbf 100644 --- a/src/components/Common/Header/alarm/alarm_item.tsx +++ b/src/components/Common/Header/alarm/alarmType/alarm_item.tsx @@ -3,6 +3,8 @@ import styled from "styled-components"; import AlarmProfile from "components/Common/Header/alarm/alarm_profile"; import { Link } from "react-router-dom"; import useGapText from "hooks/useGapText"; +import { removeRefer } from "components/Common/Header/alarm/utils"; +import StringFragmentWithMentionOrHashtagLink from "components/Common/StringFragmentWithMentionOrHashtagLink"; const Container = styled.div` display: flex; @@ -37,14 +39,8 @@ const Container = styled.div` } `; -const removeRefer = (message: string) => { - return message.replace(/\{[a-z.]+\}/g, ""); -}; - -export default function AlarmItem({ alarm }: { alarm: Alarm.AlarmItem }) { +export default function AlarmItem({ alarm }: { alarm: Alarm.CommonAlarm }) { const alarmMessage = removeRefer(alarm.message); - // content -> @username, #search -> 파란색으로 스타일링..! -> 검색가능해야하는데..? -> #search 프로필페이지 만들어야함 - // 무한스크롤 // 컴포넌트 언마운트 -> alarm창 닫도록 @@ -55,7 +51,12 @@ export default function AlarmItem({ alarm }: { alarm: Alarm.AlarmItem }) { {alarm.agent.username} - {alarmMessage} {alarm.content}{" "} + {alarmMessage} + {" "} {useGapText(alarm.createdDate)} diff --git a/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx b/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx new file mode 100644 index 00000000..914fbe0d --- /dev/null +++ b/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx @@ -0,0 +1,51 @@ +import AlarmProfile from "components/Common/Header/alarm/alarm_profile"; +import { removeRefer } from "components/Common/Header/alarm/utils"; +import FollowingModal from "components/Home/Modals/FollowingModal"; +import useGapText from "hooks/useGapText"; +import { Link } from "react-router-dom"; +import styled from "styled-components"; + +const Container = styled.div` + display: flex; + flex: 1; + + .alarm { + margin: 0 12px; + flex: 1; + + a { + text-decoration: none; + + .username { + font-weight: 700; + } + } + + .create-date { + color: ${(props) => props.theme.font.gray}; + } + } +`; + +export default function FollowAlarm({ alarm }: { alarm: Alarm.FollowAlarm }) { + const alarmMessage = removeRefer(alarm.message); + + return ( + + +
+ + {alarm.agent.username} + + {alarmMessage}{" "} + + {useGapText(alarm.createdDate)} + +
+ {/* } */} + {/* */} +
+ ); +} diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx index 37779b03..bcf50d46 100644 --- a/src/components/Common/Header/alarm/index.tsx +++ b/src/components/Common/Header/alarm/index.tsx @@ -1,6 +1,7 @@ import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; import { useAppDispatch, useAppSelector } from "app/store/Hooks"; -import AlarmItem from "components/Common/Header/alarm/alarm_item"; +import AlarmItem from "components/Common/Header/alarm/alarmType/alarm_item"; +import FollowAlarm from "components/Common/Header/alarm/alarmType/follow_alarm"; import Loading from "components/Common/Loading"; import React, { useEffect } from "react"; import styled from "styled-components"; @@ -86,13 +87,16 @@ export default function Alarm({
알람이 없습니다.
) : ( alarmList.map((alarm) => ( -
  • - +
  • + {alarm.type === "FOLLOW" ? ( + + ) : ( + + )}
  • )) )} - {/* 무한스크롤 footer */} ); diff --git a/src/components/Common/Header/alarm/utils.ts b/src/components/Common/Header/alarm/utils.ts new file mode 100644 index 00000000..e3a87170 --- /dev/null +++ b/src/components/Common/Header/alarm/utils.ts @@ -0,0 +1,3 @@ +export const removeRefer = (message: string) => { + return message.replace(/\{[a-z.]+\}/g, ""); +}; From 5e067ed2229635ae9eab35248e2f88068294f3e9 Mon Sep 17 00:00:00 2001 From: suhwa Date: Tue, 13 Sep 2022 11:20:19 +0900 Subject: [PATCH 09/20] =?UTF-8?q?fix:=20useOnView=20=EC=88=98=EC=A0=95:=20?= =?UTF-8?q?parameter,=20useEffect=20deps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit useEffect deps: ref -> ref.current로 수정 ref.current가 변경되었음에도 ref는 동일하기에 useEffect가 실행되지 않는 케이스가 있어 수정함 --- src/hooks/useOnView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useOnView.ts b/src/hooks/useOnView.ts index e85aef92..bda5d69e 100644 --- a/src/hooks/useOnView.ts +++ b/src/hooks/useOnView.ts @@ -1,6 +1,6 @@ import { RefObject, useEffect, useMemo, useState } from "react"; -const useOnView = (ref: RefObject | null) => { +const useOnView = (ref: RefObject) => { const [isIntersecting, setIntersecting] = useState(false); const observer = useMemo( @@ -19,7 +19,7 @@ const useOnView = (ref: RefObject | null) => { return () => { observer.disconnect(); }; - }, [observer, ref]); + }, [observer, ref.current]); return isIntersecting; }; From 9b72f221ba4de986036c43b05bd879979e2922eb Mon Sep 17 00:00:00 2001 From: suhwa Date: Tue, 13 Sep 2022 11:21:53 +0900 Subject: [PATCH 10/20] =?UTF-8?q?fix:=20Alarm=20=EB=AC=B4=ED=95=9C?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=EC=9D=84=20=EC=9C=84=ED=95=B4=20Ala?= =?UTF-8?q?rm=20type=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@type/index.d.ts | 8 +++++++- src/components/Common/Header/alarm/alarm_profile.tsx | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/@type/index.d.ts b/src/@type/index.d.ts index af6fbc7e..4c6b842c 100644 --- a/src/@type/index.d.ts +++ b/src/@type/index.d.ts @@ -465,7 +465,13 @@ declare module EditType { } declare module Alarm { - type AlarmItem = CommonAlarm | FollowAlarm; + type AlarmItem = { + content: AlarmContent[]; + totalPages: number; + currentPage: number; + }; + + type AlarmContent = CommonAlarm | FollowAlarm; interface CommonAlarm { id: number; type: "COMMENT" | "LIKE_POST" | "MENTION_POST"; diff --git a/src/components/Common/Header/alarm/alarm_profile.tsx b/src/components/Common/Header/alarm/alarm_profile.tsx index 5539527c..2f5c33e2 100644 --- a/src/components/Common/Header/alarm/alarm_profile.tsx +++ b/src/components/Common/Header/alarm/alarm_profile.tsx @@ -12,7 +12,7 @@ const Container = styled.div` export default function AlarmProfile({ agent, -}: Pick) { +}: Pick) { return ( From f28db0c55e6c756a60f4803db3867af83517e3b2 Mon Sep 17 00:00:00 2001 From: suhwa Date: Tue, 13 Sep 2022 11:22:50 +0900 Subject: [PATCH 11/20] =?UTF-8?q?feat:=20Alarm=20=EB=AC=B4=ED=95=9C?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EA=B5=AC=ED=98=84=20-=20alarm=20?= =?UTF-8?q?list=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C?= =?UTF-8?q?=20observing=20=EB=B6=99=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/store/ducks/alarm/alarmSlice.ts | 18 +++++- src/app/store/ducks/alarm/alarmThunk.ts | 39 ++++++------- .../Common/Header/alarm/alarm_list.tsx | 49 ++++++++++++++++ src/components/Common/Header/alarm/index.tsx | 57 ++++++++++--------- 4 files changed, 113 insertions(+), 50 deletions(-) create mode 100644 src/components/Common/Header/alarm/alarm_list.tsx diff --git a/src/app/store/ducks/alarm/alarmSlice.ts b/src/app/store/ducks/alarm/alarmSlice.ts index b31287a3..59ede416 100644 --- a/src/app/store/ducks/alarm/alarmSlice.ts +++ b/src/app/store/ducks/alarm/alarmSlice.ts @@ -1,21 +1,33 @@ import { createSlice } from "@reduxjs/toolkit"; import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; + export interface AlarmStateProps { - alarmList: Alarm.AlarmItem[] | null; + alarmList: Alarm.AlarmContent[] | null; + totalPage: number; } const initialState: AlarmStateProps = { alarmList: null, + totalPage: 0, }; const alarmSlice = createSlice({ name: " alarm", initialState, - reducers: {}, + reducers: { + clearAlarmList: (state) => { + state.alarmList = null; + }, + }, extraReducers: (build) => { build // .addCase(loadAlarmList.fulfilled, (state, action) => { - state.alarmList = action.payload; + if (action.payload.currentPage === 1) { + state.alarmList = action.payload.content; + state.totalPage = action.payload.totalPages; + } else { + state.alarmList?.push(...action.payload.content); + } }); }, }); diff --git a/src/app/store/ducks/alarm/alarmThunk.ts b/src/app/store/ducks/alarm/alarmThunk.ts index 864a5bb0..25544d62 100644 --- a/src/app/store/ducks/alarm/alarmThunk.ts +++ b/src/app/store/ducks/alarm/alarmThunk.ts @@ -1,23 +1,24 @@ import { authorizedCustomAxios } from "customAxios"; import { createAsyncThunk } from "@reduxjs/toolkit"; -export const loadAlarmList = createAsyncThunk( - "alarm/loadList", - async (payload, ThunkOptions) => { - try { - const config = { - params: { - page: 1, - size: 10, - }, - }; - const { - data: { data }, - } = await authorizedCustomAxios.get(`/alarms`, config); +export const loadAlarmList = createAsyncThunk< + Alarm.AlarmItem, + { page: number } +>("alarm/loadList", async (payload, ThunkOptions) => { + try { + const config = { + params: { + page: payload.page, + size: 10, + }, + }; + const { + data: { data }, + } = await authorizedCustomAxios.get(`/alarms`, config); - return data.content; - } catch (error) { - ThunkOptions.rejectWithValue(error); - } - }, -); + console.log(data); + return { ...data, currentPage: payload.page }; + } catch (error) { + ThunkOptions.rejectWithValue(error); + } +}); diff --git a/src/components/Common/Header/alarm/alarm_list.tsx b/src/components/Common/Header/alarm/alarm_list.tsx new file mode 100644 index 00000000..2272f6a4 --- /dev/null +++ b/src/components/Common/Header/alarm/alarm_list.tsx @@ -0,0 +1,49 @@ +import AlarmItem from "components/Common/Header/alarm/alarmType/alarm_item"; +import FollowAlarm from "components/Common/Header/alarm/alarmType/follow_alarm"; +import useOnView from "hooks/useOnView"; +import { useEffect, useRef } from "react"; +import styled from "styled-components"; + +const Container = styled.ul` + display: flex; + flex-direction: column; + + .alarm-item { + padding: 12px 16px; + } +`; + +export default function AlarmList({ + alarmList, + onLoadExtraAlarm, +}: { + alarmList: Alarm.AlarmContent[]; + onLoadExtraAlarm: () => void; +}) { + const lastAlarmItemRef = useRef(null); + const isVisible = useOnView(lastAlarmItemRef); + + useEffect(() => { + isVisible && onLoadExtraAlarm(); + }, [isVisible]); + + return ( + + {alarmList.map((alarm, index) => ( +
  • + {alarm.type === "FOLLOW" ? ( + + ) : ( + + )} +
  • + ))} +
    + ); +} diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx index bcf50d46..eb70510a 100644 --- a/src/components/Common/Header/alarm/index.tsx +++ b/src/components/Common/Header/alarm/index.tsx @@ -1,9 +1,9 @@ +import { alarmAction } from "app/store/ducks/alarm/alarmSlice"; import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; import { useAppDispatch, useAppSelector } from "app/store/Hooks"; -import AlarmItem from "components/Common/Header/alarm/alarmType/alarm_item"; -import FollowAlarm from "components/Common/Header/alarm/alarmType/follow_alarm"; +import AlarmList from "components/Common/Header/alarm/alarm_list"; import Loading from "components/Common/Loading"; -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import styled from "styled-components"; const Container = styled.div` @@ -45,18 +45,11 @@ const Container = styled.div` margin: 8px 0 0 8px; } - .alarm-list { - .alarm-item { - display: flex; - padding: 12px 16px; - } - - .empty-container { - display: flex; - justify-content: center; - margin: 50px; - font-size: 20px; - } + .empty-container { + display: flex; + justify-content: center; + margin: 50px; + font-size: 20px; } } `; @@ -67,12 +60,25 @@ export default function Alarm({ alarmContainerRef: React.RefObject; }) { const dispatch = useAppDispatch(); - const { alarmList } = useAppSelector((state) => state.alarm); + const [pageToLoad, setPageToLoad] = useState(1); + const { alarmList, totalPage } = useAppSelector((state) => state.alarm); useEffect(() => { - dispatch(loadAlarmList()); + dispatch(loadAlarmList({ page: pageToLoad })); + setPageToLoad(pageToLoad + 1); + + return () => { + dispatch(alarmAction.clearAlarmList()); + }; }, []); + const loadExtraAlarmList = () => { + if (pageToLoad <= totalPage) { + dispatch(loadAlarmList({ page: pageToLoad })); + setPageToLoad(pageToLoad + 1); + } + }; + return (
    @@ -80,23 +86,18 @@ export default function Alarm({
    이전 활동
    -
      +
      {!alarmList ? ( ) : alarmList.length === 0 ? (
      알람이 없습니다.
      ) : ( - alarmList.map((alarm) => ( -
    • - {alarm.type === "FOLLOW" ? ( - - ) : ( - - )} -
    • - )) + )} -
    +
    ); From c390cffdacf86260cf9b2a047c0ac21c0d1077b1 Mon Sep 17 00:00:00 2001 From: suhwa Date: Tue, 13 Sep 2022 11:25:59 +0900 Subject: [PATCH 12/20] =?UTF-8?q?fix:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20log=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/store/ducks/alarm/alarmThunk.ts | 2 -- src/customAxios.ts | 1 - 2 files changed, 3 deletions(-) diff --git a/src/app/store/ducks/alarm/alarmThunk.ts b/src/app/store/ducks/alarm/alarmThunk.ts index 25544d62..75457d8f 100644 --- a/src/app/store/ducks/alarm/alarmThunk.ts +++ b/src/app/store/ducks/alarm/alarmThunk.ts @@ -15,8 +15,6 @@ export const loadAlarmList = createAsyncThunk< const { data: { data }, } = await authorizedCustomAxios.get(`/alarms`, config); - - console.log(data); return { ...data, currentPage: payload.page }; } catch (error) { ThunkOptions.rejectWithValue(error); diff --git a/src/customAxios.ts b/src/customAxios.ts index 8cfb0be8..68c8bf0b 100644 --- a/src/customAxios.ts +++ b/src/customAxios.ts @@ -17,7 +17,6 @@ export const checkToken = async (config: AxiosRequestConfig) => { authorizedCustomAxios.defaults.headers.common.Authorization.split( " ", )[1]; - console.log(accessToken); const decode = jwt.decode(accessToken); const nowDate = new Date().getTime() / 1000; if (decode.exp < nowDate) { From 020fd9489663535d3790cf70536cb2b311c59c92 Mon Sep 17 00:00:00 2001 From: suhwa Date: Mon, 3 Oct 2022 15:01:14 +0900 Subject: [PATCH 13/20] =?UTF-8?q?feat:=20=EC=95=8C=EB=9E=8C>=ED=8C=94?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0,=20=ED=8C=94=EB=A1=9C=EC=9E=89=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20UI,=20=EB=AA=A8=EB=8B=AC=20=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=9F=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@type/index.d.ts | 1 + src/app/store/ducks/modal/modalSlice.ts | 7 +++ .../Header/alarm/alarmType/follow_alarm.tsx | 51 ++++++++++++++++--- src/pages/Home/Home.tsx | 12 +++++ 4 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/@type/index.d.ts b/src/@type/index.d.ts index 1a794ca9..394ba939 100644 --- a/src/@type/index.d.ts +++ b/src/@type/index.d.ts @@ -200,6 +200,7 @@ declare module ModalType { | "report" | "articleMenu" | "shareWith" + | "alarmUnfollowing" | null; interface ModalPositionProps { diff --git a/src/app/store/ducks/modal/modalSlice.ts b/src/app/store/ducks/modal/modalSlice.ts index c1c00d34..06915152 100644 --- a/src/app/store/ducks/modal/modalSlice.ts +++ b/src/app/store/ducks/modal/modalSlice.ts @@ -16,6 +16,13 @@ const modalSlice = createSlice({ name: "modal", initialState, reducers: { + setModalUsernameAndImageUrl: ( + state, + action: PayloadAction<{ nickname: string; imageUrl: string }>, + ) => { + state.memberNickname = action.payload.nickname; + state.memberImageUrl = action.payload.imageUrl; + }, startModal: ( state, action: PayloadAction, diff --git a/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx b/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx index 914fbe0d..379c09a7 100644 --- a/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx +++ b/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx @@ -1,9 +1,13 @@ +import { postFollow } from "app/store/ducks/home/homThunk"; +import { modalActions } from "app/store/ducks/modal/modalSlice"; +import { useAppDispatch } from "app/store/Hooks"; import AlarmProfile from "components/Common/Header/alarm/alarm_profile"; import { removeRefer } from "components/Common/Header/alarm/utils"; -import FollowingModal from "components/Home/Modals/FollowingModal"; import useGapText from "hooks/useGapText"; +import { useState } from "react"; import { Link } from "react-router-dom"; -import styled from "styled-components"; +import styled, { useTheme } from "styled-components"; +import Button from "styles/UI/Button"; const Container = styled.div` display: flex; @@ -29,6 +33,28 @@ const Container = styled.div` export default function FollowAlarm({ alarm }: { alarm: Alarm.FollowAlarm }) { const alarmMessage = removeRefer(alarm.message); + const dispatch = useAppDispatch(); + const theme = useTheme(); + const [isFollowing, setIsFollowing] = useState(alarm.following); + + const followHandler = () => { + dispatch(postFollow({ username: alarm.agent.username })) // + .then(() => { + setIsFollowing(!isFollowing); + }); + }; + + const showUnfollowingModalOnHandler = () => { + // 모달에 들어갈 유저 정보 세팅 + dispatch( + modalActions.setModalUsernameAndImageUrl({ + nickname: alarm.agent.username, + imageUrl: alarm.agent.image.imageUrl, + }), + ); + // 모달 켜기 + dispatch(modalActions.changeActivatedModal("alarmUnfollowing")); + }; return ( @@ -42,10 +68,23 @@ export default function FollowAlarm({ alarm }: { alarm: Alarm.FollowAlarm }) { {useGapText(alarm.createdDate)} - {/* } */} - {/* */} + {isFollowing ? ( + + ) : ( + + )} ); } diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index be9e3524..0376c000 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -108,6 +108,18 @@ const Home = () => { onModalOff={() => dispatch(modalActions.resetModal())} /> )} + {activatedModal === "alarmUnfollowing" && ( + + dispatch( + modalActions.maintainModalon("alarmUnfollowing"), + ) + } + onModalOff={() => dispatch(modalActions.resetModal())} + /> + )} ); }; From 73790af8ef5f75f9af1d14b7265d8069fe6bf1ed Mon Sep 17 00:00:00 2001 From: suhwa Date: Mon, 3 Oct 2022 15:22:57 +0900 Subject: [PATCH 14/20] =?UTF-8?q?fix:=20alarm=20type=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=ED=83=80=EC=9E=85=20=EB=AC=B6=EC=96=B4?= =?UTF-8?q?=EC=84=9C=20=ED=99=95=EC=9E=A5=ED=95=98=EB=8A=94=20=EB=B0=A9?= =?UTF-8?q?=ED=96=A5=EC=9C=BC=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 --- src/@type/index.d.ts | 30 +++++-------------- .../Header/alarm/alarmType/alarm_item.tsx | 2 +- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/@type/index.d.ts b/src/@type/index.d.ts index 394ba939..1845abf7 100644 --- a/src/@type/index.d.ts +++ b/src/@type/index.d.ts @@ -469,7 +469,8 @@ declare module Alarm { currentPage: number; }; - type AlarmContent = CommonAlarm | FollowAlarm; + type AlarmContent = PostAlarm | FollowAlarm; + interface CommonAlarm { id: number; type: "COMMENT" | "LIKE_POST" | "MENTION_POST"; @@ -478,15 +479,13 @@ declare module Alarm { id: number; username: string; name: string; - image: { - imageUrl: string; - imageType: string; - imageName: string; - imageUUID: string; - }; + image: CommonType.ImageInfo; hasStory: false; }; createdDate: string; + } + interface PostAlarm extends CommonAlarm { + type: "COMMENT" | "LIKE_POST" | "MENTION_POST"; postId: number; postImageUrl: string; content: string; @@ -494,23 +493,8 @@ declare module Alarm { hashtagsOfContent: string[]; } - interface FollowAlarm { - id: number; + interface FollowAlarm extends CommonAlarm { type: "FOLLOW"; - message: string; - agent: { - id: number; - username: string; - name: string; - image: { - imageUrl: string; - imageType: string; - imageName: string; - imageUUID: string; - }; - hasStory: false; - }; - createdDate: string; following: boolean; } } diff --git a/src/components/Common/Header/alarm/alarmType/alarm_item.tsx b/src/components/Common/Header/alarm/alarmType/alarm_item.tsx index 3d201bbf..8e7bdca1 100644 --- a/src/components/Common/Header/alarm/alarmType/alarm_item.tsx +++ b/src/components/Common/Header/alarm/alarmType/alarm_item.tsx @@ -39,7 +39,7 @@ const Container = styled.div` } `; -export default function AlarmItem({ alarm }: { alarm: Alarm.CommonAlarm }) { +export default function AlarmItem({ alarm }: { alarm: Alarm.PostAlarm }) { const alarmMessage = removeRefer(alarm.message); // 무한스크롤 // 컴포넌트 언마운트 -> alarm창 닫도록 From ef9170087f84d2654213169ad03b50090f0bea41 Mon Sep 17 00:00:00 2001 From: suhwa Date: Mon, 3 Oct 2022 15:54:45 +0900 Subject: [PATCH 15/20] =?UTF-8?q?feat:=20=EC=95=8C=EB=9E=8C=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20UI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Header/alarm/index.tsx | 27 +++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx index eb70510a..d31e5cdd 100644 --- a/src/components/Common/Header/alarm/index.tsx +++ b/src/components/Common/Header/alarm/index.tsx @@ -2,9 +2,11 @@ import { alarmAction } from "app/store/ducks/alarm/alarmSlice"; import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; import { useAppDispatch, useAppSelector } from "app/store/Hooks"; import AlarmList from "components/Common/Header/alarm/alarm_list"; +import ImageSprite from "components/Common/ImageSprite"; import Loading from "components/Common/Loading"; import React, { useEffect, useState } from "react"; import styled from "styled-components"; +import sprite from "assets/Images/sprite.png"; const Container = styled.div` position: relative; @@ -47,9 +49,14 @@ const Container = styled.div` .empty-container { display: flex; - justify-content: center; + flex-direction: column; + align-items: center; margin: 50px; - font-size: 20px; + font-size: 15px; + + span { + padding: 10px 0; + } } } `; @@ -79,6 +86,13 @@ export default function Alarm({ } }; + const emptyImage: CommonType.ImageProps = { + width: 96, + height: 96, + position: `0 -303px`, + url: sprite, + }; + return (
    @@ -90,7 +104,14 @@ export default function Alarm({ {!alarmList ? ( ) : alarmList.length === 0 ? ( -
    알람이 없습니다.
    +
    + + 게시물 활동 + + 다른 사람이 회원님이 게시물을 좋아하거나 댓글을 + 남기면 여기에 표시됩니다. + +
    ) : ( Date: Mon, 3 Oct 2022 17:49:13 +0900 Subject: [PATCH 16/20] =?UTF-8?q?fix:=20=EC=95=8C=EB=9E=8C=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=EC=83=81=ED=83=9C=EA=B0=92=20isClickAlarm=20->=20isAl?= =?UTF-8?q?armOn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Header/NavItems.tsx | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/components/Common/Header/NavItems.tsx b/src/components/Common/Header/NavItems.tsx index 41b509bd..4e419362 100644 --- a/src/components/Common/Header/NavItems.tsx +++ b/src/components/Common/Header/NavItems.tsx @@ -73,7 +73,7 @@ const AvatarWrapper = styled(NavItemWrapper)<{ isSubnavModalOn: boolean }>` const NavItems = () => { const [isSubnavModalOn, setIsSubnavMoalOn] = useState(false); - const [isClickAlarm, setIsClickAlarm] = useState(false); + const [isAlarmOn, setIsAlarmOn] = useState(false); const dispatch = useAppDispatch(); const isUploading = useAppSelector(({ upload }) => upload.isUploading); @@ -87,11 +87,7 @@ const NavItems = () => { // alarm const alarmContainerRef = useRef(null); const alarmModalControllerRef = useRef(null); - useOutsideClick( - alarmContainerRef, - setIsClickAlarm, - alarmModalControllerRef, - ); + useOutsideClick(alarmContainerRef, setIsAlarmOn, alarmModalControllerRef); const navItems = [ { @@ -143,15 +139,13 @@ const NavItems = () => { path: "/", component: ( - setIsClickAlarm(!isClickAlarm)} /> + setIsAlarmOn(!isAlarmOn)} /> ), activeComponent: ( - setIsClickAlarm(!isClickAlarm)} - /> - {isClickAlarm && ( + setIsAlarmOn(!isAlarmOn)} /> + {isAlarmOn && ( )} @@ -173,7 +167,7 @@ const NavItems = () => {
    ) : navItem.id === "피드 활동" ? ( <> - {isClickAlarm + {isAlarmOn ? navItem.activeComponent : navItem.component} From 0efa59ad046668823f28327de4122f340b8a4823 Mon Sep 17 00:00:00 2001 From: suhwa Date: Mon, 3 Oct 2022 17:50:32 +0900 Subject: [PATCH 17/20] =?UTF-8?q?fix:=20=EC=95=88=EC=93=B0=EB=8A=94=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20import=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Header/NavItems.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/Common/Header/NavItems.tsx b/src/components/Common/Header/NavItems.tsx index 4e419362..5e930489 100644 --- a/src/components/Common/Header/NavItems.tsx +++ b/src/components/Common/Header/NavItems.tsx @@ -8,13 +8,10 @@ import { ReactComponent as DirectActive } from "assets/Svgs/direct-active.svg"; import { ReactComponent as NewArticle } from "assets/Svgs/new-article.svg"; import { ReactComponent as NewArticleActive } from "assets/Svgs/new-article-active.svg"; -import { ReactComponent as Map } from "assets/Svgs/map.svg"; -import { ReactComponent as MapActive } from "assets/Svgs/map-active.svg"; - import { ReactComponent as Heart } from "assets/Svgs/heart.svg"; import { ReactComponent as HeartActive } from "assets/Svgs/heart-active.svg"; -import { NavLink, Link } from "react-router-dom"; +import { NavLink } from "react-router-dom"; import { useAppDispatch, useAppSelector } from "app/store/Hooks"; import { selectView } from "app/store/ducks/direct/DirectSlice"; import { uploadActions } from "app/store/ducks/upload/uploadSlice"; From d6e43f31132edda05e8be0f05cffc9d87db841c3 Mon Sep 17 00:00:00 2001 From: suhwa Date: Mon, 3 Oct 2022 22:26:54 +0900 Subject: [PATCH 18/20] =?UTF-8?q?fix:=20=EC=95=8C=EB=9E=8C=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20cursor=20pointer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Header/NavItems.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Common/Header/NavItems.tsx b/src/components/Common/Header/NavItems.tsx index 5e930489..3cf36fa6 100644 --- a/src/components/Common/Header/NavItems.tsx +++ b/src/components/Common/Header/NavItems.tsx @@ -163,11 +163,11 @@ const NavItems = () => { : navItem.component} ) : navItem.id === "피드 활동" ? ( - <> +
    {isAlarmOn ? navItem.activeComponent : navItem.component} - +
    ) : ( {navItem.component} From a62da1466ff7d38202165cc6c134cea441c9a02a Mon Sep 17 00:00:00 2001 From: suhwa Date: Wed, 28 Dec 2022 01:10:11 +0900 Subject: [PATCH 19/20] =?UTF-8?q?fix:=20=EA=B3=B5=ED=86=B5=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=A4=EC=85=98=EC=9C=BC=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 파일명, 타입모듈명, type -> interface --- src/@type/index.d.ts | 7 +++---- src/app/store/ducks/alarm/alarmSlice.ts | 2 +- src/app/store/ducks/alarm/alarmThunk.ts | 2 +- .../Header/alarm/{alarm_list.tsx => AlarmList.tsx} | 6 +++--- .../alarm/{alarm_profile.tsx => AlarmProfile.tsx} | 3 +-- .../alarmType/{alarm_item.tsx => AlarmItem.tsx} | 4 ++-- .../alarmType/{follow_alarm.tsx => FollowAlarm.tsx} | 12 ++++++++---- src/components/Common/Header/alarm/index.tsx | 2 +- 8 files changed, 20 insertions(+), 18 deletions(-) rename src/components/Common/Header/alarm/{alarm_list.tsx => AlarmList.tsx} (94%) rename src/components/Common/Header/alarm/{alarm_profile.tsx => AlarmProfile.tsx} (89%) rename src/components/Common/Header/alarm/alarmType/{alarm_item.tsx => AlarmItem.tsx} (92%) rename src/components/Common/Header/alarm/alarmType/{follow_alarm.tsx => FollowAlarm.tsx} (90%) diff --git a/src/@type/index.d.ts b/src/@type/index.d.ts index 1845abf7..95ce45ae 100644 --- a/src/@type/index.d.ts +++ b/src/@type/index.d.ts @@ -462,12 +462,12 @@ declare module EditType { type modalType = "image" | "gender" | null; } -declare module Alarm { - type AlarmItem = { +declare module AlarmType { + interface AlarmItem { content: AlarmContent[]; totalPages: number; currentPage: number; - }; + } type AlarmContent = PostAlarm | FollowAlarm; @@ -485,7 +485,6 @@ declare module Alarm { createdDate: string; } interface PostAlarm extends CommonAlarm { - type: "COMMENT" | "LIKE_POST" | "MENTION_POST"; postId: number; postImageUrl: string; content: string; diff --git a/src/app/store/ducks/alarm/alarmSlice.ts b/src/app/store/ducks/alarm/alarmSlice.ts index 59ede416..9b19289e 100644 --- a/src/app/store/ducks/alarm/alarmSlice.ts +++ b/src/app/store/ducks/alarm/alarmSlice.ts @@ -2,7 +2,7 @@ import { createSlice } from "@reduxjs/toolkit"; import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; export interface AlarmStateProps { - alarmList: Alarm.AlarmContent[] | null; + alarmList: AlarmType.AlarmContent[] | null; totalPage: number; } diff --git a/src/app/store/ducks/alarm/alarmThunk.ts b/src/app/store/ducks/alarm/alarmThunk.ts index 75457d8f..16526503 100644 --- a/src/app/store/ducks/alarm/alarmThunk.ts +++ b/src/app/store/ducks/alarm/alarmThunk.ts @@ -2,7 +2,7 @@ import { authorizedCustomAxios } from "customAxios"; import { createAsyncThunk } from "@reduxjs/toolkit"; export const loadAlarmList = createAsyncThunk< - Alarm.AlarmItem, + AlarmType.AlarmItem, { page: number } >("alarm/loadList", async (payload, ThunkOptions) => { try { diff --git a/src/components/Common/Header/alarm/alarm_list.tsx b/src/components/Common/Header/alarm/AlarmList.tsx similarity index 94% rename from src/components/Common/Header/alarm/alarm_list.tsx rename to src/components/Common/Header/alarm/AlarmList.tsx index 2272f6a4..36d5ac70 100644 --- a/src/components/Common/Header/alarm/alarm_list.tsx +++ b/src/components/Common/Header/alarm/AlarmList.tsx @@ -1,5 +1,5 @@ -import AlarmItem from "components/Common/Header/alarm/alarmType/alarm_item"; -import FollowAlarm from "components/Common/Header/alarm/alarmType/follow_alarm"; +import AlarmItem from "components/Common/Header/alarm/alarmType/AlarmItem"; +import FollowAlarm from "components/Common/Header/alarm/alarmType/FollowAlarm"; import useOnView from "hooks/useOnView"; import { useEffect, useRef } from "react"; import styled from "styled-components"; @@ -17,7 +17,7 @@ export default function AlarmList({ alarmList, onLoadExtraAlarm, }: { - alarmList: Alarm.AlarmContent[]; + alarmList: AlarmType.AlarmContent[]; onLoadExtraAlarm: () => void; }) { const lastAlarmItemRef = useRef(null); diff --git a/src/components/Common/Header/alarm/alarm_profile.tsx b/src/components/Common/Header/alarm/AlarmProfile.tsx similarity index 89% rename from src/components/Common/Header/alarm/alarm_profile.tsx rename to src/components/Common/Header/alarm/AlarmProfile.tsx index 2f5c33e2..8f2be0c8 100644 --- a/src/components/Common/Header/alarm/alarm_profile.tsx +++ b/src/components/Common/Header/alarm/AlarmProfile.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { Link } from "react-router-dom"; import styled from "styled-components"; @@ -12,7 +11,7 @@ const Container = styled.div` export default function AlarmProfile({ agent, -}: Pick) { +}: Pick) { return ( diff --git a/src/components/Common/Header/alarm/alarmType/alarm_item.tsx b/src/components/Common/Header/alarm/alarmType/AlarmItem.tsx similarity index 92% rename from src/components/Common/Header/alarm/alarmType/alarm_item.tsx rename to src/components/Common/Header/alarm/alarmType/AlarmItem.tsx index 8e7bdca1..5deeb6eb 100644 --- a/src/components/Common/Header/alarm/alarmType/alarm_item.tsx +++ b/src/components/Common/Header/alarm/alarmType/AlarmItem.tsx @@ -1,6 +1,6 @@ import React from "react"; import styled from "styled-components"; -import AlarmProfile from "components/Common/Header/alarm/alarm_profile"; +import AlarmProfile from "components/Common/Header/alarm/AlarmProfile"; import { Link } from "react-router-dom"; import useGapText from "hooks/useGapText"; import { removeRefer } from "components/Common/Header/alarm/utils"; @@ -39,7 +39,7 @@ const Container = styled.div` } `; -export default function AlarmItem({ alarm }: { alarm: Alarm.PostAlarm }) { +export default function AlarmItem({ alarm }: { alarm: AlarmType.PostAlarm }) { const alarmMessage = removeRefer(alarm.message); // 무한스크롤 // 컴포넌트 언마운트 -> alarm창 닫도록 diff --git a/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx b/src/components/Common/Header/alarm/alarmType/FollowAlarm.tsx similarity index 90% rename from src/components/Common/Header/alarm/alarmType/follow_alarm.tsx rename to src/components/Common/Header/alarm/alarmType/FollowAlarm.tsx index 379c09a7..4b32fd54 100644 --- a/src/components/Common/Header/alarm/alarmType/follow_alarm.tsx +++ b/src/components/Common/Header/alarm/alarmType/FollowAlarm.tsx @@ -1,7 +1,7 @@ import { postFollow } from "app/store/ducks/home/homThunk"; import { modalActions } from "app/store/ducks/modal/modalSlice"; import { useAppDispatch } from "app/store/Hooks"; -import AlarmProfile from "components/Common/Header/alarm/alarm_profile"; +import AlarmProfile from "components/Common/Header/alarm/AlarmProfile"; import { removeRefer } from "components/Common/Header/alarm/utils"; import useGapText from "hooks/useGapText"; import { useState } from "react"; @@ -31,7 +31,11 @@ const Container = styled.div` } `; -export default function FollowAlarm({ alarm }: { alarm: Alarm.FollowAlarm }) { +export default function FollowAlarm({ + alarm, +}: { + alarm: AlarmType.FollowAlarm; +}) { const alarmMessage = removeRefer(alarm.message); const dispatch = useAppDispatch(); const theme = useTheme(); @@ -44,7 +48,7 @@ export default function FollowAlarm({ alarm }: { alarm: Alarm.FollowAlarm }) { }); }; - const showUnfollowingModalOnHandler = () => { + const showUnfollowingModalHandler = () => { // 모달에 들어갈 유저 정보 세팅 dispatch( modalActions.setModalUsernameAndImageUrl({ @@ -76,7 +80,7 @@ export default function FollowAlarm({ alarm }: { alarm: Alarm.FollowAlarm }) { border: `1px solid ${theme.color.bd_gray}`, height: "30px", }} - onClick={showUnfollowingModalOnHandler} + onClick={showUnfollowingModalHandler} > 팔로잉 diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx index d31e5cdd..bac84904 100644 --- a/src/components/Common/Header/alarm/index.tsx +++ b/src/components/Common/Header/alarm/index.tsx @@ -1,7 +1,7 @@ import { alarmAction } from "app/store/ducks/alarm/alarmSlice"; import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; import { useAppDispatch, useAppSelector } from "app/store/Hooks"; -import AlarmList from "components/Common/Header/alarm/alarm_list"; +import AlarmList from "components/Common/Header/alarm/AlarmList"; import ImageSprite from "components/Common/ImageSprite"; import Loading from "components/Common/Loading"; import React, { useEffect, useState } from "react"; From 54e36fc6019a4089757bb4c196a9448e8d7315f1 Mon Sep 17 00:00:00 2001 From: suhwa Date: Wed, 28 Dec 2022 15:42:39 +0900 Subject: [PATCH 20/20] =?UTF-8?q?fix:=20Alarm=20=EB=AC=B4=ED=95=9C?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EA=B5=AC=ED=98=84=20=EC=8B=9C=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EC=83=81=ED=83=9C=EA=B0=92,=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 전역, 컴포넌트로 섞여있었음 -> 컴포넌트에서만 관리 --- src/app/store/ducks/alarm/alarmSlice.ts | 29 +++------------ src/components/Common/Header/alarm/index.tsx | 37 ++++++++++++-------- 2 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/app/store/ducks/alarm/alarmSlice.ts b/src/app/store/ducks/alarm/alarmSlice.ts index 9b19289e..28272112 100644 --- a/src/app/store/ducks/alarm/alarmSlice.ts +++ b/src/app/store/ducks/alarm/alarmSlice.ts @@ -1,35 +1,14 @@ import { createSlice } from "@reduxjs/toolkit"; -import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; -export interface AlarmStateProps { - alarmList: AlarmType.AlarmContent[] | null; - totalPage: number; -} +export interface AlarmStateProps {} -const initialState: AlarmStateProps = { - alarmList: null, - totalPage: 0, -}; +const initialState: AlarmStateProps = {}; const alarmSlice = createSlice({ name: " alarm", initialState, - reducers: { - clearAlarmList: (state) => { - state.alarmList = null; - }, - }, - extraReducers: (build) => { - build // - .addCase(loadAlarmList.fulfilled, (state, action) => { - if (action.payload.currentPage === 1) { - state.alarmList = action.payload.content; - state.totalPage = action.payload.totalPages; - } else { - state.alarmList?.push(...action.payload.content); - } - }); - }, + reducers: {}, + extraReducers: (build) => {}, }); export const alarmAction = alarmSlice.actions; diff --git a/src/components/Common/Header/alarm/index.tsx b/src/components/Common/Header/alarm/index.tsx index bac84904..fbb244df 100644 --- a/src/components/Common/Header/alarm/index.tsx +++ b/src/components/Common/Header/alarm/index.tsx @@ -1,12 +1,11 @@ -import { alarmAction } from "app/store/ducks/alarm/alarmSlice"; import { loadAlarmList } from "app/store/ducks/alarm/alarmThunk"; -import { useAppDispatch, useAppSelector } from "app/store/Hooks"; import AlarmList from "components/Common/Header/alarm/AlarmList"; import ImageSprite from "components/Common/ImageSprite"; import Loading from "components/Common/Loading"; -import React, { useEffect, useState } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import styled from "styled-components"; import sprite from "assets/Images/sprite.png"; +import { useAppDispatch } from "app/store/Hooks"; const Container = styled.div` position: relative; @@ -61,6 +60,7 @@ const Container = styled.div` } `; +// TODO: 팔로우 모달 닫을 때, 다 닫힘 -> 해당 모달만 닫히게! (알람은 닫히면 안됨) export default function Alarm({ alarmContainerRef, }: { @@ -68,23 +68,32 @@ export default function Alarm({ }) { const dispatch = useAppDispatch(); const [pageToLoad, setPageToLoad] = useState(1); - const { alarmList, totalPage } = useAppSelector((state) => state.alarm); + const [alarmList, setAlarmList] = useState([]); + const [totalPage, setTotalPage] = useState(1); useEffect(() => { - dispatch(loadAlarmList({ page: pageToLoad })); - setPageToLoad(pageToLoad + 1); - - return () => { - dispatch(alarmAction.clearAlarmList()); - }; + dispatch(loadAlarmList({ page: pageToLoad })) + .unwrap() + .then((res) => { + setAlarmList([...res.content]); + setTotalPage(res.totalPages); + setPageToLoad(pageToLoad + 1); + }); }, []); - const loadExtraAlarmList = () => { + const loadExtraAlarmList = useCallback(() => { if (pageToLoad <= totalPage) { - dispatch(loadAlarmList({ page: pageToLoad })); - setPageToLoad(pageToLoad + 1); + dispatch(loadAlarmList({ page: pageToLoad })) + .unwrap() + .then((res) => { + setAlarmList((currentList) => [ + ...currentList, + ...res.content, + ]); + setPageToLoad(pageToLoad + 1); + }); } - }; + }, [pageToLoad, totalPage, dispatch]); const emptyImage: CommonType.ImageProps = { width: 96,