refacto: devweb - structure modal and game websocket script in js files

+ feat: devweb - add admin to a game
This commit is contained in:
kmitresse
2024-06-13 15:06:03 +02:00
parent ae5d39abbf
commit 1dd75ea377
6 changed files with 309 additions and 216 deletions
@@ -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));
});