mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-05-13 17:11:49 +00:00
refacto: devweb - structure modal and game websocket script in js files
+ feat: devweb - add admin to a game
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
<jsp:attribute name="head">
|
||||
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/card.css">
|
||||
<script defer type="module" src="${pageContext.request.contextPath}/static/js/websockets/player-management-websocket.js"></script>
|
||||
<script defer type="module" src="${pageContext.request.contextPath}/static/js/websockets/game-management-websocket.js"></script>
|
||||
<script defer type="module" src="${pageContext.request.contextPath}/static/js/modal.js"></script>
|
||||
</jsp:attribute>
|
||||
<jsp:body>
|
||||
@@ -21,7 +22,7 @@
|
||||
<jsp:attribute name="footer">
|
||||
<div class="card-footer">
|
||||
<a id="leave-game-button" href="${pageContext.request.contextPath}/lobby" class="is-primary card-footer-item">${translator.translate('game_room_leave_game')}</a>
|
||||
<a data-target="#user-list-modal" class="card-footer-item modal-trigger">${translator.translate('game_room_add_player')}</a>
|
||||
<a id="invite-player" data-target="#user-list-modal" class="card-footer-item modal-trigger">${translator.translate('game_room_add_player')}</a>
|
||||
<a id="start-game-button" class="is-primary card-footer-item">${translator.translate('game_room_start_game')}</a>
|
||||
</div>
|
||||
</jsp:attribute>
|
||||
@@ -41,219 +42,5 @@
|
||||
|
||||
<!-- Liste des utilisateurs dans le lobby -->
|
||||
<modal:connected-users-list-modal/>
|
||||
|
||||
|
||||
<script type="module" defer>
|
||||
import WebsocketToolkit from "${pageContext.request.contextPath}/static/js/WebsocketToolkit.js";
|
||||
import PlayerHand from "${pageContext.request.contextPath}/static/js/PlayerHand.js"
|
||||
import Card from "${pageContext.request.contextPath}/static/js/Card.js"
|
||||
|
||||
const choice = document.querySelector('#choice');
|
||||
let havePlayed = false;
|
||||
|
||||
const timer = ${game.timer};
|
||||
let remainingTime = timer;
|
||||
let timerInterval;
|
||||
|
||||
// Display timer
|
||||
document.querySelector('#timer').innerText = remainingTime + "s";
|
||||
|
||||
const interval = () => {
|
||||
remainingTime--;
|
||||
|
||||
document.querySelector('#timer').innerText = remainingTime + "s";
|
||||
|
||||
if (remainingTime <= 0) clearInterval(timerInterval);
|
||||
}
|
||||
|
||||
choice.querySelectorAll('button').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const message = {
|
||||
type: "click",
|
||||
data: button.dataset.value
|
||||
}
|
||||
wsgame.ws.send(JSON.stringify(message));
|
||||
|
||||
havePlayed = true;
|
||||
|
||||
// Disable buttons
|
||||
choice.querySelectorAll('button').forEach(button => button.disabled = true);
|
||||
});
|
||||
});
|
||||
|
||||
const url = new URL(window.location.href);
|
||||
url.pathname = "${pageContext.request.contextPath}/ws/game/${game.id}";
|
||||
url.protocol = "ws:";
|
||||
url.searchParams.delete("id");
|
||||
|
||||
const wsgame = new WebsocketToolkit(url);
|
||||
wsgame.onOpen(() => {
|
||||
console.log("Connected to the server (GameWS)")
|
||||
|
||||
const message = {
|
||||
type: "connection",
|
||||
data: JSON.stringify({
|
||||
id: ${user.id},
|
||||
username: "${user.username}"
|
||||
})
|
||||
}
|
||||
|
||||
wsgame.ws.send(JSON.stringify(message))
|
||||
});
|
||||
wsgame.onMessage("updatePlayerList", (data) => {
|
||||
players = data;
|
||||
updatePlayerList();
|
||||
});
|
||||
wsgame.onMessage("start", (game) => {
|
||||
currentGame = game;
|
||||
|
||||
document.querySelector('#gameWaiting').style.display = 'none';
|
||||
document.querySelector('#gameStarted').style.display = 'block';
|
||||
|
||||
timerInterval = setInterval(interval, 1000);
|
||||
|
||||
const deck = document.querySelector('#deck'); // Column
|
||||
const myCard = document.querySelector('#myCard'); // Column
|
||||
const otherCards = document.querySelector('#otherCards'); // Columns
|
||||
const round = document.querySelector('#round');
|
||||
|
||||
// Reset content
|
||||
deck.innerHTML = "";
|
||||
myCard.innerHTML = "";
|
||||
otherCards.innerHTML = "";
|
||||
round.innerText = "";
|
||||
|
||||
// Show current round
|
||||
round.innerText = (currentGame.currentRound + 1)
|
||||
|
||||
// Show other player cards
|
||||
game.players
|
||||
.filter(p => p.user.id !== ${user.id})
|
||||
.forEach(p => {
|
||||
const playerHand = new PlayerHand(p);
|
||||
otherCards.innerHTML += playerHand.render({
|
||||
textPosition: PlayerHand.TextPosition.TOP,
|
||||
className: "column"
|
||||
});
|
||||
});
|
||||
|
||||
// Show my card
|
||||
const me = game.players.find(p => p.user.id === ${user.id});
|
||||
|
||||
const playerHand = new PlayerHand(me);
|
||||
myCard.innerHTML += playerHand.render({
|
||||
textPosition: PlayerHand.TextPosition.BOTTOM,
|
||||
className: "column"
|
||||
});
|
||||
|
||||
// Show deck
|
||||
const deckCard = new Card(game.currentCard.color, game.currentCard.value);
|
||||
deck.innerHTML = deckCard.render();
|
||||
})
|
||||
wsgame.onMessage("updatePlayer", (p) => {
|
||||
document.querySelector(".player-" + p.user.id + " .card-play").style.boxShadow = "inset 0px 0px 30px 10px orange";
|
||||
})
|
||||
wsgame.onMessage("timerEnd", (game) => {
|
||||
if (!havePlayed) {
|
||||
const message = {
|
||||
type: "click",
|
||||
data: "TIMER_END"
|
||||
}
|
||||
wsgame.ws.send(JSON.stringify(message));
|
||||
}
|
||||
})
|
||||
|
||||
wsgame.onMessage("nextRound", (game) => {
|
||||
currentGame = game;
|
||||
|
||||
document.querySelector('#gameWaiting').style.display = 'none';
|
||||
document.querySelector('#gameStarted').style.display = 'block';
|
||||
|
||||
const deck = document.querySelector('#deck'); // Column
|
||||
const choice = document.querySelector('#choice');
|
||||
const myCard = document.querySelector('#myCard'); // Column
|
||||
const otherCards = document.querySelector('#otherCards'); // Columns
|
||||
const round = document.querySelector('#round');
|
||||
|
||||
clearInterval(timerInterval);
|
||||
remainingTime = timer;
|
||||
document.querySelector('#timer').innerText = remainingTime + "s";
|
||||
timerInterval = setInterval(interval, 1000);
|
||||
|
||||
// Reset content
|
||||
deck.innerHTML = "";
|
||||
myCard.innerHTML = "";
|
||||
otherCards.innerHTML = "";
|
||||
round.innerText = "";
|
||||
havePlayed = false;
|
||||
choice.querySelectorAll('button').forEach(button => button.disabled = false);
|
||||
|
||||
// Show the current round
|
||||
round.innerText = (currentGame.currentRound + 1)
|
||||
|
||||
// Show other player cards
|
||||
game.players
|
||||
.filter(p => p.user.id !== ${user.id})
|
||||
.forEach(p => {
|
||||
const playerHand = new PlayerHand(p);
|
||||
otherCards.innerHTML += playerHand.render({
|
||||
textPosition: PlayerHand.TextPosition.TOP,
|
||||
className: "column"
|
||||
});
|
||||
});
|
||||
|
||||
// Show my card
|
||||
const me = game.players.find(p => p.user.id === ${user.id});
|
||||
|
||||
const playerHand = new PlayerHand(me);
|
||||
myCard.innerHTML += playerHand.render({
|
||||
textPosition: PlayerHand.TextPosition.BOTTOM,
|
||||
className: "column"
|
||||
});
|
||||
|
||||
// Show deck
|
||||
const deckCard = new Card(game.currentCard.color, game.currentCard.value);
|
||||
deck.innerHTML = deckCard.render();
|
||||
})
|
||||
|
||||
wsgame.onMessage("end", (game) => {
|
||||
clearInterval(timerInterval);
|
||||
window.location.href = "${pageContext.request.contextPath}/game-statistics?id=${game.id}&endGame=true";
|
||||
})
|
||||
|
||||
// Close handling
|
||||
wsgame.onClose(() => console.log("Disconnected from the server (GameWS)"));
|
||||
|
||||
// Game
|
||||
let currentGame;
|
||||
|
||||
// Player List
|
||||
let players = [];
|
||||
const playerList = document.querySelector('#playerList tbody');
|
||||
|
||||
function updatePlayerList() {
|
||||
playerList.innerHTML = '';
|
||||
players.forEach(player => {
|
||||
const tr = document.createElement('tr');
|
||||
const td = document.createElement('td');
|
||||
td.textContent = player.user.username;
|
||||
tr.appendChild(td);
|
||||
playerList.appendChild(tr);
|
||||
});
|
||||
}
|
||||
|
||||
// Start Game Button
|
||||
document.querySelector('#start-game-button').addEventListener('click', () => {
|
||||
if (players.length < 2 || players.length > 4) {
|
||||
alert("Il faut entre 2 et 4 joueurs pour démarrer la partie");
|
||||
return;
|
||||
}
|
||||
|
||||
const message = {type: "start", data: ""}
|
||||
wsgame.ws.send(JSON.stringify(message));
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</jsp:body>
|
||||
</layout:base>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<jsp:useBean id="user" scope="session" type="uppa.project.database.pojo.User"/>
|
||||
|
||||
<input type="hidden" id="game-id" value="${game.id}">
|
||||
<input type="hidden" id="game-timer" value="${game.timer}">
|
||||
<input type="hidden" id="user-id" value="${user.id}">
|
||||
<input type="hidden" id="user-username" value="${user.username}">
|
||||
<p><strong>${translator.translate('game_information_created_at')}</strong> ${game.createdAt.toLocaleString()}</p>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
--bulma-primary-h: 0;
|
||||
--bulma-primary-s: 70%;
|
||||
--bulma-primary-l: 35%;
|
||||
--bulma-light-l: 96%;
|
||||
--modal-content-width: 50rem;
|
||||
--bulma-custom-footer-padding: 1rem 1.5rem 1rem;
|
||||
}
|
||||
@@ -18,6 +19,13 @@ label.radio.button > input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a.is-disable {
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
color:black
|
||||
}
|
||||
|
||||
@media screen and (min-width: 769px) {
|
||||
.modal-card, .modal-content {
|
||||
width: var(--modal-content-width) !important;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export function onError(error, inputs) {
|
||||
export function onError(error, inputs = []) {
|
||||
// Animations des champs
|
||||
const languageSelector = document.getElementById('language-select');
|
||||
|
||||
@@ -25,6 +25,7 @@ export function onError(error, inputs) {
|
||||
|
||||
const notificationMessage = document.createElement("p");
|
||||
notificationMessage.classList.add("subtitle", "is-6");
|
||||
console.log(error.message)
|
||||
notificationMessage.innerHTML = error.message;
|
||||
|
||||
notificationTitle.appendChild(notificationIcon);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
export function onInfo(title, message) {
|
||||
|
||||
// Notification
|
||||
const notification = document.createElement("div");
|
||||
notification.classList.add("notification", "is-info", "is-light");
|
||||
|
||||
const notificationTitle = document.createElement("p");
|
||||
notificationTitle.classList.add("title", "is-6");
|
||||
notificationTitle.innerHTML = title;
|
||||
|
||||
const notificationIcon = document.createElement("span");
|
||||
notificationIcon.classList.add("icon");
|
||||
notificationIcon.innerHTML = "<i class='fa-solid fa-envelope fa-beat-fade' style='color: #74C0FC;'></i>";
|
||||
|
||||
const notificationMessage = document.createElement("p");
|
||||
notificationMessage.classList.add("subtitle", "is-6");
|
||||
notificationMessage.innerHTML = message;
|
||||
|
||||
notificationTitle.appendChild(notificationIcon);
|
||||
notification.appendChild(notificationTitle);
|
||||
notification.appendChild(notificationMessage);
|
||||
document.body.appendChild(notification);
|
||||
|
||||
setTimeout(() => notification.remove(), 5010);
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
import WebsocketToolkit from "../WebsocketToolkit.js";
|
||||
import PlayerHand from "../PlayerHand.js"
|
||||
import Card from "../Card.js"
|
||||
import {onInfo} from "../notification/information.js";
|
||||
import {onError} from "../notification/error.js";
|
||||
const languageSelector = document.getElementById('language-select');
|
||||
|
||||
const choice = document.querySelector('#choice');
|
||||
// Game information
|
||||
const gameId = document.querySelector('#game-id');
|
||||
const gameTimer = document.querySelector('#game-timer');
|
||||
|
||||
//User session information
|
||||
const userSessionId = document.querySelector('#user-id');
|
||||
const userSessionUsername = document.querySelector('#user-username');
|
||||
|
||||
let gameAdminID = -1
|
||||
const buttons = document.querySelectorAll('a#start-game-button, a#invite-player')
|
||||
|
||||
function updateButtons(user) {
|
||||
buttons.forEach(button => {
|
||||
if (user.id !== gameAdminID ) {
|
||||
console.log("not admin" + user.username)
|
||||
button.classList.add('is-disable');
|
||||
button.setAttribute('title', 'Accessible uniquement par l\'admin');
|
||||
} else {
|
||||
console.log("is admin" + user.username)
|
||||
button.classList.remove('is-disable');
|
||||
button.removeAttribute('title');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateAdmin(user) {
|
||||
if (gameAdminID !== -1) {
|
||||
let titleInfo;
|
||||
let messageInfo;
|
||||
if (languageSelector.value === "EN") {
|
||||
titleInfo = "The admin has leaved the game";
|
||||
messageInfo = "You are automatically select has thenew admin";
|
||||
} else {
|
||||
titleInfo = "L'admin a quitté la partie";
|
||||
messageInfo = "Vous êtes automatiquement désigné comme le nouvel admin";
|
||||
}
|
||||
onInfo(titleInfo, messageInfo)
|
||||
}
|
||||
console.log("admin:" + user.username)
|
||||
gameAdminID = user.id;
|
||||
}
|
||||
let havePlayed = false;
|
||||
|
||||
const timer = gameTimer.value;
|
||||
let remainingTime = timer;
|
||||
let timerInterval;
|
||||
|
||||
// Display timer
|
||||
document.querySelector('#timer').innerText = remainingTime + "s";
|
||||
|
||||
const interval = () => {
|
||||
remainingTime--;
|
||||
|
||||
document.querySelector('#timer').innerText = remainingTime + "s";
|
||||
|
||||
if (remainingTime <= 0) clearInterval(timerInterval);
|
||||
}
|
||||
|
||||
choice.querySelectorAll('button').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const message = {
|
||||
type: "click",
|
||||
data: button.dataset.value
|
||||
}
|
||||
wsgame.ws.send(JSON.stringify(message));
|
||||
|
||||
havePlayed = true;
|
||||
|
||||
// Disable buttons
|
||||
choice.querySelectorAll('button').forEach(button => button.disabled = true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
const url = new URL(window.location.href);
|
||||
const contextPath = url.pathname.substring(0, url.pathname.indexOf("/", 1) + 1)
|
||||
url.pathname = contextPath + "ws/game/"+gameId.value;
|
||||
url.protocol = "ws:";
|
||||
url.searchParams.delete("id");
|
||||
|
||||
const wsgame = new WebsocketToolkit(url);
|
||||
wsgame.onOpen(() => {
|
||||
console.log("Connected to the server (GameWS)")
|
||||
|
||||
const message = {
|
||||
type: "connection",
|
||||
data: JSON.stringify({
|
||||
id: userSessionId.value,
|
||||
username: userSessionUsername.value
|
||||
})
|
||||
}
|
||||
|
||||
wsgame.ws.send(JSON.stringify(message))
|
||||
});
|
||||
wsgame.onMessage("updatePlayerList", (data) => {
|
||||
players = data;
|
||||
console.log(players)
|
||||
if (gameAdminID === -1 || players[0].user.id !== gameAdminID) {
|
||||
updateAdmin(players[0].user)
|
||||
|
||||
}
|
||||
players.forEach((player) => {
|
||||
console.log("player:" + player.user.id)
|
||||
console.log("user:" + userSessionId.value)
|
||||
console.log( player.user.id.toString() == userSessionId.value)
|
||||
if (player.user.id.toString() === userSessionId.value) {
|
||||
updateButtons(player.user)
|
||||
}
|
||||
});
|
||||
updatePlayerList();
|
||||
});
|
||||
wsgame.onMessage("start", (game) => {
|
||||
currentGame = game;
|
||||
|
||||
document.querySelector('#gameWaiting').style.display = 'none';
|
||||
document.querySelector('#gameStarted').style.display = 'block';
|
||||
|
||||
timerInterval = setInterval(interval, 1000);
|
||||
|
||||
const deck = document.querySelector('#deck'); // Column
|
||||
const myCard = document.querySelector('#myCard'); // Column
|
||||
const otherCards = document.querySelector('#otherCards'); // Columns
|
||||
const round = document.querySelector('#round');
|
||||
|
||||
// Reset content
|
||||
deck.innerHTML = "";
|
||||
myCard.innerHTML = "";
|
||||
otherCards.innerHTML = "";
|
||||
round.innerText = "";
|
||||
|
||||
// Show current round
|
||||
round.innerText = (currentGame.currentRound + 1)
|
||||
|
||||
// Show other player cards
|
||||
game.players
|
||||
.filter(p => p.user.id !== userSessionId.value)
|
||||
.forEach(p => {
|
||||
const playerHand = new PlayerHand(p);
|
||||
otherCards.innerHTML += playerHand.render({
|
||||
textPosition: PlayerHand.TextPosition.TOP,
|
||||
className: "column"
|
||||
});
|
||||
});
|
||||
|
||||
// Show my card
|
||||
const me = game.players.find(p => p.user.id === userSessionId.value);
|
||||
|
||||
const playerHand = new PlayerHand(me);
|
||||
myCard.innerHTML += playerHand.render({
|
||||
textPosition: PlayerHand.TextPosition.BOTTOM,
|
||||
className: "column"
|
||||
});
|
||||
|
||||
// Show deck
|
||||
const deckCard = new Card(game.currentCard.color, game.currentCard.value);
|
||||
deck.innerHTML = deckCard.render();
|
||||
})
|
||||
wsgame.onMessage("updatePlayer", (p) => {
|
||||
document.querySelector(".player-" + p.user.id + " .card-play").style.boxShadow = "inset 0px 0px 30px 10px orange";
|
||||
})
|
||||
wsgame.onMessage("timerEnd", (game) => {
|
||||
if (!havePlayed) {
|
||||
const message = {
|
||||
type: "click",
|
||||
data: "TIMER_END"
|
||||
}
|
||||
wsgame.ws.send(JSON.stringify(message));
|
||||
}
|
||||
})
|
||||
|
||||
wsgame.onMessage("nextRound", (game) => {
|
||||
currentGame = game;
|
||||
|
||||
document.querySelector('#gameWaiting').style.display = 'none';
|
||||
document.querySelector('#gameStarted').style.display = 'block';
|
||||
|
||||
const deck = document.querySelector('#deck'); // Column
|
||||
const choice = document.querySelector('#choice');
|
||||
const myCard = document.querySelector('#myCard'); // Column
|
||||
const otherCards = document.querySelector('#otherCards'); // Columns
|
||||
const round = document.querySelector('#round');
|
||||
|
||||
clearInterval(timerInterval);
|
||||
remainingTime = timer;
|
||||
document.querySelector('#timer').innerText = remainingTime + "s";
|
||||
timerInterval = setInterval(interval, 1000);
|
||||
|
||||
// Reset content
|
||||
deck.innerHTML = "";
|
||||
myCard.innerHTML = "";
|
||||
otherCards.innerHTML = "";
|
||||
round.innerText = "";
|
||||
havePlayed = false;
|
||||
choice.querySelectorAll('button').forEach(button => button.disabled = false);
|
||||
|
||||
// Show the current round
|
||||
round.innerText = (currentGame.currentRound + 1)
|
||||
|
||||
// Show other player cards
|
||||
game.players
|
||||
.filter(p => p.user.id !== userSessionId.value)
|
||||
.forEach(p => {
|
||||
const playerHand = new PlayerHand(p);
|
||||
otherCards.innerHTML += playerHand.render({
|
||||
textPosition: PlayerHand.TextPosition.TOP,
|
||||
className: "column"
|
||||
});
|
||||
});
|
||||
|
||||
// Show my card
|
||||
const me = game.players.find(p => p.user.id === userSessionId.value);
|
||||
|
||||
const playerHand = new PlayerHand(me);
|
||||
myCard.innerHTML += playerHand.render({
|
||||
textPosition: PlayerHand.TextPosition.BOTTOM,
|
||||
className: "column"
|
||||
});
|
||||
|
||||
// Show deck
|
||||
const deckCard = new Card(game.currentCard.color, game.currentCard.value);
|
||||
deck.innerHTML = deckCard.render();
|
||||
})
|
||||
|
||||
wsgame.onMessage("end", (game) => {
|
||||
clearInterval(timerInterval);
|
||||
window.location.href = "${pageContext.request.contextPath}/game-statistics?id=${game.id}&endGame=true";
|
||||
})
|
||||
|
||||
// Close handling
|
||||
wsgame.onClose(() => console.log("Disconnected from the server (GameWS)"));
|
||||
|
||||
// Game
|
||||
let currentGame;
|
||||
|
||||
// Player List
|
||||
let players = [];
|
||||
const playerList = document.querySelector('#playerList tbody');
|
||||
|
||||
function updatePlayerList() {
|
||||
playerList.innerHTML = '';
|
||||
players.forEach(player => {
|
||||
const tr = document.createElement('tr');
|
||||
const td = document.createElement('td');
|
||||
td.textContent = player.user.username;
|
||||
tr.appendChild(td);
|
||||
playerList.appendChild(tr);
|
||||
});
|
||||
}
|
||||
|
||||
// Start Game Button
|
||||
document.querySelector('#start-game-button').addEventListener('click', () => {
|
||||
if (players.length < 2 || players.length > 4) {
|
||||
if (languageSelector.value === "EN") {
|
||||
onError(new Error("You need between 2 and 4 players to start the game"));
|
||||
} else {
|
||||
onError(new Error("Il faut entre 2 et 4 joueurs pour démarrer la partie"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const message = {type: "start", data: ""}
|
||||
wsgame.ws.send(JSON.stringify(message));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user