Skip to content

Commit

Permalink
Merge branch develop into feature/#3
Browse files Browse the repository at this point in the history
  • Loading branch information
suehub committed Nov 10, 2023
2 parents 23af7da + acbd5e6 commit 1895e78
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 84 deletions.
94 changes: 92 additions & 2 deletions src/components/Game/GameChat/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,95 @@
const GameChat = () => {
return <div>game chat</div>;
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<Message>({
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<HTMLInputElement>) => {
if (event.key === "Enter") {
submitMessage();
}
};

return (
<Card>
<CardBody>
{messages.map((message, index) => (
<ChatBubble key={index} userId={message.id} text={message.text} />
))}
</CardBody>
<InputGroup size="md">
<Input
pr="4.5rem"
type="text"
placeholder="채팅내용"
value={messageValue.value}
onChange={messageValue.onChange}
onKeyPress={handleKeyPress}
/>
<InputRightElement width="4.5rem">
<Button h="1.75rem" size="sm" onClick={submitMessage}>
전송
</Button>
</InputRightElement>
</InputGroup>
</Card>
);
};

export default GameChat;
109 changes: 77 additions & 32 deletions src/components/Main/CreateGameModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -132,39 +133,50 @@ interface ChatRoom {
status?: string;
}

interface UserType {
id: string;
name: string;
picture: string;
}

interface Props {
setModal: React.Dispatch<React.SetStateAction<boolean>>;
}

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<ChatRoom>({
name: "",
users: [],
isPrivate: false,
num: 1,
num: 6,
});

// 방제목 빈값이면 true
const [inputAction, setInpuAction] = useState(false);

const [userList, setUserList] = useState<UserType[]>([]);

// 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",
Expand All @@ -175,30 +187,57 @@ 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<HTMLInputElement>) => {
const copy = { ...roomData };
copy.num = ~~e.target.value;

setRoomData(copy);
};

// 게임 생성 후 파이어베이스 저장 밑 유저 초대 푸쉬알림
useEffect(() => {
if (createGame.result) {
// 파이어베이스 게임 데이터 생성
const newData = {
...roomData,
id: createGame.result.id,
Expand All @@ -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
Expand All @@ -235,7 +275,7 @@ const CreateGameModal = ({ setModal }: Props) => {
<ImgBox></ImgBox>
<Input
marginBottom="1rem"
border="1px solid #c6c6c6"
border={!inputAction ? "1px solid #c6c6c6" : "1px solid red"}
placeholder="방제목"
textAlign="center"
value={titleInput.value}
Expand All @@ -250,7 +290,7 @@ const CreateGameModal = ({ setModal }: Props) => {
id="1"
name="drone"
value="1"
defaultChecked
checked={roomData.num === 1}
onChange={handleRadioChange}
/>
<label htmlFor="1">1</label>
Expand Down Expand Up @@ -330,14 +370,19 @@ const CreateGameModal = ({ setModal }: Props) => {
</Section>
<Section>
<div style={{ overflow: "auto" }}>
<Input
border="1px solid #c6c6c6"
placeholder="검색"
textAlign="center"
marginBottom="1rem"
/>
<div>
<Input
border="1px solid #c6c6c6"
placeholder="검색"
textAlign="center"
marginBottom="1rem"
height="2rem"
value={searchInput.value}
onChange={searchInput.onChange}
/>
</div>
{users.result &&
users.result.map((value: any) => {
userList.map((value: UserType) => {
return (
<UserCard
key={value.id}
Expand Down
32 changes: 32 additions & 0 deletions src/components/common/ChatBubble.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { BoxProps, Container, Text } from "@chakra-ui/react";
import React from "react";
import styled from "styled-components";

const Bubble = styled.div`
margin: 8px 0px 12px;
padding: 8px;
background-color: #e2e8f0;
width: fit-content;
max-width: 300px;
border-radius: 0 12px 12px 12px;
`;

interface ChatBubbleProps extends BoxProps {
userId?: string;
text: string;
}

const ChatBubble: React.FC<ChatBubbleProps> = ({ userId, text, ...rest }) => {
return (
<Container>
<Text fontWeight="bold" mb="0px">
{userId && `${userId}`}
</Text>
<Bubble>
<Text>{text}</Text>
</Bubble>
</Container>
);
};

export default ChatBubble;
13 changes: 11 additions & 2 deletions src/components/common/ToastNotice/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -91,6 +92,10 @@ const ToastNotice: React.FC<Props> = ({ roomData, setToast }) => {
<Button
marginRight="2rem"
width="50%"
variant="outline"
borderColor="#eee"
color="#eee"
colorScheme="whiteAlpha"
onClick={() => {
live.refresh();
setToast(false);
Expand All @@ -101,6 +106,10 @@ const ToastNotice: React.FC<Props> = ({ roomData, setToast }) => {
<Button
marginRight="2rem"
width="50%"
variant="outline"
borderColor="#eee"
color="#eee"
colorScheme="whiteAlpha"
onClick={() => {
navigate(`/game?gameId=${roomData.id}`);
}}
Expand Down
Loading

0 comments on commit 1895e78

Please sign in to comment.