+ {/* 마지막 메시지 내용 */}
{lastMessageContent}
+ {/* 읽지 않은 메시지 수 */}
{unreadMessageCount && unreadMessageCount > 0 ? (
{unreadMessageCount}
) : null}
@@ -55,13 +70,29 @@ const ChatItem = ({
// 채팅 리스트 메인 컴포넌트
const ChatList = () => {
const [searchTerm, setSearchTerm] = useState(''); // 검색어 상태
- const { data: chatData, isLoading } = useQuery({
- queryKey: ['chatList'],
- queryFn: fetchChatList,
- refetchOnWindowFocus: false,
- staleTime: 5 * 60 * 1000,
+ const {
+ data: chatData,
+ isLoading,
+ refetch,
+ } = useQuery({
+ queryKey: ['chatList'], // React Query 키
+ queryFn: fetchChatList, // 데이터를 가져오는 함수
+ refetchOnWindowFocus: true, // 창 포커스 시 자동 리페치
+ staleTime: 5 * 60 * 1000, // 캐시 데이터 유효 시간
});
+ const navigate = useNavigate();
+
+ // 채팅방 클릭 핸들러
+ const handleChatRoomClick = (chatRoomId: string, otherUserNickname: string) => {
+ console.log('ChatRoomId:', chatRoomId); // 확인
+ console.log('OtherUserNickname:', otherUserNickname); // 확인
+
+ navigate(`/chatroom/${chatRoomId}`, {
+ state: { otherUserNickname, refetchChatList: refetch }, // 닉네임 전달
+ });
+ };
+
// 검색어를 기준으로 채팅 리스트 필터링
const filteredChatData = Array.isArray(chatData)
? chatData.filter((chat) =>
@@ -69,23 +100,32 @@ const ChatList = () => {
)
: [];
+ // 검색어 입력 핸들러
const handleSearchChange = (value: string) => {
setSearchTerm(value); // 검색어 상태 업데이트
};
+ // 데이터 로딩 중 처리
if (isLoading) {
return
Loading...
;
}
return (
- {/* 검색 인풋 */}
+ {/* 상단 헤더 */}
+ {/* 검색 인풋 */}
{/* 채팅 리스트 */}
{filteredChatData.map((chat) => (
-
+
handleChatRoomClick(chat.chatRoomId, chat.otherUserNickname)} // 채팅방 클릭 이벤트 추가
+ >
+
+
))}
diff --git a/src/pages/ChatRoom/api/fetchChatRoom.tsx b/src/pages/ChatRoom/api/fetchChatRoom.tsx
index 96af742..b43d196 100644
--- a/src/pages/ChatRoom/api/fetchChatRoom.tsx
+++ b/src/pages/ChatRoom/api/fetchChatRoom.tsx
@@ -17,3 +17,16 @@ export const fetchMessages = async (chatRoomId: string): Promise
return [];
}
};
+
+export const markAsRead = async (chatRoomId: string): Promise => {
+ try {
+ const response = await apiClient.put(`/chats/${chatRoomId}/markasread`);
+ if (response.status === 200) {
+ console.log('읽음 처리 완료');
+ } else {
+ console.error('읽음 처리 실패', response);
+ }
+ } catch (error) {
+ console.error('읽음 처리 중 오류 발생:', error);
+ }
+};
diff --git a/src/pages/ChatRoom/api/socket.ts b/src/pages/ChatRoom/api/socket.ts
index a7fb51f..b2acffe 100644
--- a/src/pages/ChatRoom/api/socket.ts
+++ b/src/pages/ChatRoom/api/socket.ts
@@ -5,33 +5,22 @@ const SOCKET_URL = 'wss://q-feed.n-e.kr/ws';
// STOMP 클라이언트 생성
export const stompClient = new Client({
- brokerURL: SOCKET_URL, // WebSocket URL
- reconnectDelay: 5000, // 재연결 대기 시간 (ms)
+ brokerURL: SOCKET_URL,
+ reconnectDelay: 5000,
debug: (str) => {
console.log('STOMP Debug:', str);
},
connectHeaders: {
- Authorization: 'Token', // 토큰 인증 (필요한 경우)
+ Authorization: 'Bearer token',
},
});
-// STOMP 연결 함수
export const connectStomp = () => {
- stompClient.onConnect = (frame) => {
- console.log('STOMP 연결 성공:', frame);
- };
-
- stompClient.onStompError = (frame) => {
- console.error('STOMP 에러:', frame.headers['message']);
- };
-
- stompClient.activate(); // STOMP 활성화
+ stompClient.activate();
};
-// STOMP 연결 해제 함수
export const disconnectStomp = () => {
if (stompClient.active) {
stompClient.deactivate();
- console.log('STOMP 연결 해제');
}
};
diff --git a/src/pages/ChatRoom/component/InputBar.tsx b/src/pages/ChatRoom/component/InputBar.tsx
index 1a9da8d..b76f89e 100644
--- a/src/pages/ChatRoom/component/InputBar.tsx
+++ b/src/pages/ChatRoom/component/InputBar.tsx
@@ -1,14 +1,15 @@
/** @jsxImportSource @emotion/react */
import {
- iconButtonStyle,
- iconStyle,
+ /* iconButtonStyle, */
+ /* iconStyle, */
inputContainerStyle,
inputStyle,
inputWrap,
sendButtonStyle,
} from '@/pages/ChatRoom/component/InputBar.styles';
import { useState } from 'react';
-import { MdOutlineAddAPhoto } from 'react-icons/md';
+
+/* import { MdOutlineAddAPhoto } from 'react-icons/md'; */
import { SendButton } from '@/components/ui/SendButton/SendButton';
interface InputBarProps {
@@ -54,9 +55,9 @@ const ChatInputBar: React.FC = ({
{/* 카메라 아이콘 */}
-
+ {/*
*/}
{/* 텍스트 입력 */}
{
const { id: chatRoomId } = useParams<{ id: string }>();
const navigate = useNavigate();
+ const location = useLocation();
+ const refetchChatList = location.state?.refetchChatList;
+ const otherUserNickname = location.state?.otherUserNickname || "채팅방"; // 기본값 설정
const [isNotificationEnabled, setIsNotificationEnabled] = useState(true);
- const [messages, setMessages] = useState
([]); // 메시지 상태 관리
+ const [messages, setMessages] = useState([]);
const messagesEndRef = useRef(null);
+ const myId = '83974189-a749-4a24-bd5a-8ca2577fac73';
+ const messagesContainerRef = useRef(null); // 메시지 컨테이너 참조 추가
- const toggleNotification = () => {
- setIsNotificationEnabled((prevState) => !prevState);
+ console.log('Location State:', location.state); // 전체 state 확인
+ console.log('Other User Nickname:', otherUserNickname); // 닉네임 확인
+
+ // 뒤로가기 시 채팅 리스트 새로고침
+ const handleBack = () => {
+ if (refetchChatList) refetchChatList();
+ navigate(-1);
};
- useEffect(() => {
- if (messagesEndRef.current) {
- messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
- }
- }, [messages]);
- useEffect(() => {
+ // 읽음 처리
+ const handleMarkAsRead = useCallback(async () => {
if (!chatRoomId) return;
-
- // 초기 메시지 로드
- const fetchInitialMessages = async () => {
- try {
- const response = await fetch(`/api/chats/${chatRoomId}/messages`, {
- headers: {
- Authorization: 'Token', // Postman에서 사용한 토큰
- },
- });
-
- if (response.ok) {
- const data: MessageType[] = await response.json();
- setMessages(data);
- console.log('초기 메시지 로드:', data);
- } else {
- console.error('초기 메시지 로드 실패:', response.status, await response.text());
- }
- } catch (error) {
- console.error('초기 메시지 로드 중 오류:', error);
- }
- };
-
- fetchInitialMessages();
-
- // STOMP 연결 설정
- connectStomp();
-
- stompClient.onConnect = () => {
- console.log(`STOMP 연결 성공 (ChatRoom ID: ${chatRoomId})`);
- const subscription = stompClient.subscribe(`/sub/chat/${chatRoomId}`, (message) => {
- const receivedMessage: MessageType = JSON.parse(message.body);
- setMessages((prevMessages) => [...prevMessages, receivedMessage]); // 실시간 메시지 추가
- console.log('새 메시지:', receivedMessage);
+ try {
+ await markAsRead(chatRoomId);
+ console.log('읽음 처리 완료');
+ } catch (error) {
+ console.error('읽음 처리 중 오류:', error);
+ }
+ }, [chatRoomId]);
+ // 메시지 불러오기 함수
+ const fetchInitialMessages = useCallback(async () => {
+ try {
+ const response = await fetch(`/api/chats/${chatRoomId}/messages`, {
+ headers: {
+ Authorization:
+ 'Bearer token',
+ },
});
- return () => subscription.unsubscribe();
- };
-
- stompClient.onStompError = (error) => {
- console.error('STOMP 연결 에러:', error);
- };
-
- return () => {
- disconnectStomp();
- };
+ if (response.ok) {
+ const data: MessageType[] = await response.json();
+ const sortedData = [...data].sort(
+ (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
+ );
+ setMessages(sortedData);
+
+ // 스크롤을 가장 아래로 이동
+ setTimeout(() => {
+ if (messagesContainerRef.current) {
+ messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
+ }
+ }, 0);
+ } else {
+ console.error('초기 메시지 로드 실패:', response.status, await response.text());
+ }
+ } catch (error) {
+ console.error('초기 메시지 로드 중 오류:', error);
+ }
}, [chatRoomId]);
+ // 메시지 전송 함수
const handleSendMessage = (message: string) => {
if (!chatRoomId) return;
const payload = {
roomId: Number(chatRoomId),
- senderId: '83974189-a749-4a24-bd5a-8ca2577fac73', // 본인 ID
- message, // 메시지 내용
+ senderId: myId,
+ message,
};
stompClient.publish({
destination: `/pub/chat/message`,
body: JSON.stringify(payload),
});
-
console.log('메시지 전송:', payload);
};
+ useEffect(() => {
+ if (!chatRoomId) return;
+
+ fetchInitialMessages(); // 초기 메시지 로드
+ handleMarkAsRead(); // 읽음 처리
+
+ // STOMP 설정
+ connectStomp();
+ stompClient.onConnect = () => {
+ console.log(`STOMP 연결 성공 (ChatRoom ID: ${chatRoomId})`);
+
+ const subscription = stompClient.subscribe(`/sub/chat/${chatRoomId}`, (message) => {
+ try {
+ const receivedMessage: MessageType = JSON.parse(message.body);
+
+ setMessages((prevMessages) => {
+ const updatedMessages = [
+ ...prevMessages,
+ { ...receivedMessage, isMine: receivedMessage.senderId === myId },
+ ];
+ return updatedMessages.sort(
+ (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
+ );
+ });
+
+ setTimeout(() => {
+ messagesEndRef.current?.scrollIntoView({ behavior: 'instant' });
+ }, 0);
+ } catch (error) {
+ console.error('메시지 파싱 오류:', error);
+ }
+ });
+
+ return () => subscription.unsubscribe();
+ };
+
+ return () => disconnectStomp();
+ }, [chatRoomId, fetchInitialMessages, handleMarkAsRead]);
+
+ useEffect(() => {
+ // 메시지가 업데이트될 때 스크롤 즉시 맨 아래로 이동
+ if (messagesContainerRef.current) {
+ messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
+ }
+ }, [messages]);
+
return (
- navigate(-1)} />
- 채팅방 ID: {chatRoomId}
-
-
-
+
+
+
+
+
);
};
diff --git a/src/pages/ChatRoom/styles.ts b/src/pages/ChatRoom/styles.ts
index 36168ee..e4d58b9 100644
--- a/src/pages/ChatRoom/styles.ts
+++ b/src/pages/ChatRoom/styles.ts
@@ -41,7 +41,11 @@ export const messageListStyle = css`
overflow-y: auto;
background-color: ${theme.colors.background};
`;
-
+/* export const messageContainerStyle = css`
+ flex: 1;
+ overflow-y: 'auto';
+ background-color: ${theme.colors .background};
+`; */
export const otherMessageStyle = css`
display: flex;
align-items: flex-start;
diff --git a/src/pages/ChatRoom/type/messageType.tsx b/src/pages/ChatRoom/type/messageType.tsx
index cbc7f7f..345cb44 100644
--- a/src/pages/ChatRoom/type/messageType.tsx
+++ b/src/pages/ChatRoom/type/messageType.tsx
@@ -9,4 +9,5 @@ export interface MessageType {
userNickName: string;
userProfileImage: string;
isMine: boolean;
+ senderId: string;
}