Toggle navigation
Toggle navigation
This project
Loading...
Sign in
강동현
/
nodejs-game
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
Overnap
2021-06-10 08:48:40 +0900
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
108402819d590f24b0cd96b2d46a2e2f661ccc75
10840281
2 parents
6f55e02b
a4948d98
Merge branch 'refactor' into develop
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
117 additions
and
80 deletions
web/src/App.tsx
web/src/components/common/Footer.tsx
web/src/components/common/Main.tsx
web/src/components/room/Canvas.tsx
web/src/components/room/Chat.tsx
web/src/components/room/ChatLine.tsx
web/src/components/room/GameBoard.tsx
web/src/components/room/Ready.tsx
web/src/components/room/RoomInfo.tsx
web/src/components/room/RoundInfo.tsx
web/src/components/room/Timer.tsx
web/src/components/room/UserInfo.tsx
web/src/components/room/UserRole.tsx
web/src/components/room/UserStatus.tsx
web/src/components/room/Word.tsx
web/src/components/rooms/Create.tsx
web/src/components/rooms/Refrsh.tsx
web/src/components/rooms/RoomBlock.tsx
web/src/pages/Login.tsx
web/src/pages/Room.tsx
web/src/pages/Rooms.tsx
web/src/App.tsx
View file @
1084028
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 (
...
...
web/src/components/common/Footer.tsx
View file @
1084028
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
<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>
<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>
</div>
</div>
);
}
\ No newline at end of file
}
export default Footer;
\ No newline at end of file
...
...
web/src/components/common/Main.tsx
View file @
1084028
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}
<Footer/>
</div>
);
}
\ No newline at end of file
}
export default Main;
\ No newline at end of file
...
...
web/src/components/room/Canvas.tsx
View file @
1084028
...
...
@@ -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);
...
...
@@ -185,4 +185,6 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => {
<canvas ref={canvasRef} width='640' height='480' />
</div>
);
}
\ No newline at end of file
}
export default Canvas;
\ No newline at end of file
...
...
web/src/components/room/Chat.tsx
View file @
1084028
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[]>([]);
...
...
@@ -86,4 +86,6 @@ export const Chat: React.FC<ChatProps> = (props) => {
onKeyPress={handleEnter}></input>
</div>
);
}
\ No newline at end of file
}
export default Chat;
\ No newline at end of file
...
...
web/src/components/room/ChatLine.tsx
View file @
1084028
...
...
@@ -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
...
...
web/src/components/room/GameBoard.tsx
View file @
1084028
...
...
@@ -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 { Ro
le, Ro
undData } 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'>
...
...
@@ -85,4 +91,6 @@ export const GameBoard: React.FC<GameBoardProps> = ({ isInGame }) => {
<RoundInfo round={round} wordChosen={wordChosen} />
</div>
);
}
\ No newline at end of file
}
export default GameBoard;
\ No newline at end of file
...
...
web/src/components/room/Ready.tsx
View file @
1084028
...
...
@@ -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
...
...
web/src/components/room/RoomInfo.tsx
View file @
1084028
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>
<div>{roomData.users.length}/{roomData.maxUsers}</div>
</div>
);
}
\ No newline at end of file
}
export default RoomInfo;
\ No newline at end of file
...
...
web/src/components/room/RoundInfo.tsx
View file @
1084028
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 />
...
...
@@ -16,4 +14,6 @@ export const RoundInfo: React.FC<RoundInfoProps> = ({ round, wordChosen }) => {
<div>Round {round}/5</div>
</div>
);
}
\ No newline at end of file
}
export default RoundInfo;
\ No newline at end of file
...
...
web/src/components/room/Timer.tsx
View file @
1084028
...
...
@@ -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);
...
...
@@ -52,4 +52,6 @@ export const Timer: React.FC = () => {
🕒 {time}
</div>
);
}
\ No newline at end of file
}
export default Timer;
\ No newline at end of file
...
...
web/src/components/room/UserInfo.tsx
View file @
1084028
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>
);
}
\ No newline at end of file
}
export default UserInfo
\ No newline at end of file
...
...
web/src/components/room/UserRole.tsx
View file @
1084028
...
...
@@ -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;
...
...
web/src/components/room/UserStatus.tsx
View file @
1084028
...
...
@@ -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' :
...
...
@@ -15,4 +15,6 @@ export const UserStatus: React.FC<UserStatusProps> = ({ user }) => {
{user.nickname}</div>
</div>
)
}
\ No newline at end of file
}
export default UserStatus;
\ No newline at end of file
...
...
web/src/components/room/Word.tsx
View file @
1084028
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
...
...
web/src/components/rooms/Create.tsx
View file @
1084028
...
...
@@ -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
...
...
web/src/components/rooms/Refrsh.tsx
View file @
1084028
...
...
@@ -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
...
...
web/src/components/rooms/RoomBlock.tsx
View file @
1084028
...
...
@@ -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
...
...
web/src/pages/Login.tsx
View file @
1084028
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
...
...
web/src/pages/Room.tsx
View file @
1084028
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>
...
...
@@ -125,4 +123,6 @@ export const Room: React.FC = () => {
</div>
</Main>
);
}
\ No newline at end of file
}
export default Room;
\ No newline at end of file
...
...
web/src/pages/Rooms.tsx
View file @
1084028
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
...
...
Please
register
or
login
to post a comment