diff --git a/client/src/config/globals.js b/client/src/config/globals.js index d22357f..72d5bb6 100644 --- a/client/src/config/globals.js +++ b/client/src/config/globals.js @@ -1,6 +1,6 @@ export const globals = { USER_SIGNATURE_LENGTH: 25, - CLOCK_TICK_INTERVAL_MILLIS: 10, + CLOCK_TICK_INTERVAL_MILLIS: 100, MAX_CUSTOM_ROLE_NAME_LENGTH: 30, MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH: 500, TOAST_DURATION_DEFAULT: 6, diff --git a/client/src/modules/GameCreationStepManager.js b/client/src/modules/GameCreationStepManager.js index 1d12537..1178ae0 100644 --- a/client/src/modules/GameCreationStepManager.js +++ b/client/src/modules/GameCreationStepManager.js @@ -107,13 +107,23 @@ export class GameCreationStepManager { 5: { title: 'Review and submit:', backHandler: this.defaultBackHandler, - forwardHandler: (deck, hasTimer, hasDedicatedModerator, moderatorName, timerParams) => { + forwardHandler: () => { + const button = document.getElementById('create-game'); + button.removeEventListener('click', this.steps['5'].forwardHandler); + button.classList.add('submitted'); + button.innerText = 'Creating'; XHRUtility.xhr( '/api/games/create', 'POST', null, JSON.stringify( - new Game(deck, hasTimer, hasDedicatedModerator, moderatorName, timerParams) + new Game( + this.currentGame.deck.filter((card) => card.quantity > 0), + this.currentGame.hasTimer, + this.currentGame.hasDedicatedModerator, + this.currentGame.moderatorName, + this.currentGame.timerParams + ) ) ) .then((res) => { @@ -128,9 +138,10 @@ export class GameCreationStepManager { } }).catch((e) => { const button = document.getElementById('create-game'); - button.innerText = 'Create Game'; + button.innerText = 'Create'; button.classList.remove('submitted'); - button.addEventListener('click', this.steps['4'].forwardHandler); + button.addEventListener('click', this.steps['5'].forwardHandler); + toast(e.content, 'error', true, true, 'medium'); if (e.status === 429) { toast('You\'ve sent this request too many times.', 'error', true, true, 'medium'); } @@ -449,18 +460,7 @@ function showButtons (back, forward, forwardHandler, backHandler, builtGame = nu createButton.innerText = 'Create'; createButton.setAttribute('id', 'create-game'); createButton.classList.add('app-button'); - createButton.addEventListener('click', () => { - createButton.removeEventListener('click', forwardHandler); - createButton.classList.add('submitted'); - createButton.innerText = 'Creating...'; - forwardHandler( - builtGame.deck.filter((card) => card.quantity > 0), - builtGame.hasTimer, - builtGame.hasDedicatedModerator, - builtGame.moderatorName, - builtGame.timerParams - ); - }); + createButton.addEventListener('click', forwardHandler); document.getElementById('tracker-container').appendChild(createButton); } } diff --git a/client/src/modules/GameStateRenderer.js b/client/src/modules/GameStateRenderer.js index fdc6c7a..1ae1bdd 100644 --- a/client/src/modules/GameStateRenderer.js +++ b/client/src/modules/GameStateRenderer.js @@ -2,6 +2,8 @@ import { globals } from '../config/globals.js'; import { toast } from './Toast.js'; import { HTMLFragments } from './HTMLFragments.js'; import { ModalManager } from './ModalManager.js'; +import { XHRUtility } from './XHRUtility.js'; +import { UserUtility } from './UserUtility.js'; export class GameStateRenderer { constructor (stateBucket, socket) { @@ -10,12 +12,40 @@ export class GameStateRenderer { this.killPlayerHandlers = {}; this.revealRoleHandlers = {}; this.transferModHandlers = {}; - this.startGameHandler = (e) => { + this.startGameHandler = (e) => { // TODO: prevent multiple emissions of this event (recommend converting to XHR) e.preventDefault(); if (confirm('Start the game and deal roles?')) { socket.emit(globals.COMMANDS.START_GAME, this.stateBucket.currentGameState.accessCode); } }; + this.restartGameHandler = (e) => { + e.preventDefault(); + const button = document.getElementById('restart-game'); + button.removeEventListener('click', this.restartGameHandler); + button.classList.add('submitted'); + button.innerText = 'Restarting...'; + XHRUtility.xhr( + '/api/games/' + this.stateBucket.currentGameState.accessCode + '/restart', + 'PATCH', + null, + JSON.stringify({ + playerName: this.stateBucket.currentGameState.client.name, + accessCode: this.stateBucket.currentGameState.accessCode, + sessionCookie: UserUtility.validateAnonUserSignature(globals.ENVIRONMENT.LOCAL), + localCookie: UserUtility.validateAnonUserSignature(globals.ENVIRONMENT.PRODUCTION) + }) + ) + .then((res) => { + toast('Game restarted!', 'success', true, true, 'medium'); + }) + .catch((res) => { + const button = document.getElementById('restart-game'); + button.innerText = 'Run it back š'; + button.classList.remove('submitted'); + button.addEventListener('click', this.restartGameHandler); + toast(res.content, 'error', true, true, 'medium'); + }); + }; } renderLobbyPlayers () { @@ -256,7 +286,17 @@ export class GameStateRenderer { } } - renderEndOfGame () { + renderEndOfGame (gameState) { + if ( + gameState.client.userType === globals.USER_TYPES.MODERATOR + || gameState.client.userType === globals.USER_TYPES.TEMPORARY_MODERATOR + ) { + const restartGameContainer = document.createElement('div'); + restartGameContainer.innerHTML = HTMLFragments.RESTART_GAME_BUTTON; + const button = restartGameContainer.querySelector('#restart-game'); + button.addEventListener('click', this.restartGameHandler); + document.getElementById('end-of-game-buttons').appendChild(restartGameContainer); + } this.renderPlayersWithNoRoleInformationUnlessRevealed(); } } @@ -273,6 +313,10 @@ function renderPotentialMods (gameState, group, transferModHandlers, socket) { transferModHandlers[member.id] = (e) => { if (e.type === 'click' || e.code === 'Enter') { if (confirm('Transfer moderator powers to ' + member.name + '?')) { + const transferPrompt = document.getElementById('transfer-mod-prompt'); + if (transferPrompt !== null) { + transferPrompt.innerHTML = ''; + } socket.emit(globals.COMMANDS.TRANSFER_MODERATOR, gameState.accessCode, member.id); } } diff --git a/client/src/modules/GameTimerManager.js b/client/src/modules/GameTimerManager.js index 6313512..404cc08 100644 --- a/client/src/modules/GameTimerManager.js +++ b/client/src/modules/GameTimerManager.js @@ -135,6 +135,7 @@ export class GameTimerManager { const playBtn = document.createElement('img'); playBtn.setAttribute('src', '../images/play-button.svg'); playBtn.addEventListener('click', this.playListener); + document.querySelector('#play-pause-placeholder')?.remove(); document.getElementById('play-pause').appendChild(playBtn); } @@ -148,6 +149,7 @@ export class GameTimerManager { const pauseBtn = document.createElement('img'); pauseBtn.setAttribute('src', '../images/pause-button.svg'); pauseBtn.addEventListener('click', this.pauseListener); + document.querySelector('#play-pause-placeholder')?.remove(); document.getElementById('play-pause').appendChild(pauseBtn); } } diff --git a/client/src/modules/HTMLFragments.js b/client/src/modules/HTMLFragments.js index a5f8bc0..0bb0b8e 100644 --- a/client/src/modules/HTMLFragments.js +++ b/client/src/modules/HTMLFragments.js @@ -80,7 +80,7 @@ export const HTMLFragments = {
`, - MODERATOR_GAME_VIEW: + TRANSFER_MOD_MODAL: `