diff --git a/frontend/src/components/landing/member/LandingMember.tsx b/frontend/src/components/landing/member/LandingMember.tsx
index 56f5905..b26ed7a 100644
--- a/frontend/src/components/landing/member/LandingMember.tsx
+++ b/frontend/src/components/landing/member/LandingMember.tsx
@@ -8,6 +8,7 @@ import useUpdateUserStatus from "../../../hooks/common/member/useUpdateUserStatu
import { DEFAULT_MEMBER } from "../../../constants/projects";
import { memberResponse } from "../../../types/DTO/authDTO";
import emitMemberStatusUpdate from "../../../utils/emitMemberStatusUpdate";
+import { STORAGE_KEY } from "../../../constants/storageKey";
interface LandingMemberProps {
projectTitle: string;
@@ -56,18 +57,20 @@ const LandingMember = ({ projectTitle }: LandingMemberProps) => {
};
function selectStatusOption(option: string) {
- emitMemberStatusUpdate(socket, {
- ...myInfo,
- status: USER_WORD_STATUS[option],
- });
-
if (option === USER_STATUS_WORD.away || option === USER_STATUS_WORD.off) {
handleCanAddStatusEventListener(false);
+ localStorage.setItem(STORAGE_KEY.UPDATE_STATUS_WITH_INTENTION, "true");
removeUserStatusEventListener();
} else {
handleCanAddStatusEventListener(true);
+ localStorage.removeItem(STORAGE_KEY.UPDATE_STATUS_WITH_INTENTION);
addUserStatusEventListener();
}
+
+ emitMemberStatusUpdate(socket, {
+ ...myInfo,
+ status: USER_WORD_STATUS[option],
+ });
}
return (
diff --git a/frontend/src/components/landing/member/UserBlock.tsx b/frontend/src/components/landing/member/UserBlock.tsx
index 4979901..c3a4323 100644
--- a/frontend/src/components/landing/member/UserBlock.tsx
+++ b/frontend/src/components/landing/member/UserBlock.tsx
@@ -12,19 +12,17 @@ const UserStateDisplay = ({ status }: { status: "on" | "off" | "away" }) => {
return (
);
};
-const UserBlock = ({ imageUrl, username, status }: UserBlockProps) => {
- return (
-
- );
-};
+const UserBlock = ({ imageUrl, username, status }: UserBlockProps) => (
+
+);
export default UserBlock;
diff --git a/frontend/src/constants/storageKey.ts b/frontend/src/constants/storageKey.ts
index 3cb1294..c900b23 100644
--- a/frontend/src/constants/storageKey.ts
+++ b/frontend/src/constants/storageKey.ts
@@ -1,4 +1,5 @@
export const STORAGE_KEY = {
MEMBER: "member",
REDIRECT: "redirect",
+ UPDATE_STATUS_WITH_INTENTION: "updateStatusWithIntention",
};
diff --git a/frontend/src/hooks/common/member/useAwayUser.ts b/frontend/src/hooks/common/member/useAwayUser.ts
index a6bcf60..d40c59e 100644
--- a/frontend/src/hooks/common/member/useAwayUser.ts
+++ b/frontend/src/hooks/common/member/useAwayUser.ts
@@ -3,6 +3,7 @@ import { Socket } from "socket.io-client";
import useMemberStore from "../../../stores/useMemberStore";
import useThrottle from "../throttle/useThrottle";
import emitMemberStatusUpdate from "../../../utils/emitMemberStatusUpdate";
+import { STORAGE_KEY } from "../../../constants/storageKey";
const useAwayUser = (socket: Socket) => {
const timerRef = useRef(null);
@@ -70,6 +71,13 @@ const useAwayUser = (socket: Socket) => {
addUserStatusEventListener();
}
+ if (
+ localStorage.getItem(STORAGE_KEY.UPDATE_STATUS_WITH_INTENTION) === "true"
+ ) {
+ removeUserStatusEventListener();
+ return;
+ }
+
return () => {
removeUserStatusEventListener();
};
diff --git a/frontend/src/hooks/common/member/useUpdateUserStatus.ts b/frontend/src/hooks/common/member/useUpdateUserStatus.ts
index c3c3e44..943f623 100644
--- a/frontend/src/hooks/common/member/useUpdateUserStatus.ts
+++ b/frontend/src/hooks/common/member/useUpdateUserStatus.ts
@@ -1,3 +1,4 @@
+import { useEffect, useRef } from "react";
import { Socket } from "socket.io-client";
import {
LandingSocketData,
@@ -6,8 +7,8 @@ import {
} from "../../../types/common/landing";
import { LandingDTO, LandingMemberDTO } from "../../../types/DTO/landingDTO";
import useMemberStore from "../../../stores/useMemberStore";
-import { useEffect, useRef } from "react";
import { USER_STATUS_WORD } from "../../../constants/landing";
+import sortMemberByStatus from "../../../utils/sortMemberByStatus";
const useUpdateUserStatus = (
socket: Socket,
@@ -22,11 +23,11 @@ const useUpdateUserStatus = (
addMember,
} = useMemberStore();
const inviteLinkIdRef = useRef("");
-
const handleInitEvent = (content: LandingDTO) => {
const { myInfo, member: memberList, inviteLinkId } = content;
updateMyInfo(myInfo);
- updateMemberList(memberList);
+ handleChangeStatus(USER_STATUS_WORD[myInfo.status]);
+ updateMemberList(memberList.sort(sortMemberByStatus));
inviteLinkIdRef.current = inviteLinkId;
};
@@ -51,16 +52,18 @@ const useUpdateUserStatus = (
}
updateMemberList(
- memberList.map((member) => {
- if (member.id === content.id) {
- return {
- ...member,
- status: (content as LandingMemberDTO).status,
- };
- }
+ memberList
+ .map((member) => {
+ if (member.id === content.id) {
+ return {
+ ...member,
+ status: (content as LandingMemberDTO).status,
+ };
+ }
- return member;
- })
+ return member;
+ })
+ .sort(sortMemberByStatus)
);
break;
diff --git a/frontend/src/hooks/common/socket/useLandingSocket.ts b/frontend/src/hooks/common/socket/useLandingSocket.ts
index fcbeb33..1f4b2d5 100644
--- a/frontend/src/hooks/common/socket/useLandingSocket.ts
+++ b/frontend/src/hooks/common/socket/useLandingSocket.ts
@@ -1,68 +1,27 @@
import { Socket } from "socket.io-client";
import { useEffect, useState } from "react";
-import {
- LandingDTO,
- LandingLinkDTO,
- LandingMemoDTO,
- LandingProjectDTO,
- LandingSprintDTO,
-} from "../../../types/DTO/landingDTO";
+import { LandingDTO, LandingProjectDTO } from "../../../types/DTO/landingDTO";
import { DEFAULT_VALUE } from "../../../constants/landing";
import {
LandingSocketData,
LandingSocketDomain,
- LandingSocketMemoAction,
} from "../../../types/common/landing";
const useLandingSocket = (socket: Socket) => {
const [project, setProject] = useState(
DEFAULT_VALUE.PROJECT
);
- const [sprint, setSprint] = useState(null);
- const [memoList, setMemoList] = useState([]);
- const [link, setLink] = useState([]);
const handleInitEvent = (content: LandingDTO) => {
- const { project, sprint, memoList, link } = content as LandingDTO;
+ const { project } = content as LandingDTO;
setProject(project);
- setSprint(sprint);
- setMemoList(memoList);
- setLink(link);
};
- const handleMemoEvent = (
- action: LandingSocketMemoAction,
- content: LandingMemoDTO
- ) => {
- switch (action) {
- case LandingSocketMemoAction.CREATE:
- setMemoList((memoList: LandingMemoDTO[]) => [content, ...memoList]);
- break;
- case LandingSocketMemoAction.DELETE:
- setMemoList((memoList: LandingMemoDTO[]) =>
- memoList.filter((memo: LandingMemoDTO) => memo.id !== content.id)
- );
- break;
- case LandingSocketMemoAction.COLOR_UPDATE:
- setMemoList((memoList: LandingMemoDTO[]) =>
- memoList.map((memo: LandingMemoDTO) => {
- if (memo.id !== content.id) {
- return memo;
- }
- return { ...memo, color: content.color };
- })
- );
- }
- };
-
- const handleOnLanding = ({ domain, action, content }: LandingSocketData) => {
+ const handleOnLanding = ({ domain, content }: LandingSocketData) => {
switch (domain) {
case LandingSocketDomain.INIT:
handleInitEvent(content);
break;
- case LandingSocketDomain.MEMO:
- handleMemoEvent(action, content);
- break;
}
};
@@ -77,9 +36,6 @@ const useLandingSocket = (socket: Socket) => {
return {
project,
- sprint,
- memoList,
- link,
};
};
diff --git a/frontend/src/test/sortMemberByStatus.test.ts b/frontend/src/test/sortMemberByStatus.test.ts
new file mode 100644
index 0000000..cbf6504
--- /dev/null
+++ b/frontend/src/test/sortMemberByStatus.test.ts
@@ -0,0 +1,20 @@
+import { LandingMemberDTO } from "../types/DTO/landingDTO";
+import sortMemberByStatus from "../utils/sortMemberByStatus";
+
+describe("sortMemberByStatus test", () => {
+ it("on, away, off 순 정렬 테스트", () => {
+ const memberList: LandingMemberDTO[] = [
+ { id: 1, username: "", imageUrl: "", status: "off" },
+ { id: 2, username: "", imageUrl: "", status: "on" },
+ { id: 3, username: "", imageUrl: "", status: "away" },
+ { id: 4, username: "", imageUrl: "", status: "on" },
+ { id: 5, username: "", imageUrl: "", status: "off" },
+ { id: 6, username: "", imageUrl: "", status: "away" },
+ ];
+
+ const sortedMemberIdList = memberList
+ .sort(sortMemberByStatus)
+ .map(({ id }) => id);
+ expect(sortedMemberIdList).toStrictEqual([2, 4, 3, 6, 1, 5]);
+ });
+});
diff --git a/frontend/src/utils/sortMemberByStatus.ts b/frontend/src/utils/sortMemberByStatus.ts
new file mode 100644
index 0000000..7696151
--- /dev/null
+++ b/frontend/src/utils/sortMemberByStatus.ts
@@ -0,0 +1,32 @@
+import { LandingMemberDTO, MemberStatus } from "../types/DTO/landingDTO";
+
+const getStatusOrder = (status: MemberStatus) => {
+ if (status === "on") {
+ return 2;
+ }
+
+ if (status === "away") {
+ return 1;
+ }
+
+ return 0;
+};
+
+const sortMemberByStatus = (
+ member1: LandingMemberDTO,
+ member2: LandingMemberDTO
+) => {
+ const member1Status = getStatusOrder(member1.status);
+ const member2Status = getStatusOrder(member2.status);
+ if (member1Status > member2Status) {
+ return -1;
+ }
+
+ if (member1Status < member2Status) {
+ return 1;
+ }
+
+ return 0;
+};
+
+export default sortMemberByStatus;