replace restart with return to lobby, add mockup player options button

This commit is contained in:
AlecM33
2023-08-02 18:44:33 -04:00
parent 61275dd3e5
commit d00f3d630a
9 changed files with 89 additions and 28 deletions

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 29.96 122.88"><defs><style>.cls-1{fill-rule:evenodd;}</style></defs><title>3-vertical-dots</title><path fill="#d7d7d7" class="cls-1" d="M15,0A15,15,0,1,1,0,15,15,15,0,0,1,15,0Zm0,92.93a15,15,0,1,1-15,15,15,15,0,0,1,15-15Zm0-46.47a15,15,0,1,1-15,15,15,15,0,0,1,15-15Z"/></svg>

After

Width:  |  Height:  |  Size: 362 B

View File

@@ -296,9 +296,6 @@ export const HTMLFragments = {
<h2>&#x1F3C1; The moderator has ended the game. Roles are revealed.</h2>
<div id="end-of-game-buttons">
<button id='role-info-button' class='app-button'>Roles in This Game <img alt='Info icon' src='/images/info.svg'/></button>
<a href='/'>
<button class='app-button'>Go Home \uD83C\uDFE0</button>
</a>
</div>
</div>
<div id='game-people-container'>

View File

@@ -15,7 +15,7 @@ export class Ended {
gameState.client.userType === globals.USER_TYPES.MODERATOR
|| gameState.client.userType === globals.USER_TYPES.TEMPORARY_MODERATOR
) {
document.getElementById('end-of-game-buttons').prepend(SharedStateUtil.createRestartButton(this.stateBucket));
document.getElementById('end-of-game-buttons').prepend(SharedStateUtil.createReturnToLobbyButton(this.stateBucket));
}
SharedStateUtil.displayCurrentModerator(this.stateBucket.currentGameState.people
.find((person) => person.userType === globals.USER_TYPES.MODERATOR

View File

@@ -500,7 +500,7 @@ function createEndGamePromptComponent (socket, stateBucket) {
);
});
});
div.querySelector('#game-control-prompt').prepend(SharedStateUtil.createRestartButton(stateBucket));
div.querySelector('#game-control-prompt').prepend(SharedStateUtil.createReturnToLobbyButton(stateBucket));
document.getElementById('game-content').appendChild(div);
}
}

View File

