ending games, style low timer

This commit is contained in:
Alec
2021-12-22 15:49:12 -05:00
parent 5690a0a46c
commit 31f5d01092
29 changed files with 794 additions and 125 deletions

View File

@@ -48,6 +48,29 @@ export class GameStateRenderer {
let copyImg = document.createElement("img");
copyImg.setAttribute("src", "../images/copy.svg");
gameLinkContainer.appendChild(copyImg);
let time = document.getElementById("game-time");
let playerCount = document.getElementById("game-player-count");
playerCount.innerText = getGameSize(this.stateBucket.currentGameState.deck) + ' Players'
if (this.stateBucket.currentGameState.timerParams) {
let timeString = "";
let hours = this.stateBucket.currentGameState.timerParams.hours;
let minutes = this.stateBucket.currentGameState.timerParams.minutes
if (hours) {
timeString += hours > 1
? hours + ' hours '
: hours + ' hour '
}
if (minutes) {
timeString += minutes > 1
? minutes + ' minutes '
: minutes + ' minute '
}
time.innerText = timeString;
} else {
time.innerText = 'untimed';
}
}
renderLobbyFooter() {
@@ -69,7 +92,16 @@ export class GameStateRenderer {
renderModeratorView() {
let div = document.createElement("div");
div.innerHTML = templates.END_GAME_PROMPT;
document.body.appendChild(div);
document.getElementById("game-content").appendChild(div);
document.getElementById("end-game-button").addEventListener('click', (e) => {
e.preventDefault();
if (confirm("End the game?")) {
this.socket.emit(
globals.COMMANDS.END_GAME,
this.stateBucket.currentGameState.accessCode
);
}
});
let modTransferButton = document.getElementById("mod-transfer-button");
modTransferButton.addEventListener(
@@ -78,7 +110,7 @@ export class GameStateRenderer {
ModalManager.displayModal(
"transfer-mod-modal",
"transfer-mod-modal-background",
"close-modal-button"
"close-mod-transfer-modal-button"
)
}
)
@@ -118,18 +150,7 @@ export class GameStateRenderer {
}
renderPlayersWithRoleAndAlignmentInfo() {
document.querySelectorAll('.game-player').forEach((el) => {
let pointer = el.dataset.pointer;
if (pointer && this.killPlayerHandlers[pointer]) {
el.removeEventListener('click', this.killPlayerHandlers[pointer]);
delete this.killPlayerHandlers[pointer];
}
if (pointer && this.revealRoleHandlers[pointer]) {
el.removeEventListener('click', this.revealRoleHandlers[pointer]);
delete this.revealRoleHandlers[pointer];
}
el.remove();
});
removeExistingPlayerElements(this.killPlayerHandlers, this.revealRoleHandlers);
this.stateBucket.currentGameState.people.sort((a, b) => {
return a.name >= b.name ? 1 : -1;
});
@@ -151,7 +172,8 @@ export class GameStateRenderer {
this.stateBucket.currentGameState.accessCode,
globals.ALIGNMENT.GOOD,
this.stateBucket.currentGameState.moderator.userType,
this.socket);
this.socket
);
document.getElementById("players-alive-label").innerText =
'Players: ' + this.stateBucket.currentGameState.people.filter((person) => !person.out).length + ' / '
+ this.stateBucket.currentGameState.people.length + ' Alive';
@@ -208,28 +230,27 @@ export class GameStateRenderer {
}
el.remove();
});
let modalContent = document.getElementById("transfer-mod-form-content");
if (modalContent) {
renderPotentialMods(
this.stateBucket.currentGameState,
this.stateBucket.currentGameState.people,
this.transferModHandlers,
modalContent,
this.socket
);
renderPotentialMods( // spectators can also be made mods.
this.stateBucket.currentGameState,
this.stateBucket.currentGameState.spectators,
this.transferModHandlers,
modalContent,
this.socket
);
}
renderPotentialMods(
this.stateBucket.currentGameState,
this.stateBucket.currentGameState.people,
this.transferModHandlers,
this.socket
);
renderPotentialMods( // spectators can also be made mods.
this.stateBucket.currentGameState,
this.stateBucket.currentGameState.spectators,
this.transferModHandlers,
this.socket
);
}
renderEndOfGame() {
this.renderPlayersWithNoRoleInformationUnlessRevealed();
}
}
function renderPotentialMods(gameState, group, transferModHandlers, modalContent, socket) {
function renderPotentialMods(gameState, group, transferModHandlers, socket) {
let modalContent = document.getElementById("transfer-mod-modal-content");
for (let member of group) {
if ((member.out || member.userType === globals.USER_TYPES.SPECTATOR) && !(member.id === gameState.client.id)) {
let container = document.createElement("div");
@@ -244,6 +265,7 @@ function renderPotentialMods(gameState, group, transferModHandlers, modalContent
container.addEventListener('click', transferModHandlers[member.id]);
modalContent.appendChild(container);
console.log('test');
}
}
}
@@ -420,3 +442,18 @@ function insertPlaceholderButton(container, append, type) {
container.querySelector('.player-action-buttons').prepend(button);
}
}
function removeExistingPlayerElements(killPlayerHandlers, revealRoleHandlers) {
document.querySelectorAll('.game-player').forEach((el) => {
let pointer = el.dataset.pointer;
if (pointer && killPlayerHandlers[pointer]) {
el.removeEventListener('click', killPlayerHandlers[pointer]);
delete killPlayerHandlers[pointer];
}
if (pointer && revealRoleHandlers[pointer]) {
el.removeEventListener('click', revealRoleHandlers[pointer]);
delete revealRoleHandlers[pointer];
}
el.remove();
});
}

View File

@@ -22,6 +22,11 @@ export class GameTimerManager {
let instance = this;
let timer = document.getElementById('game-timer');
timer.classList.remove('paused');
timer.classList.remove('paused-low');
timer.classList.remove('low');
if (totalTime < 60000) {
timer.classList.add('low');
}
timer.innerText = totalTime < 60000
? returnHumanReadableTime(totalTime, true)
: returnHumanReadableTime(totalTime);
@@ -29,6 +34,9 @@ export class GameTimerManager {
if (e.data.hasOwnProperty('timeRemainingInMilliseconds') && e.data.timeRemainingInMilliseconds >= 0) {
if (e.data.timeRemainingInMilliseconds === 0) {
instance.displayExpiredTime();
} else if (e.data.timeRemainingInMilliseconds < 60000) {
timer.classList.add('low');
timer.innerText = e.data.displayTime;
} else {
timer.innerText = e.data.displayTime;
}
@@ -49,10 +57,14 @@ export class GameTimerManager {
timerWorker.postMessage('stop');
let timer = document.getElementById('game-timer');
timer.innerText = timeRemaining < 60000
? returnHumanReadableTime(timeRemaining, true)
: returnHumanReadableTime(timeRemaining);
timer.classList.add('paused');
if (timeRemaining < 60000) {
timer.innerText = returnHumanReadableTime(timeRemaining, true);
timer.classList.add('paused-low');
timer.classList.add('low');
} else {
timer.innerText = returnHumanReadableTime(timeRemaining);
timer.classList.add('paused');
}
}
}
@@ -65,10 +77,14 @@ export class GameTimerManager {
}
let timer = document.getElementById('game-timer');
timer.innerText = time < 60000
? returnHumanReadableTime(time, true)
: returnHumanReadableTime(time);
timer.classList.add('paused');
if (time < 60000) {
timer.innerText = returnHumanReadableTime(time, true);
timer.classList.add('paused-low');
timer.classList.add('low');
} else {
timer.innerText = returnHumanReadableTime(time);
timer.classList.add('paused');
}
}
displayExpiredTime() {

View File

@@ -18,6 +18,8 @@ function displayModal(modalId, backgroundId, closeButtonId) {
});
closeBtn.removeEventListener("click", closeModalHandler);
closeBtn.addEventListener("click", closeModalHandler);
} else {
throw new Error("One or more of the ids supplied to ModalManager.displayModal is invalid.");
}
}

