Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit name at any time #170

Merged
merged 5 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions client/src/config/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export const PRIMITIVES = {
USER_SIGNATURE_LENGTH: 75,
CLOCK_TICK_INTERVAL_MILLIS: 50,
MAX_CUSTOM_ROLE_NAME_LENGTH: 50,
MAX_PERSON_NAME_LENGTH: 40,
MAX_DECK_SIZE: 50,
MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH: 1000,
TOAST_DURATION_DEFAULT: 6,
ACCESS_CODE_LENGTH: 4,
Expand Down
Binary file modified client/src/images/tutorial/player-view.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions client/src/modules/front_end_components/Confirmation.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { toast } from './Toast.js';

export const Confirmation = (message, onYes = null, isDOMNode = false) => {
export const Confirmation = (message, onYes = null, isDOMNode = false, confirmButtonText = 'Yes') => {
document.querySelector('#confirmation')?.remove();
document.querySelector('#confirmation-background')?.remove();

Expand All @@ -11,7 +11,7 @@ export const Confirmation = (message, onYes = null, isDOMNode = false) => {
? `<div id="confirmation-message"></div>
<div class="confirmation-buttons">
<button id="confirmation-cancel-button" class="app-button cancel">Cancel</button>
<button id="confirmation-yes-button" class="app-button">Yes</button>
<button id="confirmation-yes-button" class="app-button">` + confirmButtonText + `</button>
</div>`
: `<div id="confirmation-message"></div>
<div class="confirmation-buttons-centered">
Expand Down
29 changes: 12 additions & 17 deletions client/src/modules/front_end_components/HTMLFragments.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export const HTMLFragments = {
</div>
<div id='game-people-container'>
<div id="current-moderator" class="moderator">
<div id="current-moderator-name"></div>
<div id="current-moderator-name" class="person-name-element"></div>
<div id="current-moderator-type"></div>
</div>
<label id='players-alive-label'></label>
Expand Down Expand Up @@ -128,7 +128,7 @@ export const HTMLFragments = {
</div>
<div id='game-people-container'>
<div id="current-moderator" class="moderator">
<div id="current-moderator-name"></div>
<div id="current-moderator-name" class="person-name-element"></div>
<div id="current-moderator-type"></div>
</div>
<label id='players-alive-label'></label>
Expand Down Expand Up @@ -245,7 +245,7 @@ export const HTMLFragments = {
</div>`,
MODERATOR_PLAYER:
`<div>
<div class='game-player-name'></div>
<div class='game-player-name person-name-element'></div>
<div class='game-player-role'></div>
</div>
<div class='player-action-buttons'>
Expand All @@ -254,7 +254,7 @@ export const HTMLFragments = {
</div>`,
GAME_PLAYER:
`<div>
<div class='game-player-name'></div>
<div class='game-player-name person-name-element'></div>
<div class='game-player-role'></div>
</div>`,
INITIAL_GAME_DOM:
Expand All @@ -265,6 +265,9 @@ export const HTMLFragments = {
<div id='client-name'></div>
<div id='client-user-type'></div>
</div>
<button id="edit-name-button">
<img alt="edit name" src="../../images/pencil.svg"/>
</button>
</div>
<div id='game-state-container'></div>`,
// via https://loading.io/css/
Expand All @@ -283,18 +286,10 @@ export const HTMLFragments = {
<div></div>
<div></div>
</div>`,
NAME_CHANGE_MODAL:
`<div id='change-name-modal-background' class='modal-background'></div>
<div tabindex='-1' id='change-name-modal' class='modal'>
<form id='change-name-form'>
<div id='transfer-mod-form-content'>
<label for='player-new-name'>Your name:</label>
<input id='player-new-name' autocomplete='given-name' type='text'/>
</div>
<div class='modal-button-container'>
<input type='submit' id='submit-new-name' value='Set Name'/>
</div>
</form>
NAME_CHANGE_FORM:
`<div id='change-name-form-content'>
<label for='client-new-name'>Your name:</label>
<input maxlength="40" id='client-new-name' autocomplete='off' type='text'/>
</div>`,
ROLE_INFO_MODAL:
`<div id='role-info-modal-background' class='modal-background'></div>
Expand All @@ -314,7 +309,7 @@ export const HTMLFragments = {
</div>
<div id='game-people-container'>
<div id="current-moderator" class="moderator">
<div id="current-moderator-name"></div>
<div id="current-moderator-name" class="person-name-element"></div>
<div id="current-moderator-type"></div>
</div>
<label id='players-alive-label'></label>
Expand Down
18 changes: 9 additions & 9 deletions client/src/modules/game_creation/GameCreationStepManager.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Game } from '../../model/Game.js';
import { cancelCurrentToast, toast } from '../front_end_components/Toast.js';
import { ModalManager } from '../front_end_components/ModalManager.js';
import { ALIGNMENT } from '../../config/globals.js';
import { ALIGNMENT, PRIMITIVES } from '../../config/globals.js';
import { HTMLFragments } from '../front_end_components/HTMLFragments.js';
import { UserUtility } from '../utility/UserUtility.js';
import { RoleBox } from './RoleBox.js';
Expand Down Expand Up @@ -35,8 +35,8 @@ export class GameCreationStepManager {
2: {
title: 'Create your deck (you can edit this later):',
forwardHandler: () => {
if (this.deckManager.getDeckSize() > 50) {
toast('Your deck is too large. The max is 50 cards.', 'error', true);
if (this.deckManager.getDeckSize() > PRIMITIVES.MAX_DECK_SIZE) {
toast('Your deck is too large. The max is ' + PRIMITIVES.MAX_DECK_SIZE + ' cards.', 'error', true);
} else {
this.currentGame.deck = this.deckManager.deck.filter((card) => card.quantity > 0);
cancelCurrentToast();
Expand Down Expand Up @@ -98,7 +98,7 @@ export class GameCreationStepManager {
this.incrementStep();
this.renderStep('creation-step-container', this.step);
} else {
toast('Name must be between 1 and 30 characters.', 'error', true);
toast('Name must be between 1 and ' + PRIMITIVES.MAX_PERSON_NAME_LENGTH + ' characters.', 'error', true);
}
}
},
Expand Down Expand Up @@ -569,12 +569,12 @@ function initializeRemainingEventListeners (deckManager, roleBox) {
}

function processNewCustomRoleSubmission (name, description, team, deckManager, isUpdate, roleBox, option = null) {
if (name.length > 40) {
toast('Your name is too long (max 40 characters).', 'error', true);
if (name.length > PRIMITIVES.MAX_CUSTOM_ROLE_NAME_LENGTH) {
toast('Your name is too long (max ' + PRIMITIVES.MAX_CUSTOM_ROLE_NAME_LENGTH + ' characters).', 'error', true);
return;
}
if (description.length > 500) {
toast('Your description is too long (max 500 characters).', 'error', true);
if (description.length > PRIMITIVES.MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH) {
toast('Your description is too long (max ' + PRIMITIVES.MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH + ' characters).', 'error', true);
return;
}
if (isUpdate) {
Expand All @@ -596,5 +596,5 @@ function hasTimer (hours, minutes) {
}

function validateName (name) {
return typeof name === 'string' && name.length > 0 && name.length <= 30;
return typeof name === 'string' && name.length > 0 && name.length <= PRIMITIVES.MAX_PERSON_NAME_LENGTH;
}
1 change: 1 addition & 0 deletions client/src/modules/game_state/states/Ended.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function renderGroupOfPlayers (
for (const player of people) {
const playerEl = document.createElement('div');
playerEl.classList.add('game-player');
playerEl.dataset.pointer = player.id;
playerEl.innerHTML = HTMLFragments.GAME_PLAYER;

playerEl.querySelector('.game-player-name').innerText = player.name;
Expand Down
1 change: 1 addition & 0 deletions client/src/modules/game_state/states/InProgress.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ export class InProgress {
for (const player of people) {
const playerEl = document.createElement('div');
playerEl.classList.add('game-player');
playerEl.dataset.pointer = player.id;

// add a reference to the player's id for each corresponding element in the list
if (moderatorType) {
Expand Down
7 changes: 4 additions & 3 deletions client/src/modules/game_state/states/Lobby.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { QRCode } from '../../third_party/qrcode.js';
import { toast } from '../../front_end_components/Toast.js';
import { EVENT_IDS, SOCKET_EVENTS, USER_TYPE_ICONS, USER_TYPES } from '../../../config/globals.js';
import { EVENT_IDS, PRIMITIVES, SOCKET_EVENTS, USER_TYPE_ICONS, USER_TYPES } from '../../../config/globals.js';
import { HTMLFragments } from '../../front_end_components/HTMLFragments.js';
import { Confirmation } from '../../front_end_components/Confirmation.js';
import { SharedStateUtil } from './shared/SharedStateUtil.js';
Expand Down Expand Up @@ -79,7 +79,7 @@ export class Lobby {
roleEditPrompt.setAttribute('id', 'role-edit-prompt');
roleEditPrompt.innerHTML = HTMLFragments.ROLE_EDIT_BUTTONS;
roleEditPrompt.querySelector('#save-role-changes-button').addEventListener('click', () => {
if (this.gameCreationStepManager.deckManager.getDeckSize() > 50) {
if (this.gameCreationStepManager.deckManager.getDeckSize() > PRIMITIVES.MAX_DECK_SIZE) {
toast('Your deck is too large. The max is 50 cards.', 'error', true);
} else {
document.querySelector('#mid-game-role-editor')?.remove();
Expand Down Expand Up @@ -354,8 +354,9 @@ function getTimeString (gameState) {

function renderLobbyPerson (person, gameState, socket) {
const el = document.createElement('div');
el.dataset.pointer = person.id;
const personNameEl = document.createElement('div');
personNameEl.classList.add('lobby-player-name');
personNameEl.classList.add('lobby-player-name', 'person-name-element');
const personTypeEl = document.createElement('div');
personNameEl.innerText = person.name;
personTypeEl.innerText = person.userType + USER_TYPE_ICONS[person.userType];
Expand Down
33 changes: 28 additions & 5 deletions client/src/modules/game_state/states/shared/SharedStateUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,9 @@ export const SharedStateUtil = {
} else {
for (const spectator of spectators) {
const spectatorEl = document.createElement('div');
spectatorEl.dataset.pointer = spectator.id;
spectatorEl.classList.add('spectator');
spectatorEl.innerHTML = '<div class=\'spectator-name\'></div>' +
spectatorEl.innerHTML = '<div class=\'spectator-name person-name-element\'></div>' +
'<div>' + 'spectator' + USER_TYPE_ICONS.spectator + '</div>';
spectatorEl.querySelector('.spectator-name').innerText = spectator.name;
list.appendChild(spectatorEl);
Expand All @@ -123,6 +124,7 @@ export const SharedStateUtil = {
},

displayCurrentModerator: (moderator) => {
document.getElementById('current-moderator').dataset.pointer = moderator.id;
document.getElementById('current-moderator-name').innerText = moderator.name;
document.getElementById('current-moderator-type').innerText = moderator.userType + USER_TYPE_ICONS[moderator.userType];
},
Expand Down Expand Up @@ -183,9 +185,30 @@ export const SharedStateUtil = {
});
},

displayClientInfo: (name, userType) => {
document.getElementById('client-name').innerText = name;
document.getElementById('client-user-type').innerText = userType;
document.getElementById('client-user-type').innerText += USER_TYPE_ICONS[userType];
displayClientInfo: (gameState, socket) => {
document.getElementById('client-name').innerText = gameState.client.name;
document.getElementById('client-user-type').innerText = gameState.client.userType;
document.getElementById('client-user-type').innerText += USER_TYPE_ICONS[gameState.client.userType];
const nameForm = document.createElement('form');
nameForm.setAttribute('id', 'name-change-form');
nameForm.onsubmit = (e) => {
e.preventDefault();
document.getElementById('confirmation-yes-button').click();
};
nameForm.innerHTML = HTMLFragments.NAME_CHANGE_FORM;
nameForm.querySelector('#client-new-name').value = gameState.client.name;
document.getElementById('edit-name-button').addEventListener('click', () => {
Confirmation(nameForm, () => {
socket.emit(
SOCKET_EVENTS.IN_GAME_MESSAGE,
EVENT_IDS.CHANGE_NAME,
gameState.accessCode,
{ personId: gameState.client.id, newName: document.getElementById('client-new-name').value },
(response) => {
toast(response.message, response.errorFlag === 1 ? 'error' : 'success', true);
}
);
}, true, 'Update');
});
}
};
16 changes: 15 additions & 1 deletion client/src/modules/page_handlers/gameHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function processGameState (
});
}

SharedStateUtil.displayClientInfo(currentGameState.client.name, currentGameState.client.userType);
SharedStateUtil.displayClientInfo(currentGameState, socket);

switch (currentGameState.status) {
case STATUS.LOBBY:
Expand Down Expand Up @@ -236,6 +236,20 @@ function setClientSocketHandlers (stateBucket, socket) {
);
});

socket.on(EVENT_IDS.CHANGE_NAME, (changedId, newName) => {
const person = stateBucket.currentGameState.people.find(person => person.id === changedId);
if (person) {
person.name = newName;
if (stateBucket.currentGameState.client.id === changedId) {
stateBucket.currentGameState.client.name = newName;
SharedStateUtil.displayClientInfo(stateBucket.currentGameState, socket);
}
document.querySelectorAll('[data-pointer="' + person.id + '"]').forEach((node) => {
node.querySelector('.person-name-element').innerText = newName;
});
}
});

socket.on(EVENT_IDS.END_GAME, (people) => {
stateBucket.currentGameState.people = people;
stateBucket.currentGameState.status = STATUS.ENDED;
Expand Down
4 changes: 2 additions & 2 deletions client/src/scripts/join.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const joinHandler = (e) => {
resetJoinButtonState(e, joinHandler);
});
} else {
toast('Name must be between 1 and 30 characters.', 'error', true, true, 'long');
toast('Name must be between 1 and ' + PRIMITIVES.MAX_PERSON_NAME_LENGTH + ' characters.', 'error', true, true, 'long');
}
};

Expand Down Expand Up @@ -90,7 +90,7 @@ function resetJoinButtonState (e, joinHandler) {
}

function validateName (name) {
return typeof name === 'string' && name.length > 0 && name.length <= 30;
return typeof name === 'string' && name.length > 0 && name.length <= PRIMITIVES.MAX_PERSON_NAME_LENGTH;
}

if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
Expand Down
9 changes: 7 additions & 2 deletions client/src/styles/GLOBAL.css
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ button {
}

#how-to-use-container h1 {
color: #d7d7d7;
color: #21ba45;
font-family: signika-negative, sans-serif;
background-color: #1e1b26;
width: fit-content;
Expand Down Expand Up @@ -376,6 +376,11 @@ input {
#how-to-use-container h3 {
color: #b1afcd;
font-weight: bold;
font-family: signika-negative, sans-serif;
background-color: #1e1b26;
width: fit-content;
padding: 0 5px;
border-radius: 5px;
}

#tutorial-links {text-align: left;
Expand Down Expand Up @@ -829,7 +834,7 @@ input {

@media(max-width: 550px) {
.how-to-use-header {
font-size: 25px;
font-size: 30px;
}
#how-to-use-container h3 {
font-size: 20px;
Expand Down
Loading
Loading