Skip to content

Commit

Permalink
Merge pull request #82 from prgrms-web-devcourse/BM-375
Browse files Browse the repository at this point in the history
[BM-375] 채팅방 채팅 메세지 위에 해당 날짜들 표시하기
  • Loading branch information
HoseokNa authored Sep 5, 2022
2 parents 9badaba + 34c48b0 commit 4af966e
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 25 deletions.
9 changes: 6 additions & 3 deletions components/ChatRoom/ChatDateBox.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Center, Text } from '@chakra-ui/react';

// TODO: 메세지 날짜별로 구분하고 날짜를 prop으로 받기
const ChatDateBox = () => {
interface ChatDateBoxProps {
chatDate: string;
}

const ChatDateBox = ({ chatDate }: ChatDateBoxProps) => {
return (
<Center
bgColor="brand.primary-100"
Expand All @@ -17,7 +20,7 @@ const ChatDateBox = () => {
fontSize="13px"
lineHeight="15px"
>
2022년 8월 14일
{chatDate}
</Text>
</Center>
);
Expand Down
49 changes: 49 additions & 0 deletions hooks/useChatMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useCallback, useState } from 'react';

import { ChatMeesageResponseType, ChatMessageData } from 'types/chatMessages';
import chatDateFormat from 'utils/format/chatDateFormat';

export type ChatMessagesType = {
chatDate: string;
messages: ChatMeesageResponseType;
};

const useChatMessages = () => {
const map = new Map();
const [chatMessages, setChatMessages] = useState<ChatMessagesType[]>([]);

const setPrevMessagesFromApi = useCallback(
(messages: ChatMeesageResponseType) => {
messages.forEach((message) => {
const date = chatDateFormat(new Date(message.createdAt));
const prevMessages = map.get(date) || [];

map.set(date, [...prevMessages, message]);
});

setChatMessages(
[...map].map(([chatDate, messages]) => ({ chatDate, messages }))
);
},
[]
);

const addMessage = useCallback((message: ChatMessageData) => {
const today = chatDateFormat(new Date());
const prevMessages = map.get(today) || [];

map.set(today, [...prevMessages, message]);

setChatMessages(
[...map].map(([chatDate, messages]) => ({ chatDate, messages }))
);
}, []);

return {
chatMessages,
setPrevMessagesFromApi,
addMessage,
};
};

export default useChatMessages;
15 changes: 5 additions & 10 deletions hooks/useStomp.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Client } from '@stomp/stompjs';
import getConfig from 'next/config';
import { Dispatch, SetStateAction, useCallback } from 'react';
import { useCallback } from 'react';
import SockJS from 'sockjs-client';

import { ChatMeesageResponseType } from 'types/chatMessages';
import { ChatMessageData } from 'types/chatMessages';
import { UserInfo } from 'types/user';

const { publicRuntimeConfig } = getConfig();
Expand All @@ -12,10 +12,10 @@ let client: Client | null = null;
export interface UseStompProps {
chatRoomId: number;
userInfo: UserInfo;
setMessages: Dispatch<SetStateAction<ChatMeesageResponseType>>;
addMessage: (message: ChatMessageData) => void;
}

const useStomp = ({ chatRoomId, userInfo, setMessages }: UseStompProps) => {
const useStomp = ({ chatRoomId, userInfo, addMessage }: UseStompProps) => {
const connect = () => {
if (client !== null) {
return;
Expand Down Expand Up @@ -46,12 +46,7 @@ const useStomp = ({ chatRoomId, userInfo, setMessages }: UseStompProps) => {
return;
}

if (message.body) {
setMessages((prevMessages) => [
...prevMessages,
JSON.parse(message.body),
]);
}
addMessage(JSON.parse(message.body));
}
);

Expand Down
31 changes: 19 additions & 12 deletions pages/user/[userId]/chat/[chatRoomId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {
InferGetServerSidePropsType,
NextPage,
} from 'next';
import { useEffect, useRef, useState } from 'react';
import { Fragment, useEffect, useRef } from 'react';

import { userAPI } from 'apis';
import { ChatDateBox, ChatInput, MessageList } from 'components/ChatRoom';
import { GoBackIcon, Header, HeaderTitle } from 'components/common';
import useChatMessages, { ChatMessagesType } from 'hooks/useChatMessages';
import useStomp from 'hooks/useStomp';
import { ChatMeesageResponseType } from 'types/chatMessages';

export const getServerSideProps: GetServerSideProps = async ({
query: { userId, chatRoomId, chattingUsername = '' },
Expand All @@ -37,15 +37,16 @@ const ChatRoom: NextPage = ({
chatRoomId,
chattingUsername,
}: InferGetServerSidePropsType<typeof getServerSideProps>) => {
const [messages, setMessages] = useState<ChatMeesageResponseType>([]);
const { chatMessages, setPrevMessagesFromApi, addMessage } =
useChatMessages();
const { connect, disConnect, publish } = useStomp({
chatRoomId,
userInfo: {
userId: user.id,
username: user.username,
profileImage: user.profileImage,
},
setMessages,
addMessage,
});
const lastRef = useRef<HTMLDivElement>(null);

Expand All @@ -67,7 +68,9 @@ const ChatRoom: NextPage = ({
})
).data;

setMessages([...chatMessages.reverse(), ...messages]);
const nextMessages = [...chatMessages.reverse()];

setPrevMessagesFromApi(nextMessages);
};

useEffect(() => {
Expand All @@ -79,7 +82,7 @@ const ChatRoom: NextPage = ({
behavior: 'smooth',
block: 'end',
});
}, [lastRef, messages]);
}, [lastRef, chatMessages]);

// TODO: ... 아이콘에 채팅방 나가기, 신고하기 기능
return (
Expand All @@ -89,12 +92,16 @@ const ChatRoom: NextPage = ({
middleContent={<HeaderTitle title={chattingUsername} />}
/>
<Flex height="100%" flexDirection="column" gap="16px">
<Center>
<ChatDateBox />
</Center>
<Flex flexDirection="column" flexGrow="1">
<MessageList userId={user.id} messages={messages} />
</Flex>
{chatMessages.map(({ chatDate, messages }: ChatMessagesType, index) => (
<Fragment key={index}>
<Center>
<ChatDateBox chatDate={chatDate} />
</Center>
<Flex flexDirection="column">
<MessageList userId={user.id} messages={messages} />
</Flex>
</Fragment>
))}
</Flex>
<Flex
position="sticky"
Expand Down
7 changes: 7 additions & 0 deletions utils/format/chatDateFormat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { format } from 'date-fns';
import { ko } from 'date-fns/locale';

const chatDateFormat = (createdAt: Date) =>
format(new Date(createdAt), 'yyyy년 M월 d일', { locale: ko });

export default chatDateFormat;

1 comment on commit 4af966e

@vercel
Copy link

@vercel vercel bot commented on 4af966e Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

bidmarket – ./

bidmarket-git-main-saiko-team.vercel.app
bidmarket.vercel.app
bidmarket-saiko-team.vercel.app

Please sign in to comment.