View File

@@ -5,8 +5,19 @@ export const templates = {
"<label for='game-link'>Share Link</label>" +
"<div id='game-link'></div>" +
"</div>" +
"<div id='game-time'></div>" +
"<div id='game-player-count'></div>" +
"<div id='game-parameters'>" +
"<div>" +
"<img alt='clock' src='/images/clock.svg'/>" +
"<div id='game-time'></div>" +
"</div>" +
"<div>" +
"<img alt='person' src='/images/person.svg'/>" +
"<div id='game-player-count'></div>" +
"</div>" +
"</div>" +
"<div>" +
"<button id='role-info-button'>View Role Info <img src='/images/info.svg'</button>" +
"</div>" +
"</div>" +
"<div>" +
"<div id='lobby-people-container'>" +
@@ -31,6 +42,9 @@ export const templates = {
"<label for='game-timer'>Time Remaining</label>" +
"<div id='game-timer'></div>" +
"</div>" +
"<div>" +
"<button id='role-info-button'>View Role Info <img src='/images/info.svg'</button>" +
"</div>" +
"</div>" +
"<div id='game-role' style='display:none'>" +
"<h4 id='role-name'></h4>" +
@@ -51,22 +65,22 @@ export const templates = {
"<label for='game-timer'>Time Remaining</label>" +
"<div id='game-timer'></div>" +
"</div>" +
"<div>" +
"<button id='role-info-button'>View Role Info <img src='/images/info.svg'</button>" +
"</div>" +
"</div>" +
"<div>" +
"<div id='game-people-container'>" +
"<label id='players-alive-label'></label>" +
"<div id='game-player-list'></div>" +
"</div>",
MODERATOR_GAME_VIEW:
"<div id='transfer-mod-modal-background' class='modal-background' style='display: none'></div>" +
"<div id='transfer-mod-modal' class='modal' style='display: none'>" +
"<form id='transfer-mod-form'>" +
"<div id='transfer-mod-form-content'>" +
"<h3>Transfer Mod Powers &#128081;</h3>" +
"</div>" +
"<div id='modal-button-container'>" +
"<button id='close-modal-button'>Cancel</button>" +
"</div>" +
"</form>" +
"<h3>Transfer Mod Powers &#128081;</h3>" +
"<div id='transfer-mod-modal-content'></div>" +
"<div id='modal-button-container'>" +
"<button id='close-mod-transfer-modal-button'>Cancel</button>" +
"</div>" +
"</div>" +
"<div id='game-header'>" +
"<div class='timer-container-moderator'>" +
@@ -77,6 +91,9 @@ export const templates = {
"<div id='play-pause'>" + "</div>" +
"</div>" +
"<button id='mod-transfer-button' class='moderator-player-button make-mod-button'>Transfer Mod Powers \uD83D\uDD00</button>" +
"<div>" +
"<button id='role-info-button'>View Role Info <img src='/images/info.svg'</button>" +
"</div>" +
"</div>" +
"<div>" +
"<label id='players-alive-label'></label>" +
@@ -178,5 +195,31 @@ export const templates = {
"<input type='submit' id='submit-new-name' value='Set Name'/>" +
"</div>" +
"</form>" +
"</div>",
ROLE_INFO_MODAL:
"<div id='role-info-modal-background' class='modal-background'></div>" +
"<div id='role-info-modal' class='modal'>" +
"<h2>Roles in this game:</h2>" +
"<div id='game-role-info-container'></div>" +
"<div id='modal-button-container'>" +
"<button id='close-role-info-modal-button'>Close</button>" +
"</div>" +
"</div>",
END_OF_GAME_VIEW:
"<h2>The moderator has ended the game. Roles are revealed.</h2>" +
"<div id='end-of-game-header'>" +
"<div>" +
"<button id='role-info-button'>View Role Info <img src='/images/info.svg'</button>" +
"</div>" +
"<div>" +
"<a href='/'>" +
"<button>Go Home \uD83C\uDFE0</button>" +
"</a>" +
"</div>" +
"</div>" +
"<div id='game-people-container'>" +
"<label id='players-alive-label'></label>" +
"<div id='game-player-list'></div>" +
"</div>"
}

View File

@@ -9,7 +9,7 @@ export const toast = (message, type, positionAtTop = true, dispelAutomatically=t
function buildAndInsertMessageElement (message, type, positionAtTop, dispelAutomatically, duration) {
cancelCurrentToast();
let backgroundColor, border;
const position = positionAtTop ? 'top:2rem;' : 'bottom: 35px;';
const position = positionAtTop ? 'top:2rem;' : 'bottom: 90px;';
switch (type) {
case 'warning':
backgroundColor = '#fff5b1';