Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/pepero-1/liar-game into …
Browse files Browse the repository at this point in the history
…feature/#3
  • Loading branch information
suehub committed Nov 13, 2023
2 parents f4b039b + 120d0cd commit 2dac008
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 9 deletions.
71 changes: 67 additions & 4 deletions src/components/Game/GameChat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
import { useEffect, useRef, useState } from "react";
import { io } from "socket.io-client";
import ChatBubble from "../../common/ChatBubble";
import SystemChat from "../../common/SystemChat";
import Vote from "../Vote";

interface Message {
id: string;
Expand All @@ -17,9 +19,17 @@ interface Message {

interface GameChatProps {
gameId: string;
gameData: any;
}

const GameChat: React.FC<GameChatProps> = ({ gameId }) => {
interface UserResponse {
users: string[];
joiners?: string[];
leaver?: string;
}

const GameChat: React.FC<GameChatProps> = ({ gameId, gameData }) => {
console.log("GameChat/ gameData:", gameData);
const token = JSON.parse(localStorage.getItem("token") as string);

const socket = io(`https://fastcampus-chat.net/chat?chatId=${gameId}`, {
Expand All @@ -35,6 +45,26 @@ const GameChat: React.FC<GameChatProps> = ({ gameId }) => {
});
const [messages, setMessages]: any = useState([]);
const messageRef = useRef<HTMLInputElement | null>(null);
const [users, setUsers] = useState<string[]>([]);
console.log("users: ", users);
const [showVoteModal, setShowVoteModal] = useState(false);
const [selectedUser, setSelectedUser] = useState<string | null>("");

const handleOpenVoteModal = () => {
setShowVoteModal(true);
};

const handleCloseVoteModal = (selectedUser: string) => {
setShowVoteModal(false);
setSelectedUser(selectedUser);
};

// const handleCalculateVoteClose = (finalLiar: string) => {
// // finalLiar를 이용하여 특정 동작 수행 (SystemChat)

// // 선택한 결과 초기화
// setSelectedUser("");
// };

useEffect(() => {
socket.on("message-to-client", (messageObject) => {
Expand All @@ -48,6 +78,25 @@ const GameChat: React.FC<GameChatProps> = ({ gameId }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [socket]);

useEffect(() => {
// 유저 입장 메시지 수신
socket.on("join", (responseData: UserResponse) => {
const systemMessage = `${responseData.joiners!.join(
", ",
)} 님이 입장했습니다.`;

setMessages([...messages, { id: "system", text: systemMessage }]);
setUsers(responseData.users);
});

// 유저 퇴장 메시지 수신
socket.on("leave", (responseData: UserResponse) => {
const systemMessage = `${responseData.leaver} 님이 퇴장했습니다.`;
setMessages([...messages, { id: "system", text: systemMessage }]);
setUsers(responseData.users);
});
}, []);

// 메시지 값 변화시(소켓 통신 시) 콘솔에 메시지 데이터 출력
useEffect(() => {
if (message.id !== "") {
Expand All @@ -74,9 +123,23 @@ const GameChat: React.FC<GameChatProps> = ({ gameId }) => {
return (
<Card p={3} h="100%" mb="20px">
<CardBody>
{messages.map((message: Message, index: number) => (
<ChatBubble key={index} userId={message.id} text={message.text} />
))}
{messages.map((message: Message, index: number) =>
// 시스템 메시지인 경우 SystemMessage 컴포넌트 사용
message.id === "system" ? (
<SystemChat key={index} text={message.text} />
) : (
<ChatBubble key={index} userId={message.id} text={message.text} />
),
)}
<Button size="md" onClick={handleOpenVoteModal}>
투표하기
</Button>
{showVoteModal && (
<Vote gameData={gameData} onClose={handleCloseVoteModal} />
)}
{selectedUser && (
<SystemChat text={`${selectedUser}님이 라이어로 선택되었습니다.`} />
)}
</CardBody>
<InputGroup size="md">
<Input
Expand Down
82 changes: 82 additions & 0 deletions src/components/Game/Vote/CalculateVote.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { useState, useEffect } from "react";
import {
Button,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
ModalFooter,
Text,
} from "@chakra-ui/react";
import useFireFetch from "../../../hooks/useFireFetch";

interface CalculateVoteProps {
voteResults: string;
onClose: (finalLiar: string) => void;
gameId: string;
}

const CalculateVote: React.FC<CalculateVoteProps> = ({
voteResults,
onClose,
gameId,
}) => {
const [finalLiar, setFinalLiar] = useState<string>("");
const fireFetch = useFireFetch();

// 투표 결과 계산 로직
useEffect(() => {
const calculateFinalLiar = async () => {
const gameData = await fireFetch.useGetSome("game", "id", gameId);
const { users, votedFor } = gameData.data[0];

const votesCount: Record<string, number> = {};
users.forEach((user: string) => {
if (votedFor.includes(user)) {
votesCount[user] = (votesCount[user] || 0) + 1;
}
});

let maxVotes = 0;
for (const user in votesCount) {
if (votesCount[user] > maxVotes) {
maxVotes = votesCount[user];
setFinalLiar(user);
}
}
};

calculateFinalLiar();
}, [voteResults, gameId, fireFetch]);

// 투표 결과 계산 후 최종 라이어를 부모 컴포넌트로 전달
useEffect(() => {
if (finalLiar) {
onClose(finalLiar);
}
}, [finalLiar, onClose]);

return (
<Modal isOpen={true} onClose={() => {}}>
<ModalOverlay />
<ModalContent>
<ModalHeader>투표 결과 계산 중</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text>투표 결과 계산 중입니다...</Text>
</ModalBody>
<ModalFooter>
{finalLiar && (
<Button colorScheme="blue" onClick={() => onClose(finalLiar)}>
계산 완료
</Button>
)}
</ModalFooter>
</ModalContent>
</Modal>
);
};

export default CalculateVote;
81 changes: 79 additions & 2 deletions src/components/Game/Vote/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,82 @@
const Vote = () => {
return <div>Vote</div>;
import { useState } from "react";
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
ModalFooter,
Button,
Radio,
RadioGroup,
Stack,
} from "@chakra-ui/react";
import useFireFetch from "../../../hooks/useFireFetch";
import { arrayUnion } from "firebase/firestore";

interface GameData {
id: string;
users: string[];
}

interface VoteProps {
onClose: (selectedUser: string) => void;
gameData: GameData;
}

const Vote: React.FC<VoteProps> = ({
onClose,
gameData,
}): React.ReactElement => {
const [selectedUser, setSelectedUser] = useState<string>("");
const fireFetch = useFireFetch();

const storedToken = localStorage.getItem("token");
const tokenData = storedToken ? JSON.parse(storedToken) : null;

const handleUserChange = (value: string) => {
setSelectedUser(value);
};

const handleVoteSubmit = () => {
if (selectedUser !== null) {
const myId = tokenData.id;
fireFetch.updateData("game", gameData.id, {
votedFor: arrayUnion({ by: myId, liar: selectedUser }),
});
console.log(selectedUser + "에 투표했습니다.");
onClose(selectedUser);
}
};

return (
<>
<Modal isOpen={true} onClose={() => onClose(selectedUser)}>
<ModalOverlay />
<ModalContent>
<ModalHeader>라이어 투표하기</ModalHeader>
<ModalCloseButton />
<ModalBody>
<RadioGroup value={selectedUser} onChange={handleUserChange}>
<Stack spacing={2}>
{gameData.users.map((user) => (
<Radio key={user} value={user}>
{user}
</Radio>
))}
</Stack>
</RadioGroup>
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={handleVoteSubmit}>
투표 완료
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
};

export default Vote;
16 changes: 16 additions & 0 deletions src/components/common/SystemChat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";
import { Box } from "@chakra-ui/react";

interface SystemChatProps {
text: string;
}

const SystemChat: React.FC<SystemChatProps> = ({ text }) => {
return (
<Box textAlign="center" bgColor="gray.300" p={1} borderRadius={5} my={2}>
{text}
</Box>
);
};

export default SystemChat;
6 changes: 3 additions & 3 deletions src/pages/Game/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,17 @@ const Game = () => {
</Button>
</GridItem>
<GridItem>
<ProfileCard userId={gameData.data[0].host}></ProfileCard>
<ProfileCard userId={gameData.data[0].users[0]}></ProfileCard>
<ProfileCard userId={gameData.data[0].users[1]}></ProfileCard>
<ProfileCard userId={gameData.data[0].users[2]}></ProfileCard>
</GridItem>
<GridItem>
<GameChat gameId={gameId} />
<GameChat gameId={gameId} gameData={gameData.data[0]} />
</GridItem>
<GridItem>
<ProfileCard userId={gameData.data[0].users[2]}></ProfileCard>
<ProfileCard userId={gameData.data[0].users[3]}></ProfileCard>
<ProfileCard userId={gameData.data[0].users[4]}></ProfileCard>
<ProfileCard userId={gameData.data[0].users[5]}></ProfileCard>
</GridItem>
</Grid>
</>
Expand Down

0 comments on commit 2dac008

Please sign in to comment.