added joining to room
This commit is contained in:
parent
a1b39a3a45
commit
f318afe071
@ -17,8 +17,9 @@ const getJoinableRoom = async () => {
|
|||||||
return await Room.findOne({ full: false, started: false }).exec();
|
return await Room.findOne({ full: false, started: false }).exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
const createNewRoom = () => {
|
const createNewRoom = data => {
|
||||||
const room = new Room();
|
const room = new Room(data);
|
||||||
|
room.save();
|
||||||
return room;
|
return room;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
const { getRoom, updateRoom, getJoinableRoom, createNewRoom, findPlayer } = require('../controllers/roomController');
|
const { getRoom, updateRoom } = require('../controllers/roomController');
|
||||||
const { colors } = require('../utils/constants');
|
const { colors } = require('../utils/constants');
|
||||||
|
|
||||||
module.exports = socket => {
|
module.exports = socket => {
|
||||||
const req = socket.request;
|
const req = socket.request;
|
||||||
|
|
||||||
const handleLogin = async data => {
|
const handleLogin = async data => {
|
||||||
if (await findPlayer(req.sessionID)) return;
|
const room = await getRoom(data.roomId);
|
||||||
const room = await getJoinableRoom();
|
if (room.isFull()) return socket.emit('error:changeRoom');
|
||||||
if (room) {
|
if (room.started) return socket.emit('error:changeRoom');
|
||||||
|
if (room.private && room.password !== data.password) return socket.emit('error:wrongPassword');
|
||||||
addPlayerToExistingRoom(room, data);
|
addPlayerToExistingRoom(room, data);
|
||||||
} else {
|
|
||||||
addNewRoom(data);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReady = async () => {
|
const handleReady = async () => {
|
||||||
@ -23,13 +21,6 @@ module.exports = socket => {
|
|||||||
await updateRoom(room);
|
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) => {
|
const addPlayerToExistingRoom = async (room, data) => {
|
||||||
room.addPlayer(data.name);
|
room.addPlayer(data.name);
|
||||||
if (room.isFull()) {
|
if (room.isFull()) {
|
||||||
|
|||||||
@ -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');
|
const { sendToOnePlayerRooms, sendToOnePlayerData, sendToPlayersData } = require('../socket/emits');
|
||||||
|
|
||||||
module.exports = socket => {
|
module.exports = socket => {
|
||||||
const req = socket.request;
|
const req = socket.request;
|
||||||
|
|
||||||
const getData = async () => {
|
const handleGetData = async () => {
|
||||||
const room = await getRoom(req.session.roomId);
|
const room = await getRoom(req.session.roomId);
|
||||||
// Handle the situation when the server crashes and any player reconnects after the time has expired
|
// 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.
|
// Typically, the responsibility for changing players is managed by gameHandler.js.
|
||||||
@ -15,23 +15,17 @@ module.exports = socket => {
|
|||||||
sendToOnePlayerData(socket.id, room);
|
sendToOnePlayerData(socket.id, room);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAllRooms = async () => {
|
const handleGetAllRooms = async () => {
|
||||||
let rooms = await getRooms();
|
let rooms = await getRooms();
|
||||||
const response = [];
|
sendToOnePlayerRooms(socket.id, rooms);
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.on('room:data', getData);
|
const handleCreateRoom = async data => {
|
||||||
socket.on('room:rooms', getAllRooms);
|
createNewRoom(data);
|
||||||
|
socket.to(socket.id).emit('room:created');
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.on('room:data', handleGetData);
|
||||||
|
socket.on('room:rooms', handleGetAllRooms);
|
||||||
|
socket.on('room:create', handleCreateRoom);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,7 +7,7 @@ const PlayerSchema = require('./player');
|
|||||||
|
|
||||||
const RoomSchema = new mongoose.Schema({
|
const RoomSchema = new mongoose.Schema({
|
||||||
name: String,
|
name: String,
|
||||||
private: { type: Boolean, default: true },
|
private: { type: Boolean, default: false },
|
||||||
password: String,
|
password: String,
|
||||||
createDate: { type: Date, default: Date.now },
|
createDate: { type: Date, default: Date.now },
|
||||||
started: { type: Boolean, default: false },
|
started: { type: Boolean, default: false },
|
||||||
|
|||||||
35
src/components/LoginPage/AddServer/AddServer.css
Normal file
35
src/components/LoginPage/AddServer/AddServer.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
58
src/components/LoginPage/AddServer/AddServer.jsx
Normal file
58
src/components/LoginPage/AddServer/AddServer.jsx
Normal file
@ -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 (
|
||||||
|
<div className='lp-container'>
|
||||||
|
<div className='title-container'>
|
||||||
|
<h1>Host A Server</h1>
|
||||||
|
</div>
|
||||||
|
<div className='content-container'>
|
||||||
|
<form>
|
||||||
|
<input
|
||||||
|
type='text'
|
||||||
|
value={serverName}
|
||||||
|
onChange={e => setServerName(e.target.value)}
|
||||||
|
placeholder='Server Name'
|
||||||
|
/>
|
||||||
|
<div className='private-container'>
|
||||||
|
<p>Private</p>
|
||||||
|
<Switch checked={isPrivate} color='primary' onChange={() => setIsPrivate(!isPrivate)} />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type='text'
|
||||||
|
value={password}
|
||||||
|
onChange={e => setPassword(e.target.value)}
|
||||||
|
placeholder='password'
|
||||||
|
disabled={!isPrivate}
|
||||||
|
/>
|
||||||
|
<button onClick={handleButtonClick}>Host</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddServer;
|
||||||
@ -1,76 +1,53 @@
|
|||||||
.login-page-container {
|
.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;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 50vh;
|
width: 500px;
|
||||||
width: 400px;
|
|
||||||
position: relative;
|
|
||||||
padding: 20px;
|
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;
|
color: white;
|
||||||
}
|
}
|
||||||
.rooms {
|
|
||||||
width: 98%;
|
.title-container {
|
||||||
height: 80%;
|
|
||||||
overflow-y: scroll;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
.room {
|
|
||||||
cursor: pointer;
|
|
||||||
justify-content: space-between;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: white;
|
width: 100%;
|
||||||
width: 90%;
|
height: 40px;
|
||||||
margin: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid black;
|
|
||||||
}
|
|
||||||
.room-selected {
|
|
||||||
border: 1px solid white;
|
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 {
|
.title-container > h1 {
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
.number-of-players {
|
|
||||||
|
.content-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
align-items: center;
|
width: 100%;
|
||||||
}
|
padding: 10px;
|
||||||
.number-of-players > img {
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
margin-right: 5px;
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||||
width: 20px;
|
border-left: 1px solid black;
|
||||||
height: 20px;
|
border-right: 1px solid black;
|
||||||
}
|
border-bottom: 1px solid black;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,54 +1,16 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
|
||||||
import NameInput from './NameInput/NameInput';
|
|
||||||
import { SocketContext } from '../../App';
|
|
||||||
import './LoginPage.css';
|
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 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 (
|
return (
|
||||||
|
<>
|
||||||
<div className='login-page-container'>
|
<div className='login-page-container'>
|
||||||
<h1>Select room:</h1>
|
<ServerList />
|
||||||
<div className='rooms'>
|
<AddServer />
|
||||||
{rooms.map(room => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={selectedRoom && selectedRoom == room._id ? 'room-selected room' : 'room'}
|
|
||||||
onClick={() => {
|
|
||||||
if (selectedRoom && selectedRoom == room._id) {
|
|
||||||
setSelectedRoom(null);
|
|
||||||
} else {
|
|
||||||
setSelectedRoom(room._id);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
key={room.id}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<p>{room.name}</p>
|
|
||||||
{room.players.map(player => player.name + ' ')}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='number-of-players'>
|
|
||||||
<img src={userImage} alt='' />
|
|
||||||
<span> {room.players.length}/4 </span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<NameInput />
|
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LoginPage;
|
export default LoginPage;
|
||||||
|
|||||||
@ -1,11 +1,34 @@
|
|||||||
.name-input-container {
|
.name-input-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
flex-direction: column;
|
||||||
bottom: 0;
|
padding: 10px 20px 60px 20px;
|
||||||
flex-direction: row;
|
width: 300px;
|
||||||
width: 80%;
|
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;
|
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,
|
input,
|
||||||
button {
|
button {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -21,7 +44,7 @@ input {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
color: white;
|
color: white;
|
||||||
border: 1px solid #ccc;
|
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;
|
transition: border-color 0.3s ease-in-out, background-color 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +60,7 @@ button {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: none;
|
border: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.3s ease-in-out;
|
transition: background-color 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,45 @@
|
|||||||
import React, { useState, useContext } from 'react';
|
import React, { useState, useContext, useEffect } from 'react';
|
||||||
import { SocketContext } from '../../../App';
|
import { SocketContext } from '../../../App';
|
||||||
import './NameInput.css';
|
import './NameInput.css';
|
||||||
const NameInput = () => {
|
const NameInput = ({ isRoomPrivate, roomId }) => {
|
||||||
const socket = useContext(SocketContext);
|
const socket = useContext(SocketContext);
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [nickname, setNickname] = useState('');
|
||||||
const handleInputChange = e => {
|
const [password, setPassword] = useState('');
|
||||||
setInputValue(e.target.value);
|
const [isPasswordWrong, setIsPasswordWrong] = useState(false);
|
||||||
};
|
|
||||||
const handleButtonClick = () => {
|
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 (
|
return (
|
||||||
<div className="name-input-container">
|
<div className='name-overlay'>
|
||||||
<input placeholder='Enter name' type='text' onChange={handleInputChange} />
|
<div className='name-input-container' style={{ height: isRoomPrivate ? '100px' : '50px' }}>
|
||||||
|
<input placeholder='Nickname' type='text' onChange={e => setNickname(e.target.value)} />
|
||||||
|
{isRoomPrivate ? (
|
||||||
|
<input
|
||||||
|
placeholder='Room password'
|
||||||
|
type='text'
|
||||||
|
onChange={e => setPassword(e.target.value)}
|
||||||
|
style={{ backgroundColor: isPasswordWrong ? 'red' : null }}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
<button onClick={handleButtonClick}>JOIN</button>
|
<button onClick={handleButtonClick}>JOIN</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
51
src/components/LoginPage/ServerList/ServerList.css
Normal file
51
src/components/LoginPage/ServerList/ServerList.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
79
src/components/LoginPage/ServerList/ServerList.jsx
Normal file
79
src/components/LoginPage/ServerList/ServerList.jsx
Normal file
@ -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 (
|
||||||
|
<div className='lp-container'>
|
||||||
|
<div className='title-container'>
|
||||||
|
<h1>Server List</h1>
|
||||||
|
<div className='refresh'>
|
||||||
|
<img src={refresh} onClick={getRooms}></img>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='server-container content-container'>
|
||||||
|
{rooms ? (
|
||||||
|
<table className='rooms'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Server</th>
|
||||||
|
<th>#/#</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{rooms.map((room, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td>{room.private ? <img src={lock} /> : null}</td>
|
||||||
|
<td className='room-name'>{room.name}</td>
|
||||||
|
<td>{`${room.players.length}/4`}</td>
|
||||||
|
<td>{room.isStarted ? 'started' : 'waiting'}</td>
|
||||||
|
<td>
|
||||||
|
<button onClick={() => handleJoinClick(room)}>Join</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
) : (
|
||||||
|
<div style={{ alignSelf: 'center' }}>
|
||||||
|
<ReactLoading type='spinningBubbles' color='white' height={50} width={50} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{joining ? (
|
||||||
|
<NameInput roomId={clickedRoom._id} isRoomPrivate={clickedRoom.private} />
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default ServerList;
|
||||||
@ -14,7 +14,7 @@ const AnimatedOverlay = ({ time }) => {
|
|||||||
in={true}
|
in={true}
|
||||||
timeout={0}
|
timeout={0}
|
||||||
classNames='overlay'
|
classNames='overlay'
|
||||||
style={{ 'animation-delay': `-${animationDelay}s` }}
|
style={{ animationDelay: `-${animationDelay}s` }}
|
||||||
unmountOnExit
|
unmountOnExit
|
||||||
>
|
>
|
||||||
<div className='overlay'></div>
|
<div className='overlay'></div>
|
||||||
|
|||||||
BIN
src/images/login-page/lock.png
Normal file
BIN
src/images/login-page/lock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
src/images/login-page/refresh.png
Normal file
BIN
src/images/login-page/refresh.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 8.9 KiB |
Loading…
Reference in New Issue
Block a user