diff --git a/backend/controllers/roomController.js b/backend/controllers/roomController.js
index f698a3e..80a36ac 100644
--- a/backend/controllers/roomController.js
+++ b/backend/controllers/roomController.js
@@ -17,8 +17,9 @@ const getJoinableRoom = async () => {
return await Room.findOne({ full: false, started: false }).exec();
};
-const createNewRoom = () => {
- const room = new Room();
+const createNewRoom = data => {
+ const room = new Room(data);
+ room.save();
return room;
};
diff --git a/backend/handlers/playerHandler.js b/backend/handlers/playerHandler.js
index 2918d92..825d568 100644
--- a/backend/handlers/playerHandler.js
+++ b/backend/handlers/playerHandler.js
@@ -1,17 +1,15 @@
-const { getRoom, updateRoom, getJoinableRoom, createNewRoom, findPlayer } = require('../controllers/roomController');
+const { getRoom, updateRoom } = require('../controllers/roomController');
const { colors } = require('../utils/constants');
module.exports = socket => {
const req = socket.request;
const handleLogin = async data => {
- if (await findPlayer(req.sessionID)) return;
- const room = await getJoinableRoom();
- if (room) {
- addPlayerToExistingRoom(room, data);
- } else {
- addNewRoom(data);
- }
+ const room = await getRoom(data.roomId);
+ if (room.isFull()) return socket.emit('error:changeRoom');
+ if (room.started) return socket.emit('error:changeRoom');
+ if (room.private && room.password !== data.password) return socket.emit('error:wrongPassword');
+ addPlayerToExistingRoom(room, data);
};
const handleReady = async () => {
@@ -23,13 +21,6 @@ module.exports = socket => {
await updateRoom(room);
};
- const addNewRoom = async data => {
- const room = createNewRoom();
- room.addPlayer(data.name, req.sessionID);
- await room.save();
- reloadSession(room);
- };
-
const addPlayerToExistingRoom = async (room, data) => {
room.addPlayer(data.name);
if (room.isFull()) {
diff --git a/backend/handlers/roomHandler.js b/backend/handlers/roomHandler.js
index fbde0d6..bee90de 100644
--- a/backend/handlers/roomHandler.js
+++ b/backend/handlers/roomHandler.js
@@ -1,10 +1,10 @@
-const { getRooms, getRoom, updateRoom } = require('../controllers/roomController');
+const { getRooms, getRoom, updateRoom, createNewRoom } = require('../controllers/roomController');
const { sendToOnePlayerRooms, sendToOnePlayerData, sendToPlayersData } = require('../socket/emits');
module.exports = socket => {
const req = socket.request;
- const getData = async () => {
+ const handleGetData = async () => {
const room = await getRoom(req.session.roomId);
// Handle the situation when the server crashes and any player reconnects after the time has expired
// Typically, the responsibility for changing players is managed by gameHandler.js.
@@ -15,23 +15,17 @@ module.exports = socket => {
sendToOnePlayerData(socket.id, room);
};
- const getAllRooms = async () => {
+ const handleGetAllRooms = async () => {
let rooms = await getRooms();
- const response = [];
- rooms.forEach(room => {
- if (!room.isStarted && !room.isFull()) {
- response.push({
- _id: room._id,
- private: room.private,
- name: room.name,
- players: room.players,
- isStarted: room.isStarted,
- });
- }
- });
- sendToOnePlayerRooms(socket.id, response);
+ sendToOnePlayerRooms(socket.id, rooms);
};
- socket.on('room:data', getData);
- socket.on('room:rooms', getAllRooms);
+ const handleCreateRoom = async data => {
+ createNewRoom(data);
+ socket.to(socket.id).emit('room:created');
+ };
+
+ socket.on('room:data', handleGetData);
+ socket.on('room:rooms', handleGetAllRooms);
+ socket.on('room:create', handleCreateRoom);
};
diff --git a/backend/models/room.js b/backend/models/room.js
index c1672d4..2c7ca34 100644
--- a/backend/models/room.js
+++ b/backend/models/room.js
@@ -7,7 +7,7 @@ const PlayerSchema = require('./player');
const RoomSchema = new mongoose.Schema({
name: String,
- private: { type: Boolean, default: true },
+ private: { type: Boolean, default: false },
password: String,
createDate: { type: Date, default: Date.now },
started: { type: Boolean, default: false },
diff --git a/src/components/LoginPage/AddServer/AddServer.css b/src/components/LoginPage/AddServer/AddServer.css
new file mode 100644
index 0000000..4c64921
--- /dev/null
+++ b/src/components/LoginPage/AddServer/AddServer.css
@@ -0,0 +1,35 @@
+.refresh {
+ display: flex;
+ margin-left: auto;
+ justify-content: center;
+ align-items: center;
+ width: 40px;
+ height: 100%;
+ border: 1px solid white;
+}
+.refresh > img {
+ width: 20px;
+ height: 20px;
+ cursor: pointer;
+}
+
+form {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+}
+
+.private-container {
+ margin-left: 10px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ width: 100%;
+}
+input:disabled {
+ background-color: black;
+ color: #999;
+ border: 1px solid #ddd;
+}
diff --git a/src/components/LoginPage/AddServer/AddServer.jsx b/src/components/LoginPage/AddServer/AddServer.jsx
new file mode 100644
index 0000000..054bf54
--- /dev/null
+++ b/src/components/LoginPage/AddServer/AddServer.jsx
@@ -0,0 +1,58 @@
+import React, { useState, useContext, useEffect } from 'react';
+import './AddServer.css';
+import Switch from '@material-ui/core/Switch';
+import { SocketContext } from '../../../App';
+const AddServer = () => {
+ const socket = useContext(SocketContext);
+ const [isPrivate, setIsPrivate] = useState(false);
+ const [serverName, setServerName] = useState('');
+ const [password, setPassword] = useState('');
+
+ useEffect(() => {
+ socket.on('room:created', () => {
+ console.log('ewa');
+ socket.emit('room:rooms');
+ });
+ }, []);
+
+ const handleButtonClick = e => {
+ e.preventDefault();
+ socket.emit('room:create', {
+ name: serverName,
+ private: isPrivate,
+ password: password,
+ });
+ };
+
+ return (
+
+ );
+};
+
+export default AddServer;
diff --git a/src/components/LoginPage/LoginPage.css b/src/components/LoginPage/LoginPage.css
index 62099aa..3376c6f 100644
--- a/src/components/LoginPage/LoginPage.css
+++ b/src/components/LoginPage/LoginPage.css
@@ -1,76 +1,53 @@
.login-page-container {
+ display: flex;
+ flex-direction: row;
+
+ justify-content: center;
+ align-items: flex-start;
+ height: 50%;
+ width: 100%;
+}
+
+.lp-container {
+ margin: 50px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
- height: 50vh;
- width: 400px;
- position: relative;
+ width: 500px;
padding: 20px;
- border-radius: 5%;
- border: 5px solid white;
- background-color: rgba(0, 0, 0, 0.5);
-}
-h1 {
- margin-right: 10px;
- align-self: flex-start;
- top: 0;
- position: absolute;
color: white;
}
-.rooms {
- width: 98%;
- height: 80%;
- overflow-y: scroll;
- overflow-x: hidden;
-}
-.room {
- cursor: pointer;
- justify-content: space-between;
+
+.title-container {
display: flex;
flex-direction: row;
+ justify-content: center;
align-items: center;
- color: white;
- width: 90%;
- margin: 10px;
- padding: 10px;
- border: 1px solid black;
-}
-.room-selected {
+ width: 100%;
+ height: 40px;
border: 1px solid white;
+ border-radius: 2px;
+ transform: scaleX(1.02);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+ padding-left: 10px;
+ text-align: center;
}
-.room-selected,
-.room:hover {
- background-color: rgba(0, 0, 0, 0.5);
+
+.title-container > h1 {
+ width: 100%;
+ margin: 0;
+ padding: 0;
}
-.number-of-players {
+
+.content-container {
display: flex;
- flex-direction: row;
- align-items: center;
-}
-.number-of-players > img {
- margin-right: 5px;
- width: 20px;
- height: 20px;
-}
-
-/* Firefox */
-* {
- scrollbar-width: auto;
- scrollbar-color: #ffffff rgba(0, 0, 0, 0.1);
-}
-
-/* Chrome, Edge, and Safari */
-*::-webkit-scrollbar {
- width: 8px;
-}
-
-*::-webkit-scrollbar-track {
- background: rgba(0, 0, 0, 0);
-}
-
-*::-webkit-scrollbar-thumb {
- background-color: #ffffff;
- border-radius: 10px;
- border: 3px none #ffffff;
+ flex-direction: column;
+ width: 100%;
+ padding: 10px;
+ background-color: rgba(0, 0, 0, 0.5);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+ border-left: 1px solid black;
+ border-right: 1px solid black;
+ border-bottom: 1px solid black;
}
diff --git a/src/components/LoginPage/LoginPage.jsx b/src/components/LoginPage/LoginPage.jsx
index 835787d..9532e2d 100644
--- a/src/components/LoginPage/LoginPage.jsx
+++ b/src/components/LoginPage/LoginPage.jsx
@@ -1,54 +1,16 @@
-import React, { useContext, useEffect, useState } from 'react';
-import NameInput from './NameInput/NameInput';
-import { SocketContext } from '../../App';
import './LoginPage.css';
-import userImage from '../../images/login-page/user.png';
+import AddServer from './AddServer/AddServer';
+import ServerList from './ServerList/ServerList';
+import NameInput from './NameInput/NameInput';
const LoginPage = () => {
- const socket = useContext(SocketContext);
- const [rooms, setRooms] = useState([]);
- const [selectedRoom, setSelectedRoom] = useState(null);
-
- useEffect(async () => {
- socket.emit('room:rooms');
- socket.on('room:rooms', data => {
- data = JSON.parse(data);
- console.log(data);
- setRooms(data);
- });
- }, []);
-
return (
-
-
Select room:
-
- {rooms.map(room => {
- return (
-
{
- if (selectedRoom && selectedRoom == room._id) {
- setSelectedRoom(null);
- } else {
- setSelectedRoom(room._id);
- }
- }}
- key={room.id}
- >
-
-
{room.name}
- {room.players.map(player => player.name + ' ')}
-
-
-
-

-
{room.players.length}/4
-
-
- );
- })}
+ <>
+
-
-
+ >
);
};
+
export default LoginPage;
diff --git a/src/components/LoginPage/NameInput/NameInput.css b/src/components/LoginPage/NameInput/NameInput.css
index f7509fe..9f6282c 100644
--- a/src/components/LoginPage/NameInput/NameInput.css
+++ b/src/components/LoginPage/NameInput/NameInput.css
@@ -1,11 +1,34 @@
.name-input-container {
display: flex;
- position: absolute;
- bottom: 0;
- flex-direction: row;
- width: 80%;
+ flex-direction: column;
+ padding: 10px 20px 60px 20px;
+ width: 300px;
+ background: radial-gradient(circle, rgba(0, 138, 255, 1) 5%, rgba(9, 9, 121, 1) 81%);
+ border: 1px solid white;
+ border-radius: 8px;
margin: 20px;
}
+.name-input-container > button {
+ margin-top: 5px;
+ text-align: center;
+ width: 100px;
+ align-self: center;
+}
+.name-input-container > input {
+ margin-top: 10px;
+}
+.name-overlay {
+ position: absolute;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.5);
+ z-index: 1;
+}
input,
button {
padding: 0;
@@ -21,7 +44,7 @@ input {
border-radius: 8px;
color: white;
border: 1px solid #ccc;
- background-color: rgba(0, 0, 0, 0.5);
+ background-color: rgba(0, 0, 0, 0.2);
transition: border-color 0.3s ease-in-out, background-color 0.3s ease-in-out;
}
@@ -37,7 +60,7 @@ button {
border-radius: 8px;
border: none;
color: #fff;
- background-color: rgba(0, 0, 0, 0.5);
+ background-color: rgba(0, 0, 0, 0.4);
cursor: pointer;
transition: background-color 0.3s ease-in-out;
}
diff --git a/src/components/LoginPage/NameInput/NameInput.jsx b/src/components/LoginPage/NameInput/NameInput.jsx
index 491c56b..e1212e4 100644
--- a/src/components/LoginPage/NameInput/NameInput.jsx
+++ b/src/components/LoginPage/NameInput/NameInput.jsx
@@ -1,19 +1,44 @@
-import React, { useState, useContext } from 'react';
+import React, { useState, useContext, useEffect } from 'react';
import { SocketContext } from '../../../App';
import './NameInput.css';
-const NameInput = () => {
+const NameInput = ({ isRoomPrivate, roomId }) => {
const socket = useContext(SocketContext);
- const [inputValue, setInputValue] = useState('');
- const handleInputChange = e => {
- setInputValue(e.target.value);
- };
+ const [nickname, setNickname] = useState('');
+ const [password, setPassword] = useState('');
+ const [isPasswordWrong, setIsPasswordWrong] = useState(false);
const handleButtonClick = () => {
- socket.emit('player:login', { name: inputValue });
+ socket.emit('player:login', { name: nickname, password: password, roomId: roomId });
};
+ useEffect(() => {
+ socket.on('error:wrongPassword', () => {
+ setIsPasswordWrong(true);
+ });
+ const keyDownHandler = event => {
+ if (event.key === 'Enter') {
+ event.preventDefault();
+ handleButtonClick();
+ }
+ };
+ document.addEventListener('keydown', keyDownHandler);
+ return () => {
+ document.removeEventListener('keydown', keyDownHandler);
+ };
+ }, []);
+
return (
-
-
-
+
);
};
diff --git a/src/components/LoginPage/ServerList/ServerList.css b/src/components/LoginPage/ServerList/ServerList.css
new file mode 100644
index 0000000..318a008
--- /dev/null
+++ b/src/components/LoginPage/ServerList/ServerList.css
@@ -0,0 +1,51 @@
+th {
+ text-align: left;
+}
+img {
+ margin-right: 5px;
+ width: 20px;
+ height: 20px;
+}
+th,
+td {
+ padding: 8px;
+ text-align: left;
+ height: 50px;
+}
+tr {
+ max-height: 50px;
+}
+
+table {
+ border-collapse: collapse;
+ width: 100%;
+}
+.server-container {
+ display: flex;
+ height: 500px;
+ overflow: scroll;
+}
+.room-name {
+ max-width: 150px;
+ overflow: hidden;
+}
+/* Firefox */
+* {
+ scrollbar-width: auto;
+ scrollbar-color: #ffffff rgba(0, 0, 0, 0.1);
+}
+
+/* Chrome, Edge, and Safari */
+*::-webkit-scrollbar {
+ background: rgba(0, 0, 0, 0);
+ width: 10px;
+}
+
+*::-webkit-scrollbar-track {
+ background: rgba(0, 0, 0, 0);
+}
+
+*::-webkit-scrollbar-thumb {
+ background-color: #ffffff;
+ border-radius: 10px;
+}
diff --git a/src/components/LoginPage/ServerList/ServerList.jsx b/src/components/LoginPage/ServerList/ServerList.jsx
new file mode 100644
index 0000000..28e55a2
--- /dev/null
+++ b/src/components/LoginPage/ServerList/ServerList.jsx
@@ -0,0 +1,79 @@
+import React, { useContext, useEffect, useState } from 'react';
+import { SocketContext } from '../../../App';
+import lock from '../../../images/login-page/lock.png';
+import refresh from '../../../images/login-page/refresh.png';
+import ReactLoading from 'react-loading';
+
+import './ServerList.css';
+import NameInput from '../NameInput/NameInput';
+
+const ServerList = () => {
+ const socket = useContext(SocketContext);
+ const [rooms, setRooms] = useState([]);
+ const [joining, setJoining] = useState(false);
+ const [clickedRoom, setClickedRoom] = useState(null);
+ useEffect(async () => {
+ socket.emit('room:rooms');
+ socket.on('room:rooms', data => {
+ data = JSON.parse(data);
+ setRooms(data);
+ });
+ }, []);
+
+ const getRooms = () => {
+ setRooms(null);
+ socket.emit('room:rooms');
+ };
+
+ const handleJoinClick = room => {
+ setClickedRoom(room);
+ setJoining(true);
+ };
+
+ return (
+
+
+
Server List
+
+

+
+
+
+ {rooms ? (
+
+
+
+ |
+ Server |
+ #/# |
+ Status |
+ |
+
+
+
+ {rooms.map((room, index) => (
+
+ {room.private ? : null} |
+ {room.name} |
+ {`${room.players.length}/4`} |
+ {room.isStarted ? 'started' : 'waiting'} |
+
+
+ |
+
+ ))}
+
+
+ ) : (
+
+
+
+ )}
+
+ {joining ? (
+
+ ) : null}
+
+ );
+};
+export default ServerList;
diff --git a/src/components/navbar-components/AnimatedOverlay.jsx b/src/components/navbar-components/AnimatedOverlay.jsx
index 82b1507..5fc82fa 100644
--- a/src/components/navbar-components/AnimatedOverlay.jsx
+++ b/src/components/navbar-components/AnimatedOverlay.jsx
@@ -14,7 +14,7 @@ const AnimatedOverlay = ({ time }) => {
in={true}
timeout={0}
classNames='overlay'
- style={{ 'animation-delay': `-${animationDelay}s` }}
+ style={{ animationDelay: `-${animationDelay}s` }}
unmountOnExit
>
diff --git a/src/images/login-page/lock.png b/src/images/login-page/lock.png
new file mode 100644
index 0000000..8e56993
Binary files /dev/null and b/src/images/login-page/lock.png differ
diff --git a/src/images/login-page/refresh.png b/src/images/login-page/refresh.png
new file mode 100644
index 0000000..25988e6
Binary files /dev/null and b/src/images/login-page/refresh.png differ
diff --git a/src/images/login-page/user.png b/src/images/login-page/user.png
index 6d15e9e..0fa4040 100644
Binary files a/src/images/login-page/user.png and b/src/images/login-page/user.png differ