diff --git a/src/components/Chat/ChatContainer/index.tsx b/src/components/Chat/ChatContainer/index.tsx index 07d3014..fc1073d 100644 --- a/src/components/Chat/ChatContainer/index.tsx +++ b/src/components/Chat/ChatContainer/index.tsx @@ -4,13 +4,20 @@ import ChatZone from '../ChatZone'; import Textarea from '../Textarea'; import useSocket from '../../../hooks/useSocket'; import { getChatData, newChatData } from '../../../utils/ChatSocketData'; -import { getAllMessages, getChatDataSelector, sendMessages } from '../../../reducer/chat'; +import { + changeRoom, + deleteMessage, + editMessage, + getAllMessages, + getChatDataSelector, + sendMessage, +} from '../../../reducer/chat'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, useParams } from 'react-router'; import { Scrollbars } from 'react-custom-scrollbars'; -import { AllMessagesDataType, ChatDataType, ChatIdType, ChatUpdateDataType } from '../../../types/types'; +import { AllMessagesDataType, ChatDataType, ChatUpdateDataType } from '../../../types/types'; const WorkSpaceChat = (): JSX.Element => { const profileInfo = useSelector(getProfileInfoSelector); @@ -27,9 +34,6 @@ const WorkSpaceChat = (): JSX.Element => { const [isEnd, setIsEnd] = useState(false); const [chat, setChat] = useState(''); - // TODO: 채팅기록을 담아줄 바구니 - const [chatBucket, setChatBucket] = useState([]); - // TODO: 해당하는 채팅 Room과 연결 시도 connectionSocket(); @@ -51,7 +55,7 @@ const WorkSpaceChat = (): JSX.Element => { setIsEnd(isEnd); dispatch(getAllMessages(chats)); }); - }, [chatData]); + }, []); useEffect(() => { // TODO: room이 바뀌면 room과 다시 연결한다. @@ -63,44 +67,33 @@ const WorkSpaceChat = (): JSX.Element => { useEffect(() => { // TODO: room이 바뀌면 인피니티 스크롤을 위한 order 초기화 setOrder(0); - setChatBucket([]); + dispatch(changeRoom()); }, [room]); useEffect(() => { // TODO: 메세지를 받으면 재렌더링 한다. socket?.on('sendMessage', (chat: ChatDataType) => { if (chat) { - dispatch(sendMessages([chat])); - } - }); - - // TODO: 채팅 고유 아이디 - socket?.on('nowMessageId', ({ id, chatLength }: ChatIdType) => { - if (chatBucket[chatLength]) { - chatBucket[chatLength].id = id; + dispatch(sendMessage([chat])); } }); // TODO: 채팅 수정 socket?.on('editMessage', ({ chat, index }: ChatDataType) => { - const copyChatBucket = [...chatBucket]; if (chat) { - copyChatBucket.splice(index, 1, chat); - setChatBucket([...copyChatBucket]); + dispatch(editMessage({ chat, index })); } }); // TODO: 채팅 삭제 socket?.on('deleteMessage', ({ index }) => { - const copyChatBucket = [...chatBucket]; - copyChatBucket.splice(index, 1); - setChatBucket([...copyChatBucket]); + dispatch(deleteMessage(index)); }); // TODO: 채팅 이미지 업로드 socket?.on('sendImage', ({ chat }: ChatDataType) => { if (chat?.uploadImage) { - dispatch(sendMessages([chat])); + dispatch(sendMessage([chat])); } }); }, [chatData]); @@ -126,7 +119,7 @@ const WorkSpaceChat = (): JSX.Element => { socket?.emit('sendMessage', data); if (chat) { - dispatch(sendMessages([newChat])); + dispatch(sendMessage([newChat])); setChat(''); } diff --git a/src/components/Chat/ChatItem/index.tsx b/src/components/Chat/ChatItem/index.tsx index eb7e956..1ca6d02 100644 --- a/src/components/Chat/ChatItem/index.tsx +++ b/src/components/Chat/ChatItem/index.tsx @@ -5,13 +5,13 @@ import DeleteAlert from '../DeleteAlert'; import useInput from '../../../hooks/useInput'; import { getProfileInfoSelector } from '../../../reducer/profile'; import { getChatDeleteData, getChatEditData, newChatData } from '../../../utils/ChatSocketData'; -import { getChatDataSelector } from '../../../reducer/chat'; +import { deleteMessage, editMessage, getChatDataSelector } from '../../../reducer/chat'; import { Socket } from 'socket.io-client'; import dayjs from 'dayjs'; import autosize from 'autosize'; import { useParams } from 'react-router'; -import { useSelector } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { ChatContent, @@ -43,6 +43,7 @@ interface Props { const ChatItem = ({ socket, data, isSameSender, index }: Props): JSX.Element => { const profileInfo = useSelector(getProfileInfoSelector); const chatData = useSelector(getChatDataSelector); + const dispatch = useDispatch(); const { part: room } = useParams<{ projectUrl: string; part: string }>(); const textareaRef = useRef(null); @@ -68,11 +69,11 @@ const ChatItem = ({ socket, data, isSameSender, index }: Props): JSX.Element => // TODO: 채팅 수정 엔터 const onChatEditEnter = useCallback((): void => { const getChatEdit: ChatUpdateDataType = getChatEditData(room, index, data.id, editChat); - const newChat: ChatDataType = newChatData(data.id, editChat, '', room, profileInfo); + const chat: ChatDataType = newChatData(data.id, editChat, '', room, profileInfo); - const copyChatBucket = [...chatData]; - copyChatBucket.splice(index, 1, newChat); - // setChatBucket([...copyChatBucket]); + if (editChat) { + dispatch(editMessage({ chat, index })); + } socket?.emit('editMessage', getChatEdit); setShowChatEditForm(false); @@ -84,11 +85,11 @@ const ChatItem = ({ socket, data, isSameSender, index }: Props): JSX.Element => e.preventDefault(); const getChatEdit: ChatUpdateDataType = getChatEditData(room, index, data.id, editChat); - const newChat: ChatDataType = newChatData(data.id, editChat, '', room, profileInfo); + const chat: ChatDataType = newChatData(data.id, editChat, '', room, profileInfo); - const copyChatBucket = [...chatData]; - copyChatBucket[index] = newChat; - // setChatBucket([...copyChatBucket]); + if (editChat) { + dispatch(editMessage({ chat, index })); + } socket?.emit('editMessage', getChatEdit); setShowChatEditForm(false); @@ -113,9 +114,8 @@ const ChatItem = ({ socket, data, isSameSender, index }: Props): JSX.Element => setShowChatDeleteAlert(false); const getChatDelete = getChatDeleteData(room, index, data.id); - const copyChatBucket = [...chatData]; - copyChatBucket.splice(index, 1); - // setChatBucket([...copyChatBucket]); + dispatch(deleteMessage(index)); + socket?.emit('deleteMessage', getChatDelete); }, [chatData], diff --git a/src/components/Chat/ChatZone/index.tsx b/src/components/Chat/ChatZone/index.tsx index b2eb24b..6191f5a 100644 --- a/src/components/Chat/ChatZone/index.tsx +++ b/src/components/Chat/ChatZone/index.tsx @@ -5,7 +5,7 @@ import { getProfileInfoSelector } from '../../../reducer/profile'; import { getChatUploadImageData, newChatData } from '../../../utils/ChatSocketData'; import DragUploadModal from '../DragUploadModal'; import { chatSection } from '../../../utils/chatSection'; -import { getChatDataSelector, sendMessages } from '../../../reducer/chat'; +import { getChatDataSelector, sendMessage } from '../../../reducer/chat'; import { Socket } from 'socket.io-client'; import { Scrollbars } from 'react-custom-scrollbars'; @@ -61,7 +61,7 @@ const ChatZone = ({ socket, scrollbarRef, order, setOrder, isEnd }: Props): JSX. const newChat: ChatDataType = newChatData(-1, '', chatUploadImage, room, profileInfo); const getImageData: ChatUpdateDataType = getChatUploadImageData(room, profileInfo, chatUploadImage); - dispatch(sendMessages([newChat])); + dispatch(sendMessage([newChat])); socket?.emit('sendImage', getImageData); } }, [chatUploadImage]); diff --git a/src/components/Chat/Textarea/index.tsx b/src/components/Chat/Textarea/index.tsx index ef20b8e..8a3f347 100644 --- a/src/components/Chat/Textarea/index.tsx +++ b/src/components/Chat/Textarea/index.tsx @@ -2,7 +2,7 @@ import React, { useCallback, KeyboardEvent, FormEvent, useRef, useEffect, useSta import { changeImage, clickUploadImage } from '../../../utils/imageUpload'; import { getProfileInfoSelector } from '../../../reducer/profile'; import { getChatUploadImageData, newChatData } from '../../../utils/ChatSocketData'; -import { getChatDataSelector, sendMessages } from '../../../reducer/chat'; +import { getChatDataSelector, sendMessage } from '../../../reducer/chat'; import { Socket } from 'socket.io-client'; import autosize from 'autosize'; @@ -75,10 +75,10 @@ const Textarea = ({ socket, onSubmitForm, onChangeChat, chat }: Props): JSX.Elem const newChat: ChatDataType = newChatData(-1, '', chatUploadImage, room, profileInfo); const getImageData: ChatUpdateDataType = getChatUploadImageData(room, profileInfo, chatUploadImage); + dispatch(sendMessage([newChat])); socket?.emit('sendImage', getImageData); - dispatch(sendMessages([newChat])); } - }, [chatUploadImage, chatData]); + }, [chatUploadImage]); return ( diff --git a/src/reducer/chat.ts b/src/reducer/chat.ts index bbfb9ad..1dae398 100644 --- a/src/reducer/chat.ts +++ b/src/reducer/chat.ts @@ -1,7 +1,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { RootStateOrAny } from 'react-redux'; -import { ChatDataType } from '../types/types'; +import { ChatDataType, editChatType } from '../types/types'; // TODO: 초기 상태 const initialState: ChatDataType[] = [ @@ -43,12 +43,25 @@ export const chatSlice = createSlice({ getAllMessages: (state, { payload }: PayloadAction) => { return [...payload, ...state]; }, - sendMessages: (state, { payload }: PayloadAction) => { + sendMessage: (state, { payload }: PayloadAction) => { return [...state, ...payload]; }, + deleteMessage: (state, { payload }: PayloadAction) => { + const copyState = [...state]; + copyState.splice(payload, 1); + return [...copyState]; + }, + editMessage: (state, { payload }: PayloadAction) => { + const copyState = [...state]; + if (payload.chat) { + copyState.splice(payload.index, 1, payload.chat); + } + return [...copyState]; + }, + changeRoom: () => initialState, }, }); -export const { getAllMessages, sendMessages } = chatSlice.actions; +export const { getAllMessages, sendMessage, deleteMessage, editMessage, changeRoom } = chatSlice.actions; export const getChatDataSelector = (state: RootStateOrAny): ChatDataType[] => state.chatSlice; diff --git a/src/types/types.ts b/src/types/types.ts index 91c53ec..06332df 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -306,9 +306,9 @@ export interface ChatUpdateDataType { uploadImage?: string; } -export interface ChatIdType { - id: number; - chatLength: number; +export interface editChatType { + chat: ChatDataType; + index: number; } ////////////////////////////////////////////////////////