[Client] Various improvements and fixes to all game pages

This commit is contained in:
AudricV 2023-04-03 22:55:00 +02:00
parent 9abf67d597
commit e38c2e2621
No known key found for this signature in database
GPG Key ID: DA92EC7905614198
9 changed files with 213 additions and 259 deletions

View File

@ -47,8 +47,8 @@
:root {
/* Colors */
color-scheme: dark;
--alert-dialog-background-color: #000000DF;
--dark-theme-background-color: #0c0b0c;
--background-color: #141416;
--filter-background-color: #000000DF;
--game-black: #000000;
--game-blue: #7DDCFF;
--game-green: #008000;
@ -57,7 +57,6 @@
--game-gold: rgb(214,168,81);
--game-dark-gold: #B9935A;
--game-white: #FFFFFF;
--light-theme-background-color: #B1EDE8;
/* Sizes */
--body-margin: 0.375em;
--button-and-dialog-border-radius: 1em;
@ -65,6 +64,8 @@
}
html {
background-color: var(--background-color);
color: var(--game-white);
margin: 0;
}
@ -82,6 +83,7 @@ noscript .alert_dialog_background, noscript .alert_dialog_msg, noscript .alert_d
border-radius: var(--button-and-dialog-border-radius);
border-style: solid;
border-width: 0.125em;
color: var(--game-white);
cursor: pointer;
overflow: hidden;
padding-bottom: 0.5em;
@ -96,15 +98,6 @@ noscript .alert_dialog_background, noscript .alert_dialog_msg, noscript .alert_d
align-items: center;
}
/* Themes */
.dark {
background-color: var(--dark-theme-background-color);
}
.light {
background-color: var(--light-theme-background-color);
}
/* Utility classes */
.hidden {
display: none !important;
@ -195,7 +188,7 @@ noscript .alert_dialog_background, noscript .alert_dialog_msg, noscript .alert_d
}
.alert_dialog_background {
background-color: var(--alert-dialog-background-color);
background-color: var(--filter-background-color);
display: none;
height: 100vh;
left: 0;

View File

@ -1,4 +1,8 @@
/* Common properties */
* {
box-sizing: border-box;
}
html {
background-color: var(--game-black);
color: var(--game-white);
@ -8,11 +12,11 @@ html {
text-transform: uppercase;
}
.action_button, .scores, .summary {
.action_button, .chat_btn, .scores, .summary, #open_chat_button {
font-family: "Titan One", sans-serif;
}
.anwser_title, .emotion_and_culprit_choices_title, .introduction_text, .introduction_title, .interrogation_title, .results_title,.introduction_right ,.reveal_culprit_title, .score_title, .summary_title {
.anwser_title, .emotion_and_culprit_choices_title, .introduction_text, .introduction_title, .interrogation_title, .results_title, .introduction_right, .reveal_culprit_title, .score_title, .summary_title, #chat_popup_title {
font-family: "Ironick", serif;
}
@ -57,7 +61,7 @@ html {
text-align: center;
}
.explain_suspect_emotion_title, .interrogation_title, .introduction_title, .results_title, .reveal_culprit_title, .score_title, .suspect_answer {
.explain_suspect_emotion_title, .interrogation_title, .introduction_title, .results_title, .reveal_culprit_title, .score_title, .suspect_answer, #open_chat_button {
font-weight: bold;
}
@ -93,6 +97,10 @@ html {
background-color: transparent;
}
.message, #chat_message_box {
font-family: "Roboto Mono", sans-serif;
}
.question_answer, .questions_list, .questions_and_image, .reveal_culprit, .suspect_picture[alt], .scores, .summary_suspect, .suspects, .suspects_list {
align-content: center;
}
@ -110,33 +118,37 @@ html {
}
.suspect_picture {
border: var(--game-dark-gold) solid 5px;
border-color: var(--game-dark-gold);
border-radius: 1em;
border-style: solid;
border-width: 0.125em;
height: 15em;
width: 15em;
transition: all 0.5s ease;
width: 15em;
}
.npc_answer {
flex-direction: column;
width: 40em;
}
.image_interrogation {
height: 25em;
width: 25em;
}
.question_answer {
border: var(--game-dark-gold) solid;
background-color: #000000d0;
border-color: var(--game-dark-gold);
border-style: solid;
border-radius: 1em;
height: 6em;
background-color: #000000d0;
}
.suspect > .suspect_picture:hover {
background-color: var(--filter-background-color);
filter: grayscale(0);
transition: all 0.5s ease;
background-color: #000000d0;
}
.suspect_picture[alt] {
@ -169,26 +181,32 @@ background-color: #000000d0;
}
#emotion_and_culprit_choices_next_btn, #interrogation_next_btn, #interrogation_suspect_previous_btn, #return_to_home_btn {
position: fixed;
left: calc(100% - 6em);
position: fixed;
top: 1em;
}
/* Introduction */
.introduction {
padding: 1em;
align-content: center;
align-items: center;
display: flex;
flex-direction: row;
}
.introduction_left{
flex-wrap: wrap;
justify-content: center;
justify-items: center;
padding: 1em;
max-width: 50vw;
}
.introduction_left, .introduction_right {
padding: 1em;
width: 48vw; /* 50vw - padding * 2 */
}
.introduction_right {
font-size: 2em;
padding: 1em;
max-width: 50vw;
}
.introduction_text {
font-size: 3em;
margin-bottom: 1em;
@ -201,11 +219,10 @@ background-color: #000000d0;
}
.inspector_picture {
border: var(--game-dark-gold) solid 5px;
background-color: var(--filter-background-color);
border: var(--game-dark-gold) solid 0.125em;
border-radius: 1em;
max-width: 45vw;
background-color: #000000d0;
position: fixed;
width: 100%;
}
.username {
@ -220,6 +237,7 @@ background-color: #000000d0;
color: var(--game-black);
text-transform: none;
}
.anwser_title {
font-size: 2.5em;
margin: 0.25em;
@ -238,11 +256,8 @@ background-color: #000000d0;
margin-top: 1em;
}
#interrogation_suspect_previous_btn {
margin-right: 1em;
}
.suspect_name {
font-family: "Park Lane";
font-family: "Park Lane", serif;
font-size: 2em;
color: var(--game-dark-gold);
border-radius: 0.25em;
@ -252,6 +267,10 @@ background-color: #000000d0;
background-color: #000000dd;
}
#interrogation_suspect_previous_btn {
margin-right: 1em;
}
/* Emotion and culprit choices */
.culprit_icon {
fill: var(--game-white);
@ -260,13 +279,12 @@ background-color: #000000d0;
width: 1em;
}
.culprit_btn_checked {
background-color: var(--game-green);
}
.emotion_and_culprit_choices_title {
font-size: 2em;
font-size: 3em;
margin: 0.5em;
}
@ -299,7 +317,6 @@ background-color: #000000d0;
background-color: #000000d0;
}
.explain_suspect_emotion_description {
font-size: 1.25em;
font-weight: normal;
@ -349,86 +366,92 @@ background-color: #000000d0;
border: transparent;
}
* {box-sizing: border-box;}
/* chat */
/* Button used to open the chat form - fixed at the bottom of the page */
.open-button {
background-color: #000000dd;
color: var(--game-dark-gold);
padding: 16px 20px;
border: var(--game-dark-gold) solid;
border-radius: 1em;
cursor: pointer;
opacity: 0.8;
position: fixed;
bottom: 23px;
right: 28px;
width: 280px;
}
/* The popup chat - hidden by default */
/* Chat */
.chat-popup {
bottom: 0.5em;
color: var(--game-dark-gold);
display: none;
position: fixed;
bottom: 0;
color: var(--game-dark-gold);
right: 15px;
z-index: 9;
border: solid black 1px;
border-radius: 1em;
right: 0.5em;
z-index: 1;
}
/* Add styles to the form container */
.form-container {
max-width: 300px;
padding: 10px;
border: solid var(--game-dark-gold);
align-content: center;
align-items: center;
background-color: var(--game-black);
border-color: var(--game-dark-gold);
border-style: solid;
border-radius: 1em;
background-color: black;
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
padding: 0.25em;
width: calc(min(30em, 100vw) - 1em);
}
/* Full-width textarea */
.form-container textarea {
width: 100%;
padding: 15px;
margin: 5px 0 22px 0;
border: none;
background: #f1f1f1;
resize: none;
min-height: 5em;
}
/* When the textarea gets focus, do something */
#chat_message_box{
background-color: #505050;
outline: none;
margin: 10px;
}
.message{
list-style-type: none
}
/* Set a style for the submit/send button */
.form-container .btn {
background-color: black;
color: #04AA6D;
padding: 16px 20px;
border: #04AA6D solid;
.chat_btn {
border-radius: 1em;
border-style: solid;
cursor: pointer;
width: 100%;
margin-bottom:10px;
font-size: 1em;
margin: 1em;
opacity: 0.8;
padding: 0.25em;
width: 100%;
}
/* Add a red background color to the cancel button */
.form-container .cancel {
background-color: black;
color: red;
border-color: red;
}
/* Add some hover effects to buttons */
.form-container .btn:hover, .open-button:hover {
.chat_btn:hover, .open-button:hover {
opacity: 1;
}
.message {
font-size: 1em;
list-style-type: none;
}
#chat_button_send {
background-color: var(--game-green);
border-color: var(--game-green);
}
#close_chat_button {
background-color: var(--game-red);
border-color: var(--game-red);
}
#chat_message_box {
background-color: var(--game-grey);
border-style: solid;
border-width: 0.125em;
color: var(--game-white);
font-size: 1em;
outline: none;
margin: 1em;
width: 100%;
}
#chat_popup_title {
font-size: 2em;
margin: 0.25em;
}
#message_list {
padding: 0;
}
#open_chat_button {
background-color: var(--filter-background-color);
border: var(--game-dark-gold) solid;
border-radius: 1em;
bottom: 0.25em;
color: var(--game-dark-gold);
cursor: pointer;
font-size: 1.25em;
padding: 1em;
position: fixed;
opacity: 0.8;
right: 0.25em;
width: 5em;
}