@@ -62,7 +62,7 @@ export class Lobby {
const spectatorHandler = (e) => {
if (e.type === 'click' || e.code === 'Enter') {
Confirmation(SharedStateUtil.buildSpectatorList(this.stateBucket.currentGameState.people
.filter(p => p.userType === globals.USER_TYPES.SPECTATOR)), null, true);
.filter(p => p.userType === globals.USER_TYPES.SPECTATOR), this.stateBucket.currentGameState.client), null, true);
}
};
@@ -95,7 +95,7 @@ export class Lobby {
}
);
for (const person of sorted.filter(p => p.userType !== globals.USER_TYPES.SPECTATOR)) {
lobbyPlayersContainer.appendChild(renderLobbyPerson(person.name, person.userType));
lobbyPlayersContainer.appendChild(renderLobbyPerson(person.name, person.userType, this.stateBucket.currentGameState.client));
}
const playerCount = this.stateBucket.currentGameState.people.filter(
p => p.userType !== globals.USER_TYPES.MODERATOR && p.userType !== globals.USER_TYPES.SPECTATOR
@@ -192,7 +192,7 @@ function getTimeString (gameState) {
}
}
function renderLobbyPerson (name, userType) {
function renderLobbyPerson (name, userType, client) {
const el = document.createElement('div');
const personNameEl = document.createElement('div');
personNameEl.classList.add('lobby-player-name');
@@ -207,5 +207,9 @@ function renderLobbyPerson (name, userType) {
el.appendChild(personNameEl);
el.appendChild(personTypeEl);
if (client.userType === globals.USER_TYPES.MODERATOR || client.userType === globals.USER_TYPES.TEMPORARY_MODERATOR) {
SharedStateUtil.addPlayerOptions(el);
}
return el;
}

View File

@@ -23,9 +23,10 @@ export const SharedStateUtil = {
);
},
restartHandler: (stateBucket) => {
restartHandler: (stateBucket, status = globals.STATUS.IN_PROGRESS) => {
console.log("HEY")
XHRUtility.xhr(
'/api/games/' + stateBucket.currentGameState.accessCode + '/restart',
'/api/games/' + stateBucket.currentGameState.accessCode + '/restart?status=' + status,
'PATCH',
null,
JSON.stringify({
@@ -45,7 +46,7 @@ export const SharedStateUtil = {
const restartGameButton = document.createElement('button');
restartGameButton.classList.add('app-button');
restartGameButton.setAttribute('id', 'restart-game-button');
restartGameButton.innerText = 'Restart';
restartGameButton.innerText = 'Quick Restart';
restartGameButton.addEventListener('click', () => {
Confirmation('Restart the game, dealing everyone new roles?', () => {
SharedStateUtil.restartHandler(stateBucket);
@@ -55,6 +56,20 @@ export const SharedStateUtil = {
return restartGameButton;
},
createReturnToLobbyButton: (stateBucket) => {
const returnToLobbyButton = document.createElement('button');
returnToLobbyButton.classList.add('app-button');
returnToLobbyButton.setAttribute('id', 'return-to-lobby-button');
returnToLobbyButton.innerText = 'Return to Lobby';
returnToLobbyButton.addEventListener('click', () => {
Confirmation('Return everyone to the Lobby?', () => {
SharedStateUtil.restartHandler(stateBucket, globals.STATUS.LOBBY);
});
});
return returnToLobbyButton;
},
setClientSocketHandlers: (stateBucket, socket) => {
const startGameStateAckFn = (gameState) => {
SharedStateUtil.gameStateAckFn(gameState, socket);
@@ -63,7 +78,7 @@ export const SharedStateUtil = {
const restartGameStateAckFn = (gameState) => {
SharedStateUtil.gameStateAckFn(gameState, socket);
toast('Game restarted!', 'success');
toast('Everyone has returned to the Lobby!', 'success');
};
const fetchGameStateHandler = (ackFn) => {
@@ -160,7 +175,17 @@ export const SharedStateUtil = {
}
},
buildSpectatorList (people) {
addPlayerOptions: (personEl) => {
const kickButton = document.createElement('img');
kickButton.setAttribute('tabIndex', '0');
kickButton.setAttribute('className', 'role-remove');
kickButton.setAttribute('src', '../images/3-vertical-dots-icon.svg');
kickButton.setAttribute('title', 'Kick Player');
kickButton.setAttribute('alt', 'Kick Player');
personEl.appendChild(kickButton);
},
buildSpectatorList (people, client) {
const list = document.createElement('div');
const spectators = people.filter(p => p.userType === globals.USER_TYPES.SPECTATOR);
if (spectators.length === 0) {
@@ -173,6 +198,10 @@ export const SharedStateUtil = {
'<div>' + 'spectator' + globals.USER_TYPE_ICONS.spectator + '</div>';
spectatorEl.querySelector('.spectator-name').innerText = spectator.name;
list.appendChild(spectatorEl);
if (client.userType === globals.USER_TYPES.MODERATOR || client.userType === globals.USER_TYPES.TEMPORARY_MODERATOR) {
this.addPlayerOptions(spectatorEl);
}
}
}

View File

@@ -13,6 +13,30 @@
margin: 0 auto 0.25em auto;
}
.lobby-player, .spectator {
position: relative;
}
.lobby-player img, .spectator img {
height: 18px;
margin: 0 8px;
cursor: pointer;
padding: 5px;
border-radius: 5px;
border: 1px solid transparent;
position: absolute;
right: -33px;
}
.lobby-player img:active, .spectator img:active {
border: 1px solid whitesmoke;
}
.lobby-player img:hover, .spectator img:hover {
filter: brightness(1.5);
background-color: #8080804d;
}
.moderator {
border: 2px solid #c58f13 !important;
}
@@ -82,13 +106,13 @@
max-width: 17em;
}
#restart-game-button, #mod-transfer-button {
#return-to-lobby-button, #end-of-game-buttons #return-to-lobby-button, #mod-transfer-button {
background-color: #045EA6;
border: 2px solid #024070;
}
#restart-game-button:hover, #mod-transfer-button:hover {
background-color: #0078D773;
#return-to-lobby-button:hover, #end-of-game-buttons #return-to-lobby-button:hover, #mod-transfer-button:hover {
background-color: rgba(0, 120, 215, 0.45);
border: 2px solid #045EA6;
}
@@ -160,7 +184,7 @@ h1 {
font-size: 18px;
}
#end-of-game-header #restart-game-button {
#end-of-game-header #return-to-lobby-button {
margin-bottom: 1em !important;
animation: shadow-pulse 1.5s infinite ease-out;
padding: 10px;
@@ -543,7 +567,7 @@ label[for='moderator'] {
box-shadow: 0 -6px 40px black;
}
#start-game-button, #end-game-button, #restart-game-button {
#start-game-button, #end-game-button, #return-to-lobby-button {
font-family: 'signika-negative', sans-serif !important;
padding: 10px;
border-radius: 5px;
@@ -910,7 +934,7 @@ canvas {
height: 65px;
}
#start-game-button, #end-game-button, #restart-game-button {
#start-game-button, #end-game-button, #return-to-lobby-button {
font-size: 20px;
padding: 5px;
}

View File

@@ -102,7 +102,9 @@ router.patch('/:code/restart', async function (req, res) {
} else {
const game = await gameManager.getActiveGame(req.body.accessCode);
if (game) {
gameManager.restartGame(game, gameManager.namespace).then((data) => {
gameManager.restartGame(game, gameManager.namespace, req.query.status).then((data) => {
console.log(req.query.status);
console.log(req.query.toLobby);
res.status(200).send();
}).catch((code) => {
res.status(code).send();

View File

@@ -215,7 +215,7 @@ class GameManager {
}
};
restartGame = async (game, namespace) => {
restartGame = async (game, namespace, status = globals.STATUS.IN_PROGRESS) => {
// kill any outstanding timer threads
const subProcess = this.timerManager.timerThreads[game.accessCode];
if (subProcess) {
@@ -260,15 +260,19 @@ class GameManager {
}
}
// start the new game
game.status = globals.STATUS.IN_PROGRESS;
if (game.hasTimer) {
game.timerParams.paused = true;
game.timerParams.timeRemaining = convertFromHoursToMilliseconds(game.timerParams.hours) +
convertFromMinutesToMilliseconds(game.timerParams.minutes);
await this.timerManager.runTimer(game, namespace, this.eventManager, this);
if (status === globals.STATUS.IN_PROGRESS) {
game.status = globals.STATUS.IN_PROGRESS;
if (game.hasTimer) {
game.timerParams.paused = true;
game.timerParams.timeRemaining = convertFromHoursToMilliseconds(game.timerParams.hours) +
convertFromMinutesToMilliseconds(game.timerParams.minutes);
await this.timerManager.runTimer(game, namespace, this.eventManager, this);
}
} else {
game.status = globals.STATUS.LOBBY;
}
await this.refreshGame(game);
await this.eventManager.publisher?.publish(
globals.REDIS_CHANNELS.ACTIVE_GAME_STREAM,