Overnap

Merge branch 'refactor' into develop

import React from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { socket, SocketProvider } from './contexts/SocketContext';
import { Login } from './pages/Login';
import { Room } from './pages/Room';
import { Rooms } from './pages/Rooms';
import Login from './pages/Login';
import Room from './pages/Room';
import Rooms from './pages/Rooms';
const App: React.FC = () => {
return (
......
import React from 'react';
export const Footer: React.FC = () => {
const Footer: React.FC = () => {
return (
<div className="mt-auto flex justify-center items-center">
<a href="http://khuhub.khu.ac.kr/2020105578/nodejs-game">
<img className="object-contain h-12" src="./gitlab.png"/>
<img className="object-contain h-12" alt='logo img' src="./gitlab.png"/>
</a>
<div className="flex text-gray-600">Made by&nbsp;
<a href="https://github.com/aren227" target="_blank"
<a href="https://github.com/aren227" target="_blank" rel="noreferrer"
className="outline-none focus:outline-none
text-gray-600 hover:text-green-500
ease-linear transition-all duration-100">@aren227</a>&nbsp;
<a href="https://github.com/overnap" target="_blank"
<a href="https://github.com/overnap" target="_blank" rel="noreferrer"
className="outline-none focus:outline-none
text-gray-600 hover:text-green-500
ease-linear transition-all duration-100">@overnap</a>
......@@ -19,3 +19,5 @@ export const Footer: React.FC = () => {
</div>
);
}
export default Footer;
\ No newline at end of file
......
import React from 'react';
import { Footer } from './Footer';
import Footer from './Footer';
export const Main: React.FC = ({ children }) => {
const Main: React.FC = ({ children }) => {
return (
<div className="flex flex-col items-center w-screen h-screen">
{children}
......@@ -9,3 +9,5 @@ export const Main: React.FC = ({ children }) => {
</div>
);
}
export default Main;
\ No newline at end of file
......
......@@ -9,7 +9,7 @@ interface CanvasProps {
isDrawer: boolean;
}
export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => {
const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => {
const socket = useContext(SocketContext);
const canvasRef = useRef<HTMLCanvasElement>(null);
......@@ -186,3 +186,5 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => {
</div>
);
}
export default Canvas;
\ No newline at end of file
......
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
import SocketContext from '../../contexts/SocketContext';
import { MessageType, RawMessage } from '../common/types';
import { ChatLine } from './ChatLine';
import ChatLine from './ChatLine';
import { ChatData } from './types';
interface ChatProps {
......@@ -9,7 +9,7 @@ interface ChatProps {
h: string;
}
export const Chat: React.FC<ChatProps> = (props) => {
const Chat: React.FC<ChatProps> = (props) => {
const socket = useContext(SocketContext);
const [ input, setInput ] = useState('');
const [ chatLines, setChatLines ] = useState<ChatData[]>([]);
......@@ -87,3 +87,5 @@ export const Chat: React.FC<ChatProps> = (props) => {
</div>
);
}
export default Chat;
\ No newline at end of file
......
......@@ -5,9 +5,11 @@ interface ChatLineProps {
chatData: ChatData;
}
export const ChatLine: React.FC<ChatLineProps> = ({ chatData }) => {
const ChatLine: React.FC<ChatLineProps> = ({ chatData }) => {
return (
<div className='w-full px-3 py-1.5 bg-white
text-gray-700 text-sm'>{chatData.sender} : {chatData.message}</div>
);
}
export default ChatLine;
\ No newline at end of file
......
......@@ -2,10 +2,10 @@ import React, { useCallback, useContext, useEffect, useState } from 'react';
import { useLocation } from 'react-router';
import SocketContext from '../../contexts/SocketContext';
import { MessageType, RawMessage } from '../common/types';
import { Canvas } from './Canvas';
import { RoundInfo } from './RoundInfo';
import { Role, RoundData } from './types';
import { Word } from './Word';
import Canvas from './Canvas';
import RoundInfo from './RoundInfo';
import { RoundData } from './types';
import Word from './Word';
interface GameBoardLocation {
state: { username: string }
......@@ -15,7 +15,7 @@ interface GameBoardProps {
isInGame: boolean
}
export const GameBoard: React.FC<GameBoardProps> = ({ isInGame }) => {
const GameBoard: React.FC<GameBoardProps> = ({ isInGame }) => {
const socket = useContext(SocketContext);
const location: GameBoardLocation = useLocation();
......@@ -37,8 +37,8 @@ export const GameBoard: React.FC<GameBoardProps> = ({ isInGame }) => {
setWords([]);
const data = rawMessage.message as RoundData;
console.log('테스트 location ', location.state.username);
console.log('테스트 rolse ', data.roles);
// console.log(location.state.username);
// console.log(data.roles);
const index = data.roles.findIndex(x => x.username === location.state.username);
setIsDrawer(data.roles[index].role === 'drawer');
setWordChosen('');
......@@ -64,18 +64,24 @@ export const GameBoard: React.FC<GameBoardProps> = ({ isInGame }) => {
useEffect(() => {
socket.on('msg', handleStart);
socket.on('msg', handleGetWordLength);
socket.on('msg', handleWordSet);
socket.on('msg', handleAnswer);
return () => {
socket.off('msg', handleStart);
socket.off('msg', handleGetWordLength);
socket.off('msg', handleWordSet);
socket.off('msg', handleAnswer);
}
}, []);
useEffect(() => {
socket.on('msg', handleGetWordLength);
return () => {
socket.off('msg', handleGetWordLength);
}
}, [wordChosen]);
return (
<div className={`w-auto ${isInGame ? '' : 'hidden'}`}>
<div className='w-full flex flex-col justify-center items-center'>
......@@ -86,3 +92,5 @@ export const GameBoard: React.FC<GameBoardProps> = ({ isInGame }) => {
</div>
);
}
export default GameBoard;
\ No newline at end of file
......
......@@ -12,7 +12,7 @@ interface ReadyProps {
users: User[];
}
export const Ready: React.FC<ReadyProps> = ({ users }) => {
const Ready: React.FC<ReadyProps> = ({ users }) => {
const socket = useContext(SocketContext);
const location: ReadyLocation = useLocation();
......@@ -58,3 +58,5 @@ export const Ready: React.FC<ReadyProps> = ({ users }) => {
onClick={() => handleReady()}>{isAdmin ? 'Start' : 'Ready'}</button>
);
}
export default Ready;
\ No newline at end of file
......
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { useHistory, useLocation } from 'react-router';
import SocketContext from '../../contexts/SocketContext';
import { MessageResponse, MessageType, RawMessage } from '../common/types';
import { RoomData, UpdateRoomUser } from './types';
import React from 'react';
import { RoomData } from './types';
interface RoomInfoProps {
roomData: RoomData;
}
export const RoomInfo: React.FC<RoomInfoProps> = ({ roomData }) => {
const RoomInfo: React.FC<RoomInfoProps> = ({ roomData }) => {
return (
<div className='m-3 my-8 w-5/6 flex items-center place-content-between'>
<div>{roomData.name}</div>
......@@ -16,3 +13,5 @@ export const RoomInfo: React.FC<RoomInfoProps> = ({ roomData }) => {
</div>
);
}
export default RoomInfo;
\ No newline at end of file
......
import React from 'react';
import SocketContext from '../../contexts/SocketContext';
import { Timer } from './Timer';
import { RoundData } from './types';
import Timer from './Timer';
interface RoundInfoProps {
round: number;
wordChosen: string;
}
export const RoundInfo: React.FC<RoundInfoProps> = ({ round, wordChosen }) => {
const RoundInfo: React.FC<RoundInfoProps> = ({ round, wordChosen }) => {
return (
<div className='p-3 m-3 h-14 rounded shadow flex items-center place-content-between'>
<Timer />
......@@ -17,3 +15,5 @@ export const RoundInfo: React.FC<RoundInfoProps> = ({ round, wordChosen }) => {
</div>
);
}
export default RoundInfo;
\ No newline at end of file
......
......@@ -7,7 +7,7 @@ interface timer {
time: number;
};
export const Timer: React.FC = () => {
const Timer: React.FC = () => {
const socket = useContext(SocketContext);
const [ time, setTime ] = useState(0);
......@@ -53,3 +53,5 @@ export const Timer: React.FC = () => {
</div>
);
}
export default Timer;
\ No newline at end of file
......
import React from 'react';
import { User } from './types';
import { UserStatus } from './UserStatus';
import UserStatus from './UserStatus';
interface UserInfoProps {
users: User[];
}
export const UserInfo: React.FC<UserInfoProps> = ({ users }) => {
const UserInfo: React.FC<UserInfoProps> = ({ users }) => {
return (
<div className='w-7/12 h-60 flex justify-center'>
{users.map((user) => (<UserStatus key={user.username} user={user} />))}
</div>
);
}
export default UserInfo
\ No newline at end of file
......
......@@ -7,7 +7,7 @@ interface UserRoleProps {
isInGame: boolean;
}
export const UserRole: React.FC<UserRoleProps> = ({ isInGame }) => {
const UserRole: React.FC<UserRoleProps> = ({ isInGame }) => {
const socket = useContext(SocketContext);
const [ roles, setRoles ] = useState<RoleData[]>([]);
......@@ -39,3 +39,5 @@ export const UserRole: React.FC<UserRoleProps> = ({ isInGame }) => {
</div>
);
}
export default UserRole;
......
......@@ -5,7 +5,7 @@ interface UserStatusProps {
user: User;
}
export const UserStatus: React.FC<UserStatusProps> = ({ user }) => {
const UserStatus: React.FC<UserStatusProps> = ({ user }) => {
return (
<div className='p-3 h-12 m-4 rounded-lg shadow'>
<div className={`${user.admin ? 'text-blue-500' :
......@@ -16,3 +16,5 @@ export const UserStatus: React.FC<UserStatusProps> = ({ user }) => {
</div>
)
}
export default UserStatus;
\ No newline at end of file
......
import React, { useCallback, useContext } from 'react';
import { IndexType } from 'typescript';
import SocketContext from '../../contexts/SocketContext';
import { MessageResponse, MessageType, RawMessage } from '../common/types';
......@@ -10,7 +9,7 @@ interface WordProps {
setWords: (value: React.SetStateAction<string[]>) => void;
}
export const Word: React.FC<WordProps> = (props) => {
const Word: React.FC<WordProps> = (props) => {
const socket = useContext(SocketContext);
const handleChoose = useCallback(() => {
......@@ -24,7 +23,7 @@ export const Word: React.FC<WordProps> = (props) => {
props.setWordChosen(props.word);
}
});
}, [props.setWordChosen]);
}, [props.word, props.setWords, props.setWordChosen]);
return (
<button className={`bg-green-500 active:bg-green-600 fixed
......@@ -36,3 +35,5 @@ export const Word: React.FC<WordProps> = (props) => {
onClick={() => handleChoose()}>{props.word}</button>
);
}
export default Word;
\ No newline at end of file
......
......@@ -3,13 +3,12 @@ import { useHistory, useLocation } from 'react-router-dom';
import SocketContext from '../../contexts/SocketContext';
import { MessageResponse, MessageType, RawMessage } from '../common/types';
import { RoomData } from '../room/types';
import { Room } from './types';
interface CreateLocation {
state: { username: string }
}
export const Create: React.FC = () => {
const Create: React.FC = () => {
const history = useHistory();
const socket = useContext(SocketContext);
const [ roomName, setRoomName ] = useState('');
......@@ -33,7 +32,7 @@ export const Create: React.FC = () => {
console.log('방 생성 오류');
}
});
}, [roomName]);
}, [roomName, location.state.username]);
return (
<div className="flex items-center">
......@@ -55,3 +54,5 @@ export const Create: React.FC = () => {
</div>
);
}
export default Create;
\ No newline at end of file
......
......@@ -4,7 +4,7 @@ interface RefreshProps {
refreshRooms: () => void
}
export const Refresh: React.FC<RefreshProps> = ({ refreshRooms }) => {
const Refresh: React.FC<RefreshProps> = ({ refreshRooms }) => {
return (
<button className="bg-green-500 active:bg-green-600
text-white uppercase text-xl
......@@ -15,3 +15,5 @@ export const Refresh: React.FC<RefreshProps> = ({ refreshRooms }) => {
onClick={() => refreshRooms()}>⟳</button>
);
}
export default Refresh;
\ No newline at end of file
......
......@@ -13,7 +13,7 @@ interface RoomBlockProps {
room: Room
}
export const RoomBlock: React.FC<RoomBlockProps> = ({ room }) => {
const RoomBlock: React.FC<RoomBlockProps> = ({ room }) => {
const history = useHistory();
const socket = useContext(SocketContext);
const location: RoomBlockLocation = useLocation();
......@@ -40,7 +40,7 @@ export const RoomBlock: React.FC<RoomBlockProps> = ({ room }) => {
} else {
//TODO: 자리 꽉찼다는 MODAL
}
}, []);
}, [location.state.username, room]);
return (
<button className={`flex items-center place-content-between m-2 w-5/6
......@@ -57,3 +57,5 @@ export const RoomBlock: React.FC<RoomBlockProps> = ({ room }) => {
</button>
);
}
export default RoomBlock;
\ No newline at end of file
......
import React, { useCallback, useContext, useState } from 'react';
import { useHistory } from 'react-router';
import { Main } from '../components/common/Main';
import Main from '../components/common/Main';
import { MessageResponse, MessageType, RawMessage } from '../components/common/types';
import SocketContext from '../contexts/SocketContext';
export const Login: React.FC = () => {
const Login: React.FC = () => {
const history = useHistory();
const socket = useContext(SocketContext);
const [ username, setUsername ] = useState("");
......@@ -29,7 +29,7 @@ export const Login: React.FC = () => {
return (
<Main>
<div className="mt-auto flex flex-col items-center">
<img className="m-7" src="./logo192.png"/>
<img className="m-7" src="./logo192.png" alt='logo img' />
<div>
<input type="text"
placeholder="Username"
......@@ -51,3 +51,5 @@ export const Login: React.FC = () => {
</Main>
)
}
export default Login;
\ No newline at end of file
......
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { useHistory, useLocation } from 'react-router';
import { Main } from '../components/common/Main';
import Main from '../components/common/Main';
import { MessageResponse, MessageType, RawMessage } from '../components/common/types';
import { Canvas } from '../components/room/Canvas';
import { Chat } from '../components/room/Chat';
import { GameBoard } from '../components/room/GameBoard';
import { Ready } from '../components/room/Ready';
import { RoomInfo } from '../components/room/RoomInfo';
import Chat from '../components/room/Chat';
import GameBoard from '../components/room/GameBoard';
import Ready from '../components/room/Ready';
import RoomInfo from '../components/room/RoomInfo';
import { RoomData, UpdateRoomUser } from '../components/room/types';
import { UserInfo } from '../components/room/UserInfo';
import { UserRole } from '../components/room/UserRole';
import { UserStatus } from '../components/room/UserStatus';
import UserInfo from '../components/room/UserInfo';
import UserRole from '../components/room/UserRole';
import SocketContext from '../contexts/SocketContext';
interface RoomLocation {
state: { roomData: RoomData }
}
export const Room: React.FC = () => {
const Room: React.FC = () => {
const history = useHistory();
const socket = useContext(SocketContext);
const location: RoomLocation = useLocation();
......@@ -40,9 +38,9 @@ export const Room: React.FC = () => {
}, []);
const handleUpdateRoomUser = useCallback((rawMessage: RawMessage) => {
if (rawMessage.type == MessageType.ROOM_USER_UPDATE) {
if (rawMessage.type === MessageType.ROOM_USER_UPDATE) {
const data = rawMessage.message as UpdateRoomUser;
if (data.state == 'removed') {
if (data.state === 'removed') {
const newUsers = roomData.users;
const index = newUsers.findIndex(x => x.username === data.user.username);
if (index < 0) {
......@@ -81,7 +79,7 @@ export const Room: React.FC = () => {
return () => {
socket.off('msg', handleUpdateRoomUser);
}
}, [roomData]);
}, [handleUpdateRoomUser]);
useEffect(() => {
// 비정상적인 루트로 방을 들어오면 로그인 화면으로 푸시
......@@ -102,7 +100,7 @@ export const Room: React.FC = () => {
}
socket.emit('msg', rawMessage, (response : MessageResponse<undefined>) => {});
}
}, [])
}, [location.state]);
return (
<Main>
......@@ -126,3 +124,5 @@ export const Room: React.FC = () => {
</Main>
);
}
export default Room;
\ No newline at end of file
......
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { useHistory } from 'react-router';
import { Main } from '../components/common/Main';
import Main from '../components/common/Main';
import { MessageResponse, MessageType, RawMessage } from '../components/common/types';
import { Create } from '../components/rooms/Create';
import { Refresh } from '../components/rooms/Refrsh';
import { RoomBlock } from '../components/rooms/RoomBlock';
import Create from '../components/rooms/Create';
import Refresh from '../components/rooms/Refrsh';
import RoomBlock from '../components/rooms/RoomBlock';
import { Room } from '../components/rooms/types';
import SocketContext from '../contexts/SocketContext';
export const Rooms: React.FC = () => {
const Rooms: React.FC = () => {
const history = useHistory();
const socket = useContext(SocketContext);
const [ rooms, setRooms ] = useState<Room[]>([]);
......@@ -42,3 +42,5 @@ export const Rooms: React.FC = () => {
</Main>
)
}
export default Rooms;
\ No newline at end of file
......