View File

@ -1,7 +1,6 @@
/* Common properties */
html {
background-color: var(--game-grey);
color: var(--game-white);
font-family: "Roboto Mono", "sans-serif";
}

View File

@ -3,6 +3,7 @@ html {
background-color: var(--game-black);
color: var(--game-white);
}
.current_background {
background-position: center;
background-size: cover;
@ -178,7 +179,7 @@ html {
border-radius: 0.75em;
font-size: 1.25em;
max-height: 12em;
overflow-y: scroll;
overflow-y: auto;
padding: 0.25em;
}
@ -188,6 +189,10 @@ html {
margin: 1em;
}
.unjoined_view_players_list {
margin: 1em;
}
/* Game join view */
#game_username {
background-color: var(--game-white);
@ -199,7 +204,7 @@ html {
}
#join_game_button {
font-size: 1.25em;
font-size: 1.5em;
margin: 1em;
}

View File

@ -51,26 +51,24 @@ function unsetQuestionButtonsListeners() {
function setChatBoxButtonsListeners() {
document.getElementById("close_chat_button")
.addEventListener("click", closeForm);
.addEventListener("click", closeChatBox);
document.getElementById("open_chat_button")
.addEventListener("click", openForm);
.addEventListener("click", openChatBox);
document.getElementById("chat_button_send")
.addEventListener("click", sendChatMessage);
}
/**
* Shows the chat box
* Show the chat box.
*/
function openForm() {
function openChatBox() {
document.getElementById("chatbox").style.display = "block";
}
/**
* Hides the chat box
* Hide the chat box.
*/
function closeForm() {
function closeChatBox() {
document.getElementById("chatbox").style.display = "none";
}
@ -462,6 +460,7 @@ function initSock() {
suspect.classList.add("summary_suspect");
const img = document.createElement("img");
img.classList.add("suspect_picture");
img.setAttribute("alt", "Image d'un suspect");
img.src = NPC_FINAL_REACTION_PATH + finalResults["npcs"][npcid]["uuid"];
suspect.appendChild(img);

View File

@ -1,4 +1,5 @@
const LOBBY_IMAGE_PATH = "/static/images/cuisine.jpg"
const LOBBY_IMAGE_PATH = "/static/images/cuisine.jpg";
// Display functions
/*
@ -81,9 +82,11 @@ function displayInvalidNickNameErrorMessage(errorMessage) {
/**
* Start a game in the history mode.
*/
function startHistoryGame(event) {
event.target.textContent = "Chargement...";
makeAPIRequest("startGame");
function startHistoryGame(startHistoryGameButton) {
startHistoryGameButton.target.textContent = "Chargement\u00A0...";
makeAPIRequest("startGame").then(null, () => {
startHistoryGameButton.target.textContent = "Jouer";
});
}
/**
@ -99,19 +102,19 @@ function startChallengeGame() {
}
function getMembers() {
let data = {};
const data = {};
data['game_id'] = getRoomCode();
const response = makeAPIRequest("getGameMembers", data);
response.then(value => {
let divs = document.getElementsByClassName("player_names");
for (let playerList of divs) {
for (const playerList of document.getElementsByClassName("player_names")) {
value["members"].forEach(username => {
console.log(username);
playerList.appendChild(document.createTextNode(username + "\n"));
});
}
});
}
// Join room functions
/**
@ -357,14 +360,15 @@ function initSock() {
})
socket.on("gamestart", async () => {
if (await hasJoinedRoom()) window.location.href = "/multi";
if (await hasJoinedRoom()) {
window.location.href = "/multi";
}
})
socket.on("playersjoin", username => {
console.log(username);
Array.from(document.getElementsByClassName("player_names")).forEach(playerList =>{
for (const playerList of document.getElementsByClassName("player_names")) {
playerList.textContent += username + "\n";
})
}
});
}
@ -385,8 +389,8 @@ function initSock() {
* </p>
*/
async function initLobby() {
setGameBackground(LOBBY_IMAGE_PATH)
getMembers()
setGameBackground(LOBBY_IMAGE_PATH);
getMembers();
initSock();
if (await hasJoinedRoom()) {
displayRoomView();

View File

@ -118,7 +118,7 @@ function createMultiPlayerRoom(event) {
}
hideInvalidInputErrorMessage();
event.target.textContent = "Chargement...";
event.target.textContent = "Chargement\u00A0...";
startGame();
}
@ -131,99 +131,34 @@ function joinMultiPlayerRoom(event) {
}
hideInvalidInputErrorMessage();
event.target.textContent = "Chargement...";
joinGame();
event.target.textContent = "Chargement\u00A0...";
joinGame(event);
}
/**
* Set the current theme for the game.
* Launch a single player game.
*
* <p>
* The theme preference is read from the local storage.
* It sends the api request to
* create a game then it immediately starts the game by using the startGame API endpoint.
* </p>
*
* <p>
* If accessing to the local storage is not allow, an error message which prevents playing the game
* and requesting user to enable localStorage is shown, and the error is logged in the console.
* </p>
*/
function setCurrentTheme() {
const htmlElement = document.getElementsByTagName("html")[0];
try {
const currentTheme = localStorage.getItem("pref_theme");
if (currentTheme == "light") {
htmlElement.classList.remove("dark");
htmlElement.classList.add("light");
} else {
// Use dark theme by default
htmlElement.classList.remove("light");
htmlElement.classList.add("dark");
}
const btn = document.getElementsByClassName("theme_switcher")[0];
btn.addEventListener("pointerup", changeTheme);
} catch (e) {
console.error("Unable to set theme from localStorage", e);
htmlElement.classList.add("dark");
}
}
/**
* Change the theme from the current theme to its opposite.
*
* <p>
* If the current theme is "dark", it will become "light" and vice versa.
* </p>
*
* <p>
* The new theme is saved in the localStorage, if the browser allows this action; otherwise, an
* error message is shown in the console.
* </p>
*/
function changeTheme() {
const currentTheme = localStorage.getItem("pref_theme");
const htmlElement = document.getElementsByTagName("html")[0];
let newTheme;
if (currentTheme == "light") {
htmlElement.classList.remove("light");
htmlElement.classList.add("dark");
newTheme = "dark";
} else {
htmlElement.classList.remove("dark");
htmlElement.classList.add("light");
newTheme = "light";
}
try {
localStorage.setItem("pref_theme", newTheme);
} catch (e) {
console.error("Unable to save theme change to localStorage", e);
}
}
/**
* This function launches a single player game. It sends the api request to
* create a game then it immediately start the game by sendind the startGame api
*/
async function startSoloGame(event) {
if (!areInputsValid(false)) {
return;
}
event.target.textContent = "Chargement...";
event.target.textContent = "Chargement\u00A0...";
hideInvalidInputErrorMessage();
username = document.getElementById("game_username").value;
let data = {}
data["username"] = username;
data["solo"] = true;
await makeAPIRequest("createGame",data);
start = makeAPIRequest("startGame");
start.then(()=>{
makeAPIRequest("startGame").then(() => {
window.location.href = "/solo";
})
}, () => {
startHistoryGameButton.target.textContent = "Jouer";
});
}
/**
@ -238,13 +173,11 @@ async function startGame(){
response.then((value) => {
if (value["error"] != 0){
alert(value["msg"]);
}
else{
} else {
gameid = value["game_id"]
window.location.href = "/lobby/" + gameid;
}
});
}
/**
@ -252,7 +185,7 @@ async function startGame(){
* join an already existing game, to do so it calls the joinGame endpoint
* with the aftermentioned username and room code as parameter.
*/
async function joinGame(){
async function joinGame(event) {
username = document.getElementById("game_username").value;
gameid = document.getElementById("game_room_code").value;
console.log(username);
@ -268,7 +201,9 @@ async function joinGame(){
else{
window.location.href = "/lobby/" + gameid;
}
})
}, () => {
event.target.textContent = "Jouer";
});
}
// Set event listeners

View File

@ -20,7 +20,7 @@
<section class="introduction hidden">
<div class="introduction_left">
<h1 class="introduction_title">Truth Inquiry</h1>
<p class="introduction_text">Vous incarnez le célèbre détective <span id="username"></span> et vous êtes missionné pour résoudre une nouvelle affaire.<br> Hier, dans la soirée, cinq personnes ont été invitées par le Comte de la région dans son manoir. Cependant, dans la matinée, le Comte sest aperçu que son coffre avait été forcé.<br>Votre rôle est donc dinterroger les cinq suspects afin de comprendre leur état desprit et ainsi démasquer le coupable.<br>Cliquez sur la flèche pour découvrir les suspects et les interroger.</p>
<p class="introduction_text">Bienvenue dans Truth Inquiry, vous incarnez le célèbre détective <span id="username"></span> et êtes missionné(e) pour résoudre une nouvelle affaire.<br><br>Hier, dans la soirée, cinq personnes ont été invitées par le Comte de la région dans son manoir.<br><br>Cependant, dans la matinée, le Comte sest aperçu que son coffre avait été forcé.<br><br>Votre rôle est donc dinterroger les cinq suspects afin de comprendre leur état desprit et ainsi démasquer le coupable.<br><br>Cliquez sur la flèche pour découvrir les suspects et les interroger.</p>
<button id="introduction_next_btn" class="next_btn" aria-label="Commencer" title="Cliquez ici pour commencer à jouer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<path d="m23.15 36.95-17.3-11.1Q4.7 25.25 4.7 24t1.15-1.9L23.15 11q1.15-.7 2.35-.075 1.2.625 1.2 2.025v8.75h15.8q.95 0 1.625.675T44.8 24q0 .95-.675 1.6-.675.65-1.625.65H26.7V35q0 1.45-1.2 2.075-1.2.625-2.35-.125Z" />
@ -28,7 +28,7 @@
</button>
</div>
<div class="introduction_right">
<img class="inspector_picture" src="/static/images/inspector.png" alt="Image de l'inspecteur">
<img class="inspector_picture" src="/static/images/inspector.png" alt="Image de l'inspecteur" title="Une image de l'inspecteur">
</div>
</section>
<section class="interrogation hidden">
@ -39,23 +39,19 @@
</svg>
</button>
<ul class="suspects" id="interrogation_suspects"></ul>
<Section>
<button id="open_chat_button" class="open-button">Chat</button>
<button id="open_chat_button">Chat</button>
<div class="chat-popup" id="chatbox">
<div class="form-container">
<h1>Chat</h1>
<h1 id="chat_popup_title">Chat</h1>
<div class="messages_received_container">
<ul id="message_list" class="messages">
</ul>
</div>
<label for="msg"><b>Message</b></label>
<input type="text" id="chat_message_box" placeholder="Type message.." name="msg" required></textarea>
<button id="chat_button_send" class="btn">Send</button>
<button id="close_chat_button" type="button" class="btn cancel">Close</button>
<input type="text" id="chat_message_box" placeholder="Saisissez un message" name="msg" required="">
<button id="chat_button_send" class="chat_btn">Envoyer</button>
<button id="close_chat_button" type="button" class="chat_btn">Fermer</button>
</div>
</div>
</Section>
</section>
<section class="emotion_and_culprit_choices hidden">
<h1 class="emotion_and_culprit_choices_title">Choix du coupable et émotion des suspects</h1>

View File

@ -20,12 +20,12 @@
<input type="hidden" id="game_id" name="game_id" value={{gameid}}>
<section class="join_room_view hidden">
<h1 class="room_title">Salon</h1>
<div class="unjoinded_players_list">
<h2 class="players_title">Joueurs</h2>
<div class="unjoined_view_players_list">
<h2 class="players_title">Joueurs présents</h2>
<div class="player_names"></div>
</div>
<input type="text" id="game_username" placeholder="Entrez un pseudo" value="" required="required" maxlength="20">
<button id="join_game_button" class="action_button">Rejoindre</button>
<input id="game_username" type="text" placeholder="Entrez un pseudo" value="" required="required" maxlength="20" title="Entrez un pseudo pour rejoindre le salon">
<button id="join_game_button" class="action_button">Rejoindre le salon</button>
<p class="game_start_failed hidden">Une erreur s'est produite. Réessayez ultérieurement.</p>
</section>
<section class="room_view hidden">