Skip to content

Commit

Permalink
refactor: 채팅 목록 페이지 불필요한 API 호출 제거
Browse files Browse the repository at this point in the history
  • Loading branch information
Heeeera committed May 17, 2024
1 parent 6487cef commit 4756413
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 55 deletions.
10 changes: 10 additions & 0 deletions src/apis/chatRoomList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@ import { useSuspenseInfiniteQuery } from '@tanstack/react-query';
import { ROOMS_CHATS_MY_GAMES_API_URL } from '@/constants/apiRoutes';
import { CHAT_LIST_QUERY_KEY } from '@/constants/queryKey';

import { MessageType } from './chatRoomMessages';
import { api } from './core';

export interface LastChatMessage {
roomId: number;
content: string;
messageType: MessageType;
createdAt: string;
}

export interface ChatRoom {
id: number;
title: string;
imageUrl: string | null;
headCount: number;
unreadChatCount: number;
lastChatMessage: LastChatMessage;
}

interface ChatRoomListResponse {
Expand Down
78 changes: 47 additions & 31 deletions src/hooks/useSendChatMessage.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { useCallback, useEffect, useRef, useState } from 'react';

import { Client, IMessage } from '@stomp/stompjs';
import { useQueryClient } from '@tanstack/react-query';
import SockJS from 'sockjs-client';

import { type ChatMessage, type MessageType } from '@/apis/chatRoomMessages';
import type { LastChatMessage } from '@/apis/chatRoomList';
import type { ChatMessage, MessageType } from '@/apis/chatRoomMessages';
import {
CHAT_CONNECT_SOCKET_URL,
CHAT_EXIT_SOCKET_URL,
CHAT_SEND_SOCKET_URL,
CHAT_SUBSCRIBE_SOCKET_URL,
} from '@/constants/apiRoutes';
import { CHATS_QUERY_KEY } from '@/constants/queryKey';
import { STORAGE_KEY_ACCESS_TOKEN } from '@/constants/storageKeys';

export interface MessageRequest {
Expand All @@ -27,18 +26,45 @@ export interface MessageRequest {
*
*/

const useSendChatMessage = (
gatheringId: number,
interface SendChatMessageParams {
rawMessages?: ChatMessage[];
gatheringId: number;
isPublishExitMessage?: boolean;
rawLastChatMessage?: LastChatMessage;
unreadChatCount?: number;
}

const useSendChatMessage = ({
rawMessages = [],
gatheringId,
isPublishExitMessage = false,
rawLastChatMessage: ChatMessage | undefined = undefined,
) => {
rawLastChatMessage,
unreadChatCount = 0,
}: SendChatMessageParams) => {
const client = useRef<Client | null>(null);
const [lastChatMessage, setLastChatMessage] = useState<
ChatMessage | undefined
>(rawLastChatMessage);
const [lastMessage, setLastMessage] = useState(rawLastChatMessage);
const [messages, setMessages] = useState<ChatMessage[]>(rawMessages);
const [unreadMessagesCount, setUnreadMessagesCount] =
useState(unreadChatCount);

const accessToken = localStorage.getItem(STORAGE_KEY_ACCESS_TOKEN);
const queryClient = useQueryClient();

const subscribe = () => {
client.current?.subscribe(
`${CHAT_SUBSCRIBE_SOCKET_URL}/${gatheringId}`,
(message: IMessage) => {
const newMessage = JSON.parse(message.body);

setMessages(prevState => [newMessage, ...prevState]);
setLastMessage(newMessage);
setUnreadMessagesCount(prevState => prevState + 1);
},
{
Authorization: `Bearer ${accessToken}`,
RoomId: String(gatheringId),
},
);
};

const connect = () => {
const socket = new SockJS(
Expand All @@ -47,21 +73,8 @@ const useSendChatMessage = (

client.current = new Client({
webSocketFactory: () => socket,
onConnect: () =>
client.current?.subscribe(
`${CHAT_SUBSCRIBE_SOCKET_URL}/${gatheringId}`,
(message: IMessage) => {
queryClient.invalidateQueries({
queryKey: [CHATS_QUERY_KEY, gatheringId],
});

setLastChatMessage(JSON.parse(message.body));
},
{
Authorization: `Bearer ${accessToken}`,
RoomId: String(gatheringId),
},
),
debug: str => console.log(str),
onConnect: () => subscribe(),
onStompError: frame => {
throw new Error(`Broker reported error: ${frame.headers.message}`);
},
Expand All @@ -81,12 +94,9 @@ const useSendChatMessage = (
RoomId: gatheringId.toString(),
},
});

queryClient.invalidateQueries({
queryKey: [CHATS_QUERY_KEY, gatheringId],
});
}

setUnreadMessagesCount(0);
client.current.deactivate();
};

Expand Down Expand Up @@ -121,7 +131,13 @@ const useSendChatMessage = (
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return { lastChatMessage, sendMessage };
return {
messages,
lastMessage,
unreadMessagesCount,
sendMessage,
subscribe,
};
};

export default useSendChatMessage;
46 changes: 22 additions & 24 deletions src/pages/ChatRoomList/components/ChatRoomList/ChatRoomListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { Link } from 'react-router-dom';

import type { ChatRoom } from '@/apis/chatRoomList';
import {
ChatMessage,
useGetChatRoomMessagesApi,
} from '@/apis/chatRoomMessages';
import type { ChatRoom, LastChatMessage } from '@/apis/chatRoomList';
import defaultThumbnailImage from '@/assets/default-thumbnail-image.png';
import Button from '@/components/Button';
import Chip from '@/components/Chip';
Expand All @@ -17,24 +13,30 @@ interface ChatRoomListItemProps {
chatRoom: ChatRoom;
}

const MAX_UNCHECKED_MESSAGE_NUMBER = 50;

const ChatRoomListItem = ({ chatRoom }: ChatRoomListItemProps) => {
const { id, imageUrl, title, headCount } = chatRoom;
const { id, imageUrl, title, headCount, unreadChatCount, lastChatMessage } =
chatRoom;

const { lastChatMessage: rawLastChatMessage, uncheckedMessagesCount } =
useGetChatRoomMessagesApi(id, MAX_UNCHECKED_MESSAGE_NUMBER);
const { lastChatMessage } = useSendChatMessage(id, false, rawLastChatMessage);
const { lastMessage, unreadMessagesCount } = useSendChatMessage({
gatheringId: id,
rawLastChatMessage: lastChatMessage,
unreadChatCount,
});

const getLastChatMessageText = (lastChatMessage: ChatMessage | undefined) => {
const getLastChatMessageText = (lastChatMessage: LastChatMessage) => {
if (!lastChatMessage) {
return EMPTY_CHAT_ROOM_MESSAGE;
}

const { nickname, type, content } = lastChatMessage;
const { messageType, content } = lastChatMessage;
console.log(lastChatMessage);

if (type === 'UNFIX' || type === 'PARTICIPANT' || type === 'EXIT') {
return `${nickname}${content}`;
if (
messageType === 'UNFIX' ||
messageType === 'PARTICIPANT' ||
messageType === 'EXIT'
) {
return content.replace('님이', '참가자가');
}

return content;
Expand All @@ -56,20 +58,16 @@ const ChatRoomListItem = ({ chatRoom }: ChatRoomListItemProps) => {
<span className='text-xs text-gray-accent3'>{headCount}</span>
</div>
<div className='line-clamp-2 text-start text-xs text-gray-accent3'>
{getLastChatMessageText(lastChatMessage)}
{getLastChatMessageText(lastMessage as LastChatMessage)}
</div>
</div>
{lastChatMessage && (
{lastMessage && (
<div className='flex shrink-0 flex-col items-center gap-1 text-[10px] text-gray-accent3'>
<div>
{formatToTimeUntilTodayThenDate(lastChatMessage.createdAt)}
{formatToTimeUntilTodayThenDate(lastMessage.createdAt)}
</div>
{uncheckedMessagesCount !== 0 && (
<Chip variant='fill'>
{uncheckedMessagesCount === MAX_UNCHECKED_MESSAGE_NUMBER
? `${MAX_UNCHECKED_MESSAGE_NUMBER}+`
: uncheckedMessagesCount}
</Chip>
{unreadMessagesCount !== 0 && (
<Chip variant='fill'>{unreadMessagesCount}</Chip>
)}
</div>
)}
Expand Down

0 comments on commit 4756413

Please sign in to comment.