diff --git a/src/components/Game/GameChat/index.tsx b/src/components/Game/GameChat/index.tsx index 8cd19f3e..391e9a12 100644 --- a/src/components/Game/GameChat/index.tsx +++ b/src/components/Game/GameChat/index.tsx @@ -1,5 +1,95 @@ -const GameChat = () => { - return
game chat
; +import { + Button, + Card, + CardBody, + Input, + InputGroup, + InputRightElement, +} from "@chakra-ui/react"; +import { useEffect, useState } from "react"; +import { io } from "socket.io-client"; +import useInput from "../../../hooks/useInput"; +import ChatBubble from "../../common/ChatBubble"; + +interface Message { + id: string; + text: string; +} +const GameChat = ({ gameId }) => { + console.log(gameId); + const token = JSON.parse(localStorage.getItem("token") as string); + + const socket = io(`https://fastcampus-chat.net/chat?chatId=${gameId}`, { + extraHeaders: { + Authorization: `Bearer ${token.accessToken}`, + serverId: import.meta.env.VITE_APP_SERVER_ID, + }, + }); + + // 메세지 데이터 + const [message, setMessage] = useState({ + id: "", + text: "", + }); + const [messages, setMessages]: any = useState([]); + const messageValue = useInput(""); + + useEffect(() => { + socket.on("message-to-client", (messageObject) => { + // 메시지 데이터, 작성 유저 상태 저장 + const copy = { ...message }; + copy.id = messageObject.userId; + copy.text = messageObject.text; + setMessage(copy); + }); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [socket]); + + // 메시지 값 변화시(소켓 통신 시) 콘솔에 메시지 데이터 출력 + useEffect(() => { + if (message.id !== "") { + console.log(message); + setMessages([...messages, message]); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [message.text]); + + const submitMessage = () => { + socket.emit("message-to-server", messageValue.value); + messageValue.clear(); + }; + + const handleKeyPress = (event: React.KeyboardEvent) => { + if (event.key === "Enter") { + submitMessage(); + } + }; + + return ( + + + {messages.map((message, index) => ( + + ))} + + + + + + + + + ); }; export default GameChat; diff --git a/src/components/Main/CreateGameModal/index.tsx b/src/components/Main/CreateGameModal/index.tsx index 4ffb3da5..b1121208 100644 --- a/src/components/Main/CreateGameModal/index.tsx +++ b/src/components/Main/CreateGameModal/index.tsx @@ -2,12 +2,13 @@ import { Button, Input } from "@chakra-ui/react"; import { serverTimestamp } from "firebase/firestore"; import { ChangeEvent, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; -import { io } from "socket.io-client"; +// import { io } from "socket.io-client"; import styled from "styled-components"; import useFetch from "../../../hooks/useFetch"; import useFireFetch from "../../../hooks/useFireFetch"; import useInput from "../../../hooks/useInput"; import UserCard from "../../common/UserCard"; +import useSocket from "../../../hooks/useSocket"; const Container = styled.div` position: absolute; @@ -31,10 +32,10 @@ const Wrap = styled.div` width: 45rem; height: 30rem; - background-color: #fff; - display: flex; + background-color: #fff; + & > div:first-child { padding: 3rem 1.5rem 3rem 5rem; } @@ -132,39 +133,50 @@ interface ChatRoom { status?: string; } +interface UserType { + id: string; + name: string; + picture: string; +} + interface Props { setModal: React.Dispatch>; } const CreateGameModal = ({ setModal }: Props) => { const navigate = useNavigate(); + const fireFetch = useFireFetch(); const token = JSON.parse(localStorage.getItem("token") as string); - const socket = io( - `https://fastcampus-chat.net/chat?chatId=9fe8a1af-9c60-4937-82dd-21d6da5b9cd9`, - { - extraHeaders: { - Authorization: `Bearer ${token.accessToken}`, - serverId: import.meta.env.VITE_APP_SERVER_ID, - }, - }, - ); + // 소켓 연결 + const sendMessage = useSocket("9fe8a1af-9c60-4937-82dd-21d6da5b9cd9"); - const fireFetch = useFireFetch(); + // 게임 데이터 const [roomData, setRoomData] = useState({ name: "", users: [], isPrivate: false, - num: 1, + num: 6, }); + // 방제목 빈값이면 true + const [inputAction, setInpuAction] = useState(false); + + const [userList, setUserList] = useState([]); + + // input 초기화 + const titleInput = useInput(""); + const searchInput = useInput(""); + + // 유저정보 요청 const users = useFetch({ url: "https://fastcampus-chat.net/users", method: "GET", start: true, }); + // 게임 만들기 post요청 선언 (호출 X) const createGame = useFetch({ url: "https://fastcampus-chat.net/chat", method: "POST", @@ -175,21 +187,46 @@ const CreateGameModal = ({ setModal }: Props) => { start: false, }); - const titleInput = useInput(""); + useEffect(() => { + if (users.result) { + const filter = users.result.filter( + (value: UserType) => value.id !== token.id, + ); + setUserList(filter); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [users.result]); + // 방제목 input 저장 useEffect(() => { const copy = { ...roomData }; copy.name = titleInput.value; setRoomData(copy); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [titleInput.value, titleInput.value]); + }, [titleInput.value]); - const handleMakeRoom = () => { - createGame.refresh(); + // 유저 검색 기능 + useEffect(() => { + if (users.result) { + const filter = users.result.filter((value: UserType) => + value.name.includes(searchInput.value), + ); + setUserList(filter); + } + }, [searchInput.value, users.result]); - console.log(roomData); + // 게임 생성 함수 + const handleMakeRoom = () => { + if (roomData.name === "") { + setInpuAction(true); + console.log(roomData); + } else { + // 게임 생성 POST 호출 + createGame.refresh(); + } }; + // 게임 인원 선택 함수 const handleRadioChange = (e: ChangeEvent) => { const copy = { ...roomData }; copy.num = ~~e.target.value; @@ -197,8 +234,10 @@ const CreateGameModal = ({ setModal }: Props) => { setRoomData(copy); }; + // 게임 생성 후 파이어베이스 저장 밑 유저 초대 푸쉬알림 useEffect(() => { if (createGame.result) { + // 파이어베이스 게임 데이터 생성 const newData = { ...roomData, id: createGame.result.id, @@ -208,20 +247,21 @@ const CreateGameModal = ({ setModal }: Props) => { status: "대기중", }; + // 파이어베이스 POST요청 fireFetch.usePostData("game", createGame.result.id, newData); - // const roomText = [...JSON.stringify(newData)]; - + // 초대된 유저 목록 생성 const inviteUser: (string | ChatRoom | string[])[] = [...roomData.users]; inviteUser.push(newData); inviteUser.push("*&^"); - // const text = inviteUser.toString(); const text = JSON.stringify(inviteUser); - socket.emit("message-to-server", text); + // 초대 메시지 전달 + sendMessage(text); + // 해당 게임방으로 이동 navigate(`/game?gameId=${createGame.result.id}`); } // eslint-disable-next-line react-hooks/exhaustive-deps @@ -235,7 +275,7 @@ const CreateGameModal = ({ setModal }: Props) => { { id="1" name="drone" value="1" - defaultChecked + checked={roomData.num === 1} onChange={handleRadioChange} /> @@ -330,14 +370,19 @@ const CreateGameModal = ({ setModal }: Props) => {
- +
+ +
{users.result && - users.result.map((value: any) => { + userList.map((value: UserType) => { return ( = ({ userId, text, ...rest }) => { + return ( + + + {userId && `${userId}`} + + + {text} + + + ); +}; + +export default ChatBubble; diff --git a/src/components/common/ToastNotice/index.tsx b/src/components/common/ToastNotice/index.tsx index 98feddf0..d567e331 100644 --- a/src/components/common/ToastNotice/index.tsx +++ b/src/components/common/ToastNotice/index.tsx @@ -4,7 +4,7 @@ import styled from "styled-components"; import useFetch from "../../../hooks/useFetch"; const Toast = styled.div` - border-radius: 16px; + border-radius: 0.5rem; display: flex; justify-content: center; @@ -14,7 +14,8 @@ const Toast = styled.div` top: 2rem; left: 2rem; - background: #cdcdcd; + background-color: rgba(20, 20, 20, 0.8); + color: #fff; width: 400px; height: 150px; @@ -91,6 +92,10 @@ const ToastNotice: React.FC = ({ roomData, setToast }) => {