-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/MOVIEJOJO7/cat-talk into fe…
…ature/#48
- Loading branch information
Showing
11 changed files
with
541 additions
and
169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { getCookie } from '@/Components/Login/Cookie'; | ||
import { useRouter } from 'next/navigation'; | ||
import { Socket } from 'socket.io-client'; | ||
import { DefaultEventsMap } from 'socket.io/dist/typed-events'; | ||
|
||
const ChatHeader = ({ | ||
socket, | ||
chatId, | ||
chatName, | ||
chatUsers, | ||
}: { | ||
socket: Socket<DefaultEventsMap, DefaultEventsMap>; | ||
chatId: string; | ||
chatName: string; | ||
chatUsers: number; | ||
}) => { | ||
const router = useRouter(); | ||
|
||
const accessToken = getCookie('accessToken'); | ||
|
||
const handleBackChat = () => { | ||
socket.disconnect(); | ||
router.back(); | ||
}; | ||
|
||
const handleLeaveChat = async () => { | ||
await fetch('https://fastcampus-chat.net/chat/leave', { | ||
method: 'PATCH', | ||
headers: { | ||
'content-type': 'application/json', | ||
serverId: process.env.NEXT_PUBLIC_SERVER_ID as string, | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
body: JSON.stringify({ chatId }), | ||
}); | ||
|
||
socket.disconnect(); | ||
router.back(); | ||
}; | ||
|
||
return ( | ||
<> | ||
<button onClick={handleBackChat}>뒤로 가기</button> | ||
<span>{chatName}</span> | ||
<span>{chatUsers}</span> | ||
<button onClick={handleLeaveChat}>채팅방 나가기</button> | ||
</> | ||
); | ||
}; | ||
|
||
export default ChatHeader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
'use client'; | ||
|
||
import React, { useEffect, useState } from 'react'; | ||
import { Socket } from 'socket.io-client'; | ||
import { Chat, Message, chatUsersObject } from '@/types'; | ||
import { DefaultEventsMap } from 'socket.io/dist/typed-events'; | ||
import ChatHeader from '@/Components/Chat/ChatHeader'; | ||
import RenderChats from '@/Components/Chat/RenderChats'; | ||
|
||
const ChatRoom = ({ | ||
socket, | ||
chatId, | ||
privateValue, | ||
accessToken, | ||
}: { | ||
socket: Socket<DefaultEventsMap, DefaultEventsMap>; | ||
chatId: string; | ||
privateValue: string; | ||
accessToken: string; | ||
}) => { | ||
const initChatusers = { | ||
id: '', | ||
name: '', | ||
users: [], // 속한 유저 정보 | ||
isPrivate: JSON.parse(privateValue), | ||
latestMessage: null, | ||
updatedAt: new Date(), | ||
}; | ||
|
||
const [messages, setMessages] = useState<Message[]>([]); | ||
const [newMessage, setNewMessage] = useState(''); | ||
const [chatUsers, setChatUsers] = useState<Chat>(initChatusers); | ||
|
||
// 채팅 참여자 fetch, socket 이벤트 등록 (1회 동작) | ||
useEffect(() => { | ||
const fetchChatUsers = async () => { | ||
const res = await fetch( | ||
`https://fastcampus-chat.net/chat/only?chatId=${chatId}`, | ||
{ | ||
method: 'GET', | ||
headers: { | ||
'content-type': 'application/json', | ||
serverId: process.env.NEXT_PUBLIC_SERVER_ID as string, | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
cache: 'no-cache', | ||
}, | ||
); | ||
const chatUsersObject: chatUsersObject = await res.json(); | ||
const chatUsers: Chat = chatUsersObject.chat; | ||
|
||
setChatUsers(chatUsers); | ||
}; | ||
|
||
fetchChatUsers(); | ||
|
||
socket.on('connect', () => { | ||
socket.on('messages-to-client', (responseData) => { | ||
setMessages(responseData.messages); | ||
}); | ||
|
||
socket.on('message-to-client', (messageObject) => { | ||
setMessages((prevMessages) => [...prevMessages, messageObject]); | ||
}); | ||
|
||
socket.emit('fetch-messages'); | ||
}); | ||
|
||
socket.on('connect_error', (error) => { | ||
throw error; | ||
}); | ||
|
||
return () => { | ||
socket.off('message-to-client'); | ||
socket.off('messages-to-client'); | ||
}; | ||
}, [accessToken, chatId, socket]); | ||
|
||
// 서버로 메시지 전송 | ||
const sendMessage = () => { | ||
if (newMessage.trim() !== '') { | ||
socket.emit('message-to-server', newMessage); | ||
setNewMessage(''); | ||
} | ||
}; | ||
|
||
// enter 입력 시 메시지 전송 | ||
const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => { | ||
if (e.key === 'Enter') { | ||
sendMessage(); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
<ChatHeader | ||
socket={socket} | ||
chatId={chatId} | ||
chatName={chatUsers.name} | ||
chatUsers={chatUsers.users.length} | ||
/> | ||
|
||
{privateValue === 'true' ? ( | ||
<> | ||
{chatUsers.users.length === 2 || chatUsers.users.length === 1 ? ( | ||
<> | ||
<p>1대1 채팅방 입니다.</p> | ||
<RenderChats | ||
messages={messages} | ||
chatUsers={chatUsers} | ||
useModal={false} | ||
/> | ||
</> | ||
) : ( | ||
<> | ||
<p> true 그룹 채팅방 입니다.</p> | ||
<RenderChats | ||
messages={messages} | ||
chatUsers={chatUsers} | ||
useModal={true} | ||
/> | ||
</> | ||
)} | ||
</> | ||
) : ( | ||
<> | ||
<p> false 오픈 채팅방 입니다. </p> | ||
<RenderChats | ||
messages={messages} | ||
chatUsers={chatUsers} | ||
useModal={false} | ||
/> | ||
</> | ||
)} | ||
|
||
<input | ||
type="text" | ||
value={newMessage} | ||
onChange={(e) => setNewMessage(e.target.value)} | ||
onKeyPress={handleKeyPress} | ||
/> | ||
<button onClick={sendMessage}>전송</button> | ||
</> | ||
); | ||
}; | ||
|
||
export default ChatRoom; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { useRouter } from 'next/navigation'; | ||
import Image from 'next/image'; | ||
import { Message, User } from '@/types'; | ||
|
||
const Chats = ({ | ||
message, | ||
user, | ||
myId, | ||
useModal, | ||
}: { | ||
message: Message; | ||
user: User; | ||
myId: string; | ||
useModal: boolean; | ||
}) => { | ||
const router = useRouter(); | ||
|
||
const openProfile = () => { | ||
router.push(`/profile/${user.id}?isMyProfile=false`); | ||
}; | ||
|
||
return ( | ||
<> | ||
{user.id === myId ? null : ( | ||
<> | ||
{useModal ? ( | ||
<Image | ||
src={user.picture} | ||
width={50} | ||
height={50} | ||
alt="User Picture" | ||
onClick={openProfile} | ||
/> | ||
) : ( | ||
<Image | ||
src={user.picture} | ||
width={50} | ||
height={50} | ||
alt="User Picture" | ||
/> | ||
)} | ||
</> | ||
)} | ||
<p>{user.username}</p> | ||
<p>{message.text}</p> | ||
</> | ||
); | ||
}; | ||
|
||
export default Chats; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { getCookie } from '@/Components/Login/Cookie'; | ||
import React, { useEffect, useRef } from 'react'; | ||
import { Chat, Message } from '@/types'; | ||
import Chats from '@/Components/Chat/Chats'; | ||
|
||
const RenderChats = ({ | ||
messages, | ||
chatUsers, | ||
useModal, | ||
}: { | ||
messages: Message[]; | ||
chatUsers: Chat; | ||
useModal: boolean; | ||
}) => { | ||
const myId = getCookie('userId'); | ||
const messageEndRef = useRef<HTMLDivElement>(null); | ||
|
||
// 새로운 메세지 전송시 하단 스크롤 | ||
useEffect(() => { | ||
const setTimeoutId = setTimeout(() => { | ||
if (messageEndRef.current) { | ||
messageEndRef.current.scrollIntoView({ behavior: 'smooth' }); | ||
} | ||
}, 500); | ||
|
||
return () => { | ||
clearTimeout(setTimeoutId); | ||
}; | ||
}, [messages.length]); | ||
|
||
return ( | ||
<> | ||
<ul> | ||
{messages.map((message, index) => { | ||
const myUser = chatUsers.users.find( | ||
(user) => user.id === message.userId, | ||
); | ||
|
||
if (myUser) { | ||
return ( | ||
<li | ||
key={message.id} | ||
className={ | ||
message.userId === myId ? 'bg-pink-500' : 'bg-pink-100' | ||
} | ||
> | ||
{index === 0 || | ||
new Date(message.createdAt).toDateString() !== | ||
new Date(messages[index - 1].createdAt).toDateString() ? ( | ||
<div className="h-[25px] bg-blue-300"> | ||
{new Date(message.createdAt).toDateString()} | ||
</div> | ||
) : null} | ||
|
||
<Chats | ||
key={message.id} | ||
message={message} | ||
user={myUser} | ||
myId={myId} | ||
useModal={useModal} | ||
/> | ||
</li> | ||
); | ||
} | ||
})} | ||
<div ref={messageEndRef}></div> | ||
</ul> | ||
</> | ||
); | ||
}; | ||
|
||
export default RenderChats; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.