Skip to content

Commit 947a6ee

Browse files
committed
Refactor: Chats 코드 흐름 정리 & 변수 명명 규칙에 따라 변수명 수정
1 parent f777257 commit 947a6ee

10 files changed

Lines changed: 150 additions & 158 deletions

File tree

src/pages/Chats/ChatRoom/ChatBox/index.tsx

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ import { OpponentInfoAtom } from '@recoil/util/OpponentInfo';
66
import { useSocket } from '@context/SocketProvider';
77

88
const ChatBox: React.FC = () => {
9-
const opponentInfo = useRecoilValue(OpponentInfoAtom);
10-
const storageValue = localStorage.getItem('my_id');
11-
const userId = storageValue ? Number(storageValue) : -1;
12-
const { chatRoomId } = useParams();
13-
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
14-
159
const [newMessage, setNewMessage] = useState('');
16-
10+
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
1711
const socket = useSocket();
12+
13+
const { chatRoomId } = useParams();
14+
const storageValue = localStorage.getItem('my_id');
15+
const userId = storageValue ? Number(storageValue) : -1;
16+
const opponentInfo = useRecoilValue(OpponentInfoAtom);
1817
const isOpponentValid = !!(opponentInfo && opponentInfo.id);
1918

19+
useEffect(() => {
20+
if (textareaRef.current && !isOpponentValid) {
21+
textareaRef.current.disabled = true;
22+
textareaRef.current.placeholder = '메시지를 보낼 수 없습니다.';
23+
}
24+
}, []);
25+
2026
// textarea 내용에 따라 높이 조정
2127
useEffect(() => {
2228
if (textareaRef.current) {
@@ -25,23 +31,23 @@ const ChatBox: React.FC = () => {
2531
}
2632
}, [newMessage]);
2733

28-
useEffect(() => {
29-
if (textareaRef.current && !isOpponentValid) {
30-
textareaRef.current.disabled = true;
31-
textareaRef.current.placeholder = '메시지를 보낼 수 없습니다.';
32-
}
33-
}, []);
34-
35-
const onChangeMessage = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {
34+
const handleMessageChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
3635
setNewMessage(e.target.value);
3736
};
3837

39-
const sendNewMessage = (): void => {
38+
const handleEnterKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
39+
if (e.key === 'Enter' && !e.shiftKey) {
40+
e.preventDefault();
41+
handleNewMessageSubmit();
42+
}
43+
};
44+
45+
const handleNewMessageSubmit = () => {
4046
if (newMessage === '') {
4147
return;
4248
}
4349

44-
// 메시지 전송
50+
// 메시지 전송 api
4551
if (socket) {
4652
const sendMessageRequest = {
4753
chatRoomId: Number(chatRoomId),
@@ -50,31 +56,23 @@ const ChatBox: React.FC = () => {
5056
fromUserId: userId,
5157
createdAt: new Date().toISOString(),
5258
};
53-
5459
socket.emit('sendMessage', sendMessageRequest);
5560
setNewMessage('');
5661
}
5762
};
5863

59-
const onKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>): void => {
60-
if (e.key === 'Enter' && !e.shiftKey) {
61-
e.preventDefault();
62-
sendNewMessage();
63-
}
64-
};
65-
6664
return (
6765
<ChatBoxContainer>
6866
<Textarea
6967
$isOpponentValid={isOpponentValid}
7068
placeholder="메시지 보내기"
7169
ref={textareaRef}
7270
value={newMessage}
73-
onKeyDown={onKeyDown}
74-
onChange={onChangeMessage}
75-
onSubmit={sendNewMessage}
71+
onChange={handleMessageChange}
72+
onKeyDown={handleEnterKeyDown}
73+
onSubmit={handleNewMessageSubmit}
7674
/>
77-
<SendButton $isOpponentValid={isOpponentValid} onClick={sendNewMessage} />
75+
<SendButton $isOpponentValid={isOpponentValid} onClick={handleNewMessageSubmit} />
7876
</ChatBoxContainer>
7977
);
8078
};

src/pages/Chats/ChatRoom/RcvdMessage/index.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,17 @@ const RcvdMessage: React.FC<RcvdMessageProps & { onClickProfile: () => void }> =
1616
}) => {
1717
if (isProfileImageVisible) {
1818
return (
19-
<>
20-
<FirstMessageLayout $isSenderChanged={isSenderChanged}>
21-
<UserImage onClick={onClickProfile} src={profilePictureUrl} alt="프로필 사진" />
22-
<MessageBox>
23-
<UsernameText onClick={onClickProfile} $textTheme={{ style: 'body2-regular' }} color={theme.colors.black}>
24-
{fromUserNickname}
25-
</UsernameText>
26-
<Message $textTheme={{ style: 'body2-regular' }} color={theme.colors.black}>
27-
{content}
28-
</Message>
29-
</MessageBox>
30-
</FirstMessageLayout>
31-
</>
19+
<FirstMessageLayout $isSenderChanged={isSenderChanged}>
20+
<UserImage onClick={onClickProfile} src={profilePictureUrl} alt="프로필 사진" />
21+
<MessageBox>
22+
<UsernameText onClick={onClickProfile} $textTheme={{ style: 'body2-regular' }} color={theme.colors.black}>
23+
{fromUserNickname}
24+
</UsernameText>
25+
<Message $textTheme={{ style: 'body2-regular' }} color={theme.colors.black}>
26+
{content}
27+
</Message>
28+
</MessageBox>
29+
</FirstMessageLayout>
3230
);
3331
} else {
3432
return (

src/pages/Chats/ChatRoom/SentMessage/index.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ import { Message, TimeWrapper, MessageLayout } from './styles';
66
const SentMessage: React.FC<SentMessageProps> = React.memo(
77
({ content, isSenderChanged, isTimeVisible, formattedTime }) => {
88
return (
9-
<>
10-
<MessageLayout $isSenderChanged={isSenderChanged}>
11-
{isTimeVisible && <TimeWrapper>{formattedTime}</TimeWrapper>}
12-
<Message $textTheme={{ style: 'body2-regular' }} color={theme.colors.black}>
13-
{content}
14-
</Message>
15-
</MessageLayout>
16-
</>
9+
<MessageLayout $isSenderChanged={isSenderChanged}>
10+
{isTimeVisible && <TimeWrapper>{formattedTime}</TimeWrapper>}
11+
<Message $textTheme={{ style: 'body2-regular' }} color={theme.colors.black}>
12+
{content}
13+
</Message>
14+
</MessageLayout>
1715
);
1816
},
1917
);

src/pages/Chats/ChatRoom/createExtendedMessages.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ export const createExtendedMessages = (
1414
const isNewDay = (curDate: string, lastDate: string) => {
1515
const curDateDayjs = dayjs(curDate);
1616
const lastDateDayjs = dayjs(lastDate);
17+
1718
return !curDateDayjs.isSame(lastDateDayjs, 'day');
1819
};
1920

21+
// 렌더링에 필요한 요소를 추가한 메시지 배열
2022
const temp: ExtendedMessageDto[] = allMessages.map((message: chatRoomMessagesData, index) => {
2123
const prevMessage = index !== 0 ? allMessages[index - 1] : null;
2224
const nextMessage = index !== allMessages.length - 1 ? allMessages[index + 1] : null;

src/pages/Chats/ChatRoom/index.tsx

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,18 @@ const ChatRoom: React.FC = () => {
4646
const chatWindowRef = useRef<HTMLDivElement>(null);
4747
const messageLengthRef = useRef(0);
4848

49+
const nav = useNavigate();
50+
const socket = useSocket();
51+
4952
const storageValue = localStorage.getItem('my_id');
5053
const userId = storageValue ? Number(storageValue) : -1;
5154
const { chatRoomId } = useParams();
5255
const opponentInfo = useRecoilValue(OpponentInfoAtom);
5356

54-
const nav = useNavigate();
55-
const socket = useSocket();
57+
// 메시지 수신 시 아래로 스크롤 (스크롤 아래 고정)
58+
const scrollToBottom = (ref: React.RefObject<HTMLDivElement>) => {
59+
if (ref.current) ref.current.scrollIntoView();
60+
};
5661

5762
// 프로필 사진 클릭 시 프로필 페이지로 이동
5863
const handleUserClick = useCallback(() => {
@@ -100,7 +105,7 @@ const ChatRoom: React.FC = () => {
100105
}
101106
};
102107

103-
// 전체 메시지 조회
108+
// 전체 메시지 조회 socket api
104109
const getChatRoomMessages = (data: chatRoomMessagesData[]) => {
105110
setAllMessages(data);
106111
if (data.length > messageLengthRef.current) {
@@ -109,12 +114,37 @@ const ChatRoom: React.FC = () => {
109114
setIsLoading(false);
110115
};
111116

112-
// 새 메시지 수신
117+
// 새 메시지 수신 socket api
113118
const getNewMessage = (data: chatRoomMessagesData) => {
114119
setAllMessages((prevMessages) => [...prevMessages, data]);
115120
setIsScroll((prev) => !prev);
116121
};
117122

123+
// 채팅방 입장 시 스크롤 아래로 이동
124+
useEffect(() => {
125+
const messagesContainer = chatWindowRef.current?.parentElement;
126+
127+
if (messagesContainer) {
128+
messagesContainer.style.scrollBehavior = 'auto';
129+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
130+
}
131+
}, []);
132+
133+
// 메시지 수신 시 스크롤 아래로 이동
134+
useEffect(() => {
135+
if (isScroll) {
136+
scrollToBottom(chatWindowRef);
137+
setIsScroll((prev) => !prev);
138+
}
139+
}, [isScroll]);
140+
141+
// 메시지 수신 시 렌더링에 필요한 정보 추가
142+
// 이거 위에랑 합칠수없나?
143+
useEffect(() => {
144+
const temp = createExtendedMessages(allMessages, userId, opponentInfo);
145+
setextendedMessages(temp);
146+
}, [allMessages]);
147+
118148
useEffect(() => {
119149
if (socket) {
120150
// 채팅방 입장
@@ -137,34 +167,6 @@ const ChatRoom: React.FC = () => {
137167
};
138168
}, [chatRoomId, socket]);
139169

140-
// 메시지 렌더링에 필요한 정보 추가
141-
useEffect(() => {
142-
const temp = createExtendedMessages(allMessages, userId, opponentInfo);
143-
setextendedMessages(temp);
144-
}, [allMessages]);
145-
146-
const scrollToBottom = (ref: React.RefObject<HTMLDivElement>) => {
147-
if (ref.current) ref.current.scrollIntoView();
148-
};
149-
150-
useEffect(() => {
151-
// 채팅방 입장 시 스크롤 아래로 이동
152-
const messagesContainer = chatWindowRef.current?.parentElement;
153-
154-
if (messagesContainer) {
155-
messagesContainer.style.scrollBehavior = 'auto';
156-
messagesContainer.scrollTop = messagesContainer.scrollHeight;
157-
}
158-
}, []);
159-
160-
// 메시지 수신 시 스크롤 아래로 이동
161-
useEffect(() => {
162-
if (isScroll) {
163-
scrollToBottom(chatWindowRef);
164-
setIsScroll((prev) => !prev);
165-
}
166-
}, [isScroll]);
167-
168170
const bottomSheetMenuProps: BottomSheetMenuProps = {
169171
items: [
170172
{
@@ -218,7 +220,7 @@ const ChatRoom: React.FC = () => {
218220
},
219221
};
220222

221-
const kebabMenuBottomSheet: BottomSheetProps<BottomSheetMenuProps> = {
223+
const kebabMenuBottomSheetProps: BottomSheetProps<BottomSheetMenuProps> = {
222224
isOpenBottomSheet: isMenuBottomSheetOpen,
223225
isHandlerVisible: true,
224226
Component: BottomSheetMenu,
@@ -230,11 +232,6 @@ const ChatRoom: React.FC = () => {
230232

231233
return (
232234
<OODDFrame>
233-
{isLoading && <Loading />}
234-
{isLeaveModalOpen && <Modal {...leaveModalProps} />}
235-
{isBlockModalOpen && <Modal {...blockModalProps} />}
236-
{isStatusModalOpen && <Modal {...statusModalProps} />}
237-
<BottomSheet {...kebabMenuBottomSheet} />
238235
<TopBar
239236
text={opponentInfo?.nickname || '알수없음'}
240237
LeftButtonSrc={Back}
@@ -264,7 +261,12 @@ const ChatRoom: React.FC = () => {
264261
})}
265262
<div ref={chatWindowRef} />
266263
</MessagesContainer>
267-
<ChatBox></ChatBox>
264+
<ChatBox />
265+
{isLoading && <Loading />}
266+
{isLeaveModalOpen && <Modal {...leaveModalProps} />}
267+
{isBlockModalOpen && <Modal {...blockModalProps} />}
268+
{isStatusModalOpen && <Modal {...statusModalProps} />}
269+
<BottomSheet {...kebabMenuBottomSheetProps} />
268270
</OODDFrame>
269271
);
270272
};

src/pages/Chats/ChatRoomItem/index.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ import defaultProfile from '@assets/default/defaultProfile.svg';
1212
dayjs.extend(relativeTime);
1313

1414
const ChatRoomItem: React.FC<ChatRoomData> = ({ chatRoomId, otherUser, latestMessage }) => {
15-
const nav = useNavigate();
16-
const [, setOpponentInfo] = useRecoilState(OpponentInfoAtom);
1715
const [timeAgo, setTimeAgo] = useState<string | null>(null);
16+
const [, setOpponentInfo] = useRecoilState(OpponentInfoAtom);
17+
const nav = useNavigate();
18+
19+
const handleChatRoomClick = () => {
20+
setOpponentInfo(otherUser);
21+
nav(`/chats/${chatRoomId}`);
22+
};
1823

1924
useEffect(() => {
2025
if (latestMessage.createdAt) {
@@ -33,13 +38,8 @@ const ChatRoomItem: React.FC<ChatRoomData> = ({ chatRoomId, otherUser, latestMes
3338
}
3439
}, []);
3540

36-
const onClickChatRoom = () => {
37-
setOpponentInfo(otherUser);
38-
nav(`/chats/${chatRoomId}`);
39-
};
40-
4141
return (
42-
<ChatRoomItemLayout onClick={onClickChatRoom}>
42+
<ChatRoomItemLayout onClick={handleChatRoomClick}>
4343
<UserImage src={otherUser?.profileUrl || defaultProfile} alt="user" />
4444
<LeftBox>
4545
<StyledText $textTheme={{ style: 'body2-medium' }} color="#1D1D1D">

0 commit comments

Comments
 (0)