From c45dd60ac51f3df6057e1283bc90e56f66d39723 Mon Sep 17 00:00:00 2001 From: sue Date: Wed, 15 Nov 2023 14:55:57 +0900 Subject: [PATCH 1/3] Feat: GameStart Rendering... --- src/components/Game/GameChat/index.tsx | 21 ++++++++------ src/components/Game/GameStart/index.tsx | 1 + src/components/Main/CreateGameModal/index.tsx | 1 + src/pages/Game/index.tsx | 28 +++++++++++++++---- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/components/Game/GameChat/index.tsx b/src/components/Game/GameChat/index.tsx index 1aad7fff..6665cd25 100644 --- a/src/components/Game/GameChat/index.tsx +++ b/src/components/Game/GameChat/index.tsx @@ -20,6 +20,13 @@ interface Message { interface GameChatProps { socket: Socket; gameData: any; + onGameInfoReceived: (gameInfo: { + category: string; + keyword: string; + liar: string; + users: string[]; + status: string; + }) => void; } interface UserResponse { @@ -28,7 +35,11 @@ interface UserResponse { leaver?: string; } -const GameChat: React.FC = ({ socket, gameData }) => { +const GameChat: React.FC = ({ + socket, + gameData, + onGameInfoReceived, +}) => { console.log("GameChat/ gameData:", gameData); const [message, setMessage] = useState({ @@ -61,13 +72,7 @@ const GameChat: React.FC = ({ socket, gameData }) => { if (messageObject.text.split("~")[1] === "!@##") { const gameInfo = JSON.parse(messageObject.text.split("~")[0]); console.log("parseData:", gameInfo); - window.localStorage.setItem( - "shuffledUsers", - JSON.stringify(gameInfo.users), - ); - window.localStorage.setItem("category", gameInfo.category); - window.localStorage.setItem("keyword", gameInfo.keyword); - window.localStorage.setItem("liar", gameInfo.liar); + onGameInfoReceived(gameInfo); return; } // 메시지 데이터, 작성 유저 상태 저장 diff --git a/src/components/Game/GameStart/index.tsx b/src/components/Game/GameStart/index.tsx index 552fc432..55321518 100644 --- a/src/components/Game/GameStart/index.tsx +++ b/src/components/Game/GameStart/index.tsx @@ -100,6 +100,7 @@ const GameStart: React.FC = ({ keyword: ranKeyword, liar: ranLiar, users: shuffledUsers, + status: status, }); // 모든 클라이언트에게 게임 정보를 포함하는 이벤트 전송 diff --git a/src/components/Main/CreateGameModal/index.tsx b/src/components/Main/CreateGameModal/index.tsx index f3044847..5f975a58 100644 --- a/src/components/Main/CreateGameModal/index.tsx +++ b/src/components/Main/CreateGameModal/index.tsx @@ -142,6 +142,7 @@ interface UserType { } export interface Socket { + off(arg0: string): unknown; on(event: string, callback: any): void; emit(event: string, data: any): void; } diff --git a/src/pages/Game/index.tsx b/src/pages/Game/index.tsx index 52f5686c..cc3a2886 100644 --- a/src/pages/Game/index.tsx +++ b/src/pages/Game/index.tsx @@ -11,6 +11,13 @@ interface ProfileCardProps { userId: string; } +interface GameInfo { + category: string; + keyword: string; + liar: string; + users: string[]; +} + const ProfileCard: React.FC = ({ userId }) => { return ( @@ -37,7 +44,7 @@ const Game = () => { const fireFetch = useFireFetch(); const gameData = fireFetch.useGetSome("game", "id", gameId as string); const [status, setStatus] = useState(""); - const [users, setUsers] = useState([]); + const [users, setUsers] = useState([]); const [category, setCategory] = useState(""); const [keyword, setKeyword] = useState(""); @@ -82,6 +89,14 @@ const Game = () => { } }; + const handleGameInfoReceived = (gameInfo: GameInfo) => { + setCategory(gameInfo.category); + setKeyword(gameInfo.keyword); + setLiar(gameInfo.liar); + setUsers(gameInfo.users); + setStatus("게임중"); + }; + if (gameData.data.length === 0) { return

Loading...

; } @@ -108,10 +123,7 @@ const Game = () => {
{status === "게임중" ? ( <> -

- 주제는 {window.localStorage.getItem("category")} 입니다. -   -

+

주제는 {category} 입니다.  

{liar === user.id ? (

당신은 Liar 입니다.

@@ -140,7 +152,11 @@ const Game = () => { })} - + From 09541db8517c192e0bc0628dc930b3caf8e575c8 Mon Sep 17 00:00:00 2001 From: sue Date: Wed, 15 Nov 2023 15:45:32 +0900 Subject: [PATCH 2/3] Feat: Socket Connect GameStart --- src/components/Game/GameChat/index.tsx | 8 +- src/components/Game/GameStart/index.tsx | 24 ++- src/components/Game/Keyword/index.tsx | 268 ++++++++++++------------ src/pages/Game/index.tsx | 21 +- 4 files changed, 159 insertions(+), 162 deletions(-) diff --git a/src/components/Game/GameChat/index.tsx b/src/components/Game/GameChat/index.tsx index 6665cd25..4d5b9f1a 100644 --- a/src/components/Game/GameChat/index.tsx +++ b/src/components/Game/GameChat/index.tsx @@ -69,9 +69,15 @@ const GameChat: React.FC = ({ useEffect(() => { socket.on("message-to-client", (messageObject: any) => { + // 게임 시작 메시지 if (messageObject.text.split("~")[1] === "!@##") { const gameInfo = JSON.parse(messageObject.text.split("~")[0]); - console.log("parseData:", gameInfo); + onGameInfoReceived(gameInfo); + return; + } + // 게임 종료 메시지 + if (messageObject.text.split("~")[1] === "##@!") { + const gameInfo = JSON.parse(messageObject.text.split("~")[0]); onGameInfoReceived(gameInfo); return; } diff --git a/src/components/Game/GameStart/index.tsx b/src/components/Game/GameStart/index.tsx index 55321518..7774e7c3 100644 --- a/src/components/Game/GameStart/index.tsx +++ b/src/components/Game/GameStart/index.tsx @@ -49,6 +49,7 @@ const GameStart: React.FC = ({ // const [keyword, setKeyword] = useState(""); // const [liar, setLiar] = useState(""); const [showStartModal, setShowStartModal] = useState(false); + // const [shuffledUsers, setshuffledUsers] = useState([]); useEffect(() => { if (showStartModal) { @@ -84,7 +85,7 @@ const GameStart: React.FC = ({ const ranLiar = users[getRandNum(users.length)]; // 유저 순서 랜덤으로 섞기 - const shuffledUsers: string[] = users + const newUsers: string[] = users .map( (userId: string): UserWithSort => ({ value: userId, // 실제 유저 ID @@ -99,10 +100,12 @@ const GameStart: React.FC = ({ category: selectedCategory.category, keyword: ranKeyword, liar: ranLiar, - users: shuffledUsers, - status: status, + users: newUsers, + status: "게임중", }); + // setshuffledUsers(newUsers); + // 모든 클라이언트에게 게임 정보를 포함하는 이벤트 전송 socket.emit("message-to-server", gameInfo + "~!@##"); @@ -116,11 +119,16 @@ const GameStart: React.FC = ({ const hadleEnd = () => { updateStatus("대기중"); - window.localStorage.setItem("category", ""); - window.localStorage.setItem("keyword", ""); - window.localStorage.setItem("liar", "false"); - // setCategory(null); - // setKeyword(""); + const gameInfo = JSON.stringify({ + category: "", + keyword: "", + liar: "", + users: users, + status: "대기중", + }); + + socket.emit("message-to-server", gameInfo + "~##@!"); + setShowStartModal(false); }; diff --git a/src/components/Game/Keyword/index.tsx b/src/components/Game/Keyword/index.tsx index 175fe015..31ceef31 100644 --- a/src/components/Game/Keyword/index.tsx +++ b/src/components/Game/Keyword/index.tsx @@ -1,134 +1,134 @@ -import { - Button, - Center, - Flex, - Modal, - ModalBody, - ModalCloseButton, - ModalContent, - ModalOverlay, - useDisclosure, -} from "@chakra-ui/react"; -import { useEffect, useState } from "react"; -import data from "../../../data/category.json"; - -interface Categories { - category: string; - keyword: string[]; -} -[]; - -const Keyword = ({ status, updateStatus }: any) => { - const categories = data.CategoryList; - const [category, setCategory] = useState(null); - const [keyword, setKeyword] = useState(""); - const users = data.users; - - const { isOpen, onClose, onOpen } = useDisclosure(); - - // 모달 자동 닫기 - useEffect(() => { - let timer: NodeJS.Timeout; - - if (isOpen) { - timer = setTimeout(() => { - onClose(); - }, 3000); - } - return () => clearTimeout(timer); - }, [isOpen, onClose]); - - // 랜덤 숫자 계산 - const getRandNum = (length: number): number => { - const randNum = Math.floor(Math.random() * length); - - return randNum; - }; - - // 게임 시작 - const handleStart = async () => { - await updateStatus("게임중"); - - const selectedCategory = categories[getRandNum(categories.length)]; - const ranKeyword = - selectedCategory.keyword[getRandNum(selectedCategory.keyword.length)]; - const ranLiar = users.name[getRandNum(users.name.length)]; - - setCategory(selectedCategory); - setKeyword(ranKeyword); - - window.localStorage.setItem("category", selectedCategory.category); - window.localStorage.setItem("keyword", ranKeyword); - if (ranLiar === "연수") { - window.localStorage.setItem("liar", "true"); - } else { - window.localStorage.setItem("liar", "false"); - } - onOpen(); - }; - - // status 변화에 따라 localStorage에 저장 - useEffect(() => { - if (status === "게임중") { - const currentCategory = window.localStorage.getItem("category") ?? ""; - const currentKeyword = window.localStorage.getItem("keyword") ?? ""; - - setCategory({ category: currentCategory, keyword: [currentKeyword] }); - setKeyword(currentKeyword); - } - }, [status]); - - // 게임 종료 - const hadleEnd = async () => { - await updateStatus("대기중"); - - window.localStorage.setItem("category", ""); - window.localStorage.setItem("keyword", ""); - window.localStorage.setItem("liar", "false"); - setCategory(null); - setKeyword(""); - }; - - return ( - <> - {status === "대기중" ? ( - - ) : ( - - )} - - - - - -
- -
주제는 {category?.category} 입니다.
- {window.localStorage.getItem("liar") === "true" ? ( - <> -
당신은 Liar 입니다.
-
키워드를 추리하세요.
- - ) : ( -
키워드는 {keyword} 입니다.
- )} -
-
-
-
-
- - ); -}; - -export default Keyword; +// import { +// Button, +// Center, +// Flex, +// Modal, +// ModalBody, +// ModalCloseButton, +// ModalContent, +// ModalOverlay, +// useDisclosure, +// } from "@chakra-ui/react"; +// import { useEffect, useState } from "react"; +// import data from "../../../data/category.json"; + +// interface Categories { +// category: string; +// keyword: string[]; +// } +// []; + +// const Keyword = ({ status, updateStatus }: any) => { +// const categories = data.CategoryList; +// const [category, setCategory] = useState(null); +// const [keyword, setKeyword] = useState(""); +// const users = data.users; + +// const { isOpen, onClose, onOpen } = useDisclosure(); + +// // 모달 자동 닫기 +// useEffect(() => { +// let timer: NodeJS.Timeout; + +// if (isOpen) { +// timer = setTimeout(() => { +// onClose(); +// }, 3000); +// } +// return () => clearTimeout(timer); +// }, [isOpen, onClose]); + +// // 랜덤 숫자 계산 +// const getRandNum = (length: number): number => { +// const randNum = Math.floor(Math.random() * length); + +// return randNum; +// }; + +// // 게임 시작 +// const handleStart = async () => { +// await updateStatus("게임중"); + +// const selectedCategory = categories[getRandNum(categories.length)]; +// const ranKeyword = +// selectedCategory.keyword[getRandNum(selectedCategory.keyword.length)]; +// const ranLiar = users.name[getRandNum(users.name.length)]; + +// setCategory(selectedCategory); +// setKeyword(ranKeyword); + +// window.localStorage.setItem("category", selectedCategory.category); +// window.localStorage.setItem("keyword", ranKeyword); +// if (ranLiar === "연수") { +// window.localStorage.setItem("liar", "true"); +// } else { +// window.localStorage.setItem("liar", "false"); +// } +// onOpen(); +// }; + +// // status 변화에 따라 localStorage에 저장 +// useEffect(() => { +// if (status === "게임중") { +// const currentCategory = window.localStorage.getItem("category") ?? ""; +// const currentKeyword = window.localStorage.getItem("keyword") ?? ""; + +// setCategory({ category: currentCategory, keyword: [currentKeyword] }); +// setKeyword(currentKeyword); +// } +// }, [status]); + +// // 게임 종료 +// const hadleEnd = async () => { +// await updateStatus("대기중"); + +// window.localStorage.setItem("category", ""); +// window.localStorage.setItem("keyword", ""); +// window.localStorage.setItem("liar", "false"); +// setCategory(null); +// setKeyword(""); +// }; + +// return ( +// <> +// {status === "대기중" ? ( +// +// ) : ( +// +// )} +// +// +// +// +// +//
+// +//
주제는 {category?.category} 입니다.
+// {window.localStorage.getItem("liar") === "true" ? ( +// <> +//
당신은 Liar 입니다.
+//
키워드를 추리하세요.
+// +// ) : ( +//
키워드는 {keyword} 입니다.
+// )} +//
+//
+//
+//
+//
+// +// ); +// }; + +// export default Keyword; diff --git a/src/pages/Game/index.tsx b/src/pages/Game/index.tsx index cc3a2886..04bcb91f 100644 --- a/src/pages/Game/index.tsx +++ b/src/pages/Game/index.tsx @@ -16,6 +16,7 @@ interface GameInfo { keyword: string; liar: string; users: string[]; + status: string; } const ProfileCard: React.FC = ({ userId }) => { @@ -63,24 +64,6 @@ const Game = () => { } }, [gameData.data]); - useEffect(() => { - if (status === "게임중") { - // 저장된 유저 순서 로컬 스토리지에서 가져오기 - const shuffledUsers = JSON.parse( - window.localStorage.getItem("shuffledUsers") || "[]", - ); - setUsers(shuffledUsers); - - const currentCategory = window.localStorage.getItem("category") ?? ""; - const currentKeyword = window.localStorage.getItem("keyword") ?? ""; - const currentLiar = window.localStorage.getItem("liar") ?? ""; - - setCategory(currentCategory); - setKeyword(currentKeyword); - setLiar(currentLiar); - } - }, [status]); - // status 업데이트 함수 const updateStatus = (newStatus: string) => { setStatus(newStatus); @@ -94,7 +77,7 @@ const Game = () => { setKeyword(gameInfo.keyword); setLiar(gameInfo.liar); setUsers(gameInfo.users); - setStatus("게임중"); + setStatus(gameInfo.status); }; if (gameData.data.length === 0) { From db44820801fd3fdeb15ced4de0bb58447f99f0ff Mon Sep 17 00:00:00 2001 From: sue Date: Wed, 15 Nov 2023 16:36:10 +0900 Subject: [PATCH 3/3] Feat: Add current, speaking --- src/components/Game/GameStart/index.tsx | 71 +++++++++---------------- src/pages/Game/index.tsx | 57 +++++++++++++------- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/components/Game/GameStart/index.tsx b/src/components/Game/GameStart/index.tsx index 7774e7c3..6dcddfc3 100644 --- a/src/components/Game/GameStart/index.tsx +++ b/src/components/Game/GameStart/index.tsx @@ -1,6 +1,6 @@ import { Button, - useDisclosure, + // useDisclosure, // Modal, // ModalOverlay, // ModalContent, @@ -9,7 +9,7 @@ import { // Center, // Flex, } from "@chakra-ui/react"; -import { useEffect, useState } from "react"; +// import { useEffect, useState } from "react"; import data from "../../../data/category.json"; import { useRecoilValue } from "recoil"; import { userState } from "../../../recoil/atoms/userState"; @@ -20,15 +20,8 @@ interface GameStartProps { status: string; users: string[]; host: string; - updateStatus: (newStatus: string) => void; } -// interface Categories { -// category: string; -// keyword: string[]; -// } -// []; - interface UserWithSort { value: string; sort: number; @@ -39,36 +32,31 @@ const GameStart: React.FC = ({ status, users, host, - updateStatus, }) => { const user = useRecoilValue(userState); const categories = data.CategoryList; - const { isOpen, onClose, onOpen } = useDisclosure(); - // const [category, setCategory] = useState(null); - // const [keyword, setKeyword] = useState(""); - // const [liar, setLiar] = useState(""); - const [showStartModal, setShowStartModal] = useState(false); - // const [shuffledUsers, setshuffledUsers] = useState([]); - - useEffect(() => { - if (showStartModal) { - onOpen(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [showStartModal]); - - // 모달 자동 닫기 로직 - useEffect(() => { - let timer: NodeJS.Timeout; - - if (isOpen) { - timer = setTimeout(() => { - onClose(); - }, 2500); - } - return () => clearTimeout(timer); - }, [isOpen, onClose]); + // const { isOpen, onClose, onOpen } = useDisclosure(); + // const [showStartModal, setShowStartModal] = useState(false); + + // useEffect(() => { + // if (showStartModal) { + // onOpen(); + // } + // // eslint-disable-next-line react-hooks/exhaustive-deps + // }, [showStartModal]); + + // // 모달 자동 닫기 로직 + // useEffect(() => { + // let timer: NodeJS.Timeout; + + // if (isOpen) { + // timer = setTimeout(() => { + // onClose(); + // }, 2500); + // } + // return () => clearTimeout(timer); + // }, [isOpen, onClose]); // 랜덤 숫자 계산 함수 const getRandNum = (length: number): number => { @@ -77,8 +65,6 @@ const GameStart: React.FC = ({ // 게임 시작 함수 const handleStart = async () => { - updateStatus("게임중"); - const selectedCategory = categories[getRandNum(categories.length)]; const ranKeyword = selectedCategory.keyword[getRandNum(selectedCategory.keyword.length)]; @@ -104,21 +90,14 @@ const GameStart: React.FC = ({ status: "게임중", }); - // setshuffledUsers(newUsers); - // 모든 클라이언트에게 게임 정보를 포함하는 이벤트 전송 socket.emit("message-to-server", gameInfo + "~!@##"); - // setCategory(selectedCategory); - // setKeyword(ranKeyword); - // setLiar(ranLiar); - setShowStartModal(true); + // setShowStartModal(true); }; // 게임 종료 const hadleEnd = () => { - updateStatus("대기중"); - const gameInfo = JSON.stringify({ category: "", keyword: "", @@ -129,7 +108,7 @@ const GameStart: React.FC = ({ socket.emit("message-to-server", gameInfo + "~##@!"); - setShowStartModal(false); + // setShowStartModal(false); }; return ( diff --git a/src/pages/Game/index.tsx b/src/pages/Game/index.tsx index 04bcb91f..3dc64c90 100644 --- a/src/pages/Game/index.tsx +++ b/src/pages/Game/index.tsx @@ -6,6 +6,8 @@ import GameStart from "../../components/Game/GameStart"; import { useRecoilValue } from "recoil"; import { userState } from "../../recoil/atoms/userState"; import connect from "../../socket/socket"; +import useFetch from "../../hooks/useFetch"; +import { useNavigate } from "react-router-dom"; interface ProfileCardProps { userId: string; @@ -29,14 +31,9 @@ const ProfileCard: React.FC = ({ userId }) => { ); }; -// interface Categories { -// category: string; -// keyword: string[]; -// } -// []; - const Game = () => { const user = useRecoilValue(userState); + const navigate = useNavigate(); const queryString = window.location.search; const searchParams = new URLSearchParams(queryString); @@ -47,13 +44,17 @@ const Game = () => { const [status, setStatus] = useState(""); const [users, setUsers] = useState([]); + // 게임 소켓 서버 연결 + const socket = connect(gameId as string); + // 메인 소켓 서버 연결 (메인페이지 상태 변경 통신) + const socketMain = connect("9984747e-389a-4aef-9a8f-968dc86a44e4"); + const [category, setCategory] = useState(""); const [keyword, setKeyword] = useState(""); const [liar, setLiar] = useState(""); - console.log(category, keyword); - - const socket = connect(gameId as string); + const [current, setCurrent] = useState(""); + const [speaking, setSpeaking] = useState(""); useEffect(() => { if (gameData.data && gameData.data.length > 0) { @@ -64,13 +65,15 @@ const Game = () => { } }, [gameData.data]); - // status 업데이트 함수 - const updateStatus = (newStatus: string) => { - setStatus(newStatus); - if (gameId) { - fireFetch.updateData("game", gameId, { status: newStatus }); - } - }; + // 게임 나가기 api 선언 (호출 X) + const leave = useFetch({ + url: "https://fastcampus-chat.net/chat/leave", + method: "PATCH", + data: { + chatId: gameId, + }, + start: false, + }); const handleGameInfoReceived = (gameInfo: GameInfo) => { setCategory(gameInfo.category); @@ -78,7 +81,11 @@ const Game = () => { setLiar(gameInfo.liar); setUsers(gameInfo.users); setStatus(gameInfo.status); + + setCurrent("개별발언"); + setSpeaking(users[0]); }; + console.log(current, speaking); if (gameData.data.length === 0) { return

Loading...

; @@ -97,7 +104,22 @@ const Game = () => { mt="50px" > - @@ -126,7 +148,6 @@ const Game = () => { status={status} users={users} host={gameData.data[0].host} - updateStatus={updateStatus} />