diff --git a/.babelrc b/.babelrc index ec29cf4..28b1125 100644 --- a/.babelrc +++ b/.babelrc @@ -1,8 +1,5 @@ { - "presets": [ - "@babel/preset-env", - "@babel/preset-react" - ], + "presets": ["@babel/preset-env", "@babel/preset-react"], "plugins": [ "@babel/plugin-transform-runtime", [ @@ -15,9 +12,10 @@ "@styles": "./src/styles", "@views": "./src/views", "@utils": "./src/utils", - "@components": "./src/components" + "@components": "./src/components", + "@hooks": "./src/hooks" } } ] ] -} \ No newline at end of file +} diff --git a/package.json b/package.json index c92f73c..70a2f96 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "recoil": "^0.1.3", "sass": "^1.32.8", "sass-loader": "^11.0.1", - "socket.io-client": "2.3.1", + "socket.io-client": "^4.1.3", "style-loader": "^2.0.0", "swr": "^0.5.6", "uuid": "3.4.0", diff --git a/src/App.jsx b/src/App.jsx index 04277da..f94ccec 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -27,8 +27,8 @@ function App() { - - + + diff --git a/src/hooks/useInput.js b/src/hooks/useInput.js new file mode 100644 index 0000000..2407521 --- /dev/null +++ b/src/hooks/useInput.js @@ -0,0 +1,12 @@ +import { useCallback, useState } from 'react'; + +const useInput = initialData => { + const [value, setValue] = useState(initialData); + + const handler = useCallback(e => { + setValue(e.target.value); + }, []); + return [value, handler, setValue]; +}; + +export default useInput; diff --git a/src/states/Chatroom.js b/src/states/Chatroom.js index 8fe7692..fc35e05 100644 --- a/src/states/Chatroom.js +++ b/src/states/Chatroom.js @@ -1,10 +1,30 @@ -import { atom } from 'recoil'; +import { atom, selectorFamily } from 'recoil'; +import { API_FIND_CHATROOM, API_GET_MESSAGES, requestAPI } from '../utils/api'; const chatroomState = atom({ key: 'chatroomList', - default: [] + default: [], }); -export { - chatroomState, -}; +const messagesState = atom({ + key: 'messageList', + default: [], +}); + +const emptyMsg = atom({ + key: 'emptyMsg', + default: null, +}); + +const currentChatRoom = selectorFamily({ + key: 'currentChatRoom', + get: chatRoomId => async () => { + const { data: chatRoom } = await requestAPI(API_FIND_CHATROOM().setPathParam(chatRoomId)); + const { data: messages } = await requestAPI( + API_GET_MESSAGES().setQuery({ chatRoomId, start: 0, end: 10 }), + ); + return { chatRoom, messages }; + }, +}); + +export { messagesState, chatroomState, emptyMsg, currentChatRoom }; diff --git a/src/utils/api.js b/src/utils/api.js index 4628574..8952681 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -66,7 +66,7 @@ export const API_UPDATE_LECTURES = makeAPI(PATCH, '/lecture'); export const API_GET_HISTORIES = makeAPI(GET, '/history'); const axiosInstance = axios.create({ - baseURL: 'http://localhost:2021/api', + baseURL: `${API_URL_BASE}/api`, timeout: 20000, }); diff --git a/src/views/chat/chatMessage.jsx b/src/views/chat/chatMessage.jsx index 2b842f7..d1bb26f 100644 --- a/src/views/chat/chatMessage.jsx +++ b/src/views/chat/chatMessage.jsx @@ -84,10 +84,10 @@ const useStyles = makeStyles({ margin: '0px 1px 0px 1px', }, content: { - maxWidth: '90%', - fontSize: '0.9rem', + maxWidth: '40%', + fontSize: '1.1rem', margin: '0px 1px 0px 1px', - padding: '0px 6px 0px 6px', + padding: '5px 10px', borderRadius: '5px', }, from: { diff --git a/src/views/chat/chatroom.jsx b/src/views/chat/chatroom.jsx index 8a4e865..7c947cf 100644 --- a/src/views/chat/chatroom.jsx +++ b/src/views/chat/chatroom.jsx @@ -1,31 +1,38 @@ import React, { useEffect, useRef, useState } from 'react'; import ContentEditable from 'react-contenteditable'; -import { Menu, MenuItem, Button, Container, makeStyles, Typography } from '@material-ui/core'; +import { Button, Container, makeStyles, Typography } from '@material-ui/core'; import IconButton from '@material-ui/core/IconButton'; import MoreVertIcon from '@material-ui/icons/MoreVert'; import ExitToAppIcon from '@material-ui/icons/ExitToApp'; +import { Redirect, useHistory, useParams } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; +import useInput from '@hooks/useInput'; import { v4 as uuidv4 } from 'uuid'; -import { API_FIND_CHATROOM, API_GET_MESSAGES, API_GET_POINTS, requestAPI } from '../../utils/api'; +import usersIcon from '@img/fontawesome/chat-users.svg'; +import userIcon from '@img/fontawesome/chat-user.svg'; import { StatusCodes } from 'http-status-codes'; +import { uosYellow } from '@utils/styles/Colors'; import ChatMessage from './chatMessage'; +import { API_GET_MESSAGES, requestAPI } from '../../utils/api'; import { getSocket } from '../../utils/socket'; -import { Redirect, useHistory } from 'react-router'; -import { uosYellow } from '@utils/styles/Colors'; import UserInfoDialog from '../../components/UserInfoDialog'; -import userIcon from '@img/fontawesome/chat-user.svg'; -import usersIcon from '@img/fontawesome/chat-users.svg'; import RoomInfoMenu from './RoomInfoMenu'; import MainMenu from './MainMenu'; +import { currentChatRoom } from '../../states/Chatroom'; -export default function Chatroom({ id }) { - const [chatRoom, setChatRoom] = useState({}); - const [messages, setMessages] = useState([]); +export default function Chatroom() { + const { chatRoomId } = useParams(); + const { chatRoom: initChatRoom, messages: initMessages } = useRecoilValue( + currentChatRoom(chatRoomId), + ); + const [messages, setMessages] = useState(initMessages); + const [chatRoom, setChatRoom] = useState(initChatRoom); const [readPoints, setReadPoints] = useState([]); const [emptyMsg, setEmptyMsg] = useState(''); const [infoOpen, setInfoOpen] = useState(false); const [menuAnchorEl, setMenuAnchorEl] = useState(null); const [infoAnchorEl, setInfoAnchorEl] = useState(null); - const [input, setInput] = useState(''); + const [input, handleInput, setInput] = useInput(''); const classes = useStyles(); @@ -47,7 +54,6 @@ export default function Chatroom({ id }) { if (!userId) { return ; } - const chatRoomId = id; const socket = getSocket(); const menuOption = ['채팅방 이름 변경', '참여자 목록', '채팅방 나가기']; const loadUnit = 100; @@ -77,8 +83,8 @@ export default function Chatroom({ id }) { messageRef.current = newMessages; socket.emit('read', { - chatRoomId: chatRoomId, - userId: userId, + chatRoomId, + userId, messageIdx: range.current.end, }); }; @@ -115,64 +121,11 @@ export default function Chatroom({ id }) { socket.on('message', onMessageEvent); socket.on('read', onReadEvent); - const getChatRoom = async chatRoomId => { - const response = await requestAPI(API_FIND_CHATROOM().setPathParam(chatRoomId)); - - if (response.status !== StatusCodes.OK) { - setEmptyMsg('데이터를 불러오는데 실패했습니다.'); - - history.push('/chatrooms'); - - throw new Error(); - } - - setChatRoom(response.data); - chatRoomRef.current = response.data; - - return response.data; - }; - - const getMessages = async (chatRoomId, start, end) => { - if (end < 0) return; - - const response = await requestAPI(API_GET_MESSAGES().setQuery({ chatRoomId, start, end })); - - if (response.status !== StatusCodes.OK) { - setEmptyMsg('채팅을 불러오는데 실패했습니다.'); - return; - } - setMessages(response.data); - messageRef.current = response.data; - }; - - const getReadPoints = async chatRoomId => { - const response = await requestAPI(API_GET_POINTS().setQuery({ chatRoomId })); - - if (response.status !== StatusCodes.OK) { - setEmptyMsg('데이터를 불러오는데 실패했습니다.'); - return; - } - setReadPoints(response.data); - readPointRef.current = response.data; - }; - - getChatRoom(chatRoomId) - .then(room => { - const start = room.length > loadUnit ? room.length - loadUnit : 0; - const end = room.length > 0 ? room.length - 1 : 0; - - range.current = { start, end }; - - getMessages(chatRoomId, start, end); - getReadPoints(chatRoomId); - - socket.emit('read', { - chatRoomId: chatRoomId, - userId: userId, - messageIdx: range.current.end, - }); - }) - .catch(() => {}); + socket.emit('read', { + chatRoomId, + userId, + messageIdx: 10, + }); return () => { socket.off('read'); @@ -186,10 +139,6 @@ export default function Chatroom({ id }) { document.execCommand('insertText', false, text); }; - const onChange = e => { - setInput(e.target.value); - }; - const onEnterPress = e => { if (e.key === 'Enter') { e.preventDefault(); @@ -208,7 +157,6 @@ export default function Chatroom({ id }) { type: 'normal', content: input, }; - socket.emit('message', messageEvent); const newMessages = messageRef.current.concat(messageEvent); @@ -348,7 +296,7 @@ export default function Chatroom({ id }) { tagName="div" html={input} onPaste={onPaste} - onChange={onChange} + onChange={handleInput} onKeyPress={onEnterPress} />