From d1da905cb903de6872a80d6e66f7196cb4203391 Mon Sep 17 00:00:00 2001 From: Alec Maier Date: Tue, 28 Apr 2020 02:56:42 -0400 Subject: [PATCH 1/2] gallery/list views for setup page --- assets/images/gallery.svg | 90 ++++++++++++++++++ assets/images/list.svg | 109 ++++++++++++++++++++++ static/modules/card-manager.js | 47 +++++++++- static/setup.js | 162 ++++++++++++++++++++++++--------- static/styles.css | 152 +++++++++++++++++++++++++++++-- views/create_game.html | 26 ++++-- views/index.html | 8 +- views/join_game.html | 4 +- 8 files changed, 527 insertions(+), 71 deletions(-) create mode 100644 assets/images/gallery.svg create mode 100644 assets/images/list.svg diff --git a/assets/images/gallery.svg b/assets/images/gallery.svg new file mode 100644 index 0000000..56a2e0f --- /dev/null +++ b/assets/images/gallery.svg @@ -0,0 +1,90 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/assets/images/list.svg b/assets/images/list.svg new file mode 100644 index 0000000..d3d8453 --- /dev/null +++ b/assets/images/list.svg @@ -0,0 +1,109 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/static/modules/card-manager.js b/static/modules/card-manager.js index 22e96d4..8277780 100644 --- a/static/modules/card-manager.js +++ b/static/modules/card-manager.js @@ -39,7 +39,11 @@ export class CardManager { let cardClass = card.isTypeOfWerewolf ? "card card-werewolf" : "card"; cardContainer.setAttribute("class", cardClass); - cardContainer.setAttribute("id", "card-" + index); + if (card.team === "good") { + cardContainer.setAttribute("id", "card-" + index); + } else { + cardContainer.setAttribute("id", "card-" + index); + } cardContainer.innerHTML = "
" + "
" + @@ -61,10 +65,45 @@ export class CardManager { return cardContainer; } - static constructCustomCardIndicator() { + static constructCompactDeckBuilderElement(card, index) { + const cardContainer = document.createElement("div"); + + const quantityClass = card.team === "good" ? "card-quantity quantity-village" : "card-quantity quantity-wolf"; + + let cardClass = card.isTypeOfWerewolf ? "compact-card card-werewolf" : "compact-card"; + cardContainer.setAttribute("class", cardClass); + if (card.team === "good") { + cardContainer.setAttribute("id", "card-" + index); + } else { + cardContainer.setAttribute("id", "card-" + index); + } + cardContainer.innerHTML = + "
" + + "

-

" + + "
" + + "
" + + "

" + card.role + "

" + + "
" + card.quantity + "
" + + "
" + + "
" + + "

+

" + + "
"; + return cardContainer; + } + + static constructCustomCardIndicator(isCondensed, team) { let customCard = document.createElement("div"); - customCard.classList.add("card", "custom-card"); - customCard.setAttribute("id", "custom"); + if (isCondensed) { + customCard.classList.add("compact-card", "custom-card"); + } else { + customCard.classList.add("card", "custom-card"); + } + + if (team === "good") { + customCard.setAttribute("id", "custom-good"); + } else { + customCard.setAttribute("id", "custom-evil"); + } let cardHeader = document.createElement("h1"); cardHeader.innerText = "Add Custom Role"; diff --git a/static/setup.js b/static/setup.js index dded4b7..7dd1766 100644 --- a/static/setup.js +++ b/static/setup.js @@ -21,12 +21,13 @@ const fullDeck = []; let gameSize = 0; let atLeastOnePlayer = false; - // register event listeners on buttons document.getElementById("reset-btn").addEventListener("click", resetCardQuantities); document.getElementById("create-btn").addEventListener("click", createGame); -document.getElementById("role-btn").addEventListener("click", function() { displayModal("role-modal") }); -document.getElementById("edit-role-btn").addEventListener("click", function() { displayModal("edit-custom-roles-modal") }); +document.getElementById("role-view-changer-gallery").addEventListener("click", function() { toggleViewChanger(false) }); +document.getElementById("role-view-changer-list").addEventListener("click", function() { toggleViewChanger(true) }); +document.getElementById("role-btn").addEventListener("click", function() { displayModal("role-modal", undefined) }); +document.getElementById("edit-role-btn").addEventListener("click", function() { displayModal("edit-custom-roles-modal", undefined) }); document.getElementById("custom-role-form").addEventListener("submit", function(e) { addCustomCardToRoles(e); }); @@ -37,48 +38,106 @@ Array.from(document.getElementsByClassName("close")).forEach(function(element) { // render all of the available cards to the user window.onload = function() { readInUserCustomRoles(); - renderAvailableCards(); + renderAvailableCards(false); }; -function renderAvailableCards() { +function renderAvailableCards(isCondensed) { cards.sort(function(a, b) { return a.role.toUpperCase().localeCompare(b.role); }); - document.getElementById("card-select").innerHTML = ""; + document.getElementById("card-select-good").innerHTML = ""; + document.getElementById("card-select-evil").innerHTML = ""; document.getElementById("roles").innerHTML = ""; document.getElementById("custom-roles").innerHTML = ""; + for (let i = 0; i < cards.length; i ++) { - const card = CardManager.createCard(cards[i]); - if (card.custom) { - renderCustomRoleInModal(cards[i], i); - } - fullDeck.push(card); - - document.getElementById("roles").appendChild(CardManager.constructModalRoleElement(card)); - document.getElementById("card-select").appendChild(CardManager.constructDeckBuilderElement(card, i)); - - // Add event listeners to the top and bottom halves of the card to change the quantity. - let cardTop = document.getElementById("card-" + i).getElementsByClassName("card-top")[0]; - let cardQuantity = document.getElementById("card-" + i).getElementsByClassName("card-quantity")[0]; - let cardBottom = document.getElementById("card-" + i).getElementsByClassName("card-bottom")[0]; - cardTop.addEventListener("click", incrementCardQuantity, false); - cardBottom.addEventListener("click", decrementCardQuantity, false); - cardTop.card = card; - cardTop.quantityEl = cardQuantity; - cardBottom.card = card; - cardBottom.quantityEl = cardQuantity; - + cards[i].team === "good" + ? renderGoodRole(cards[i], i, isCondensed) + : renderEvilRole(cards[i], i, isCondensed); } if (document.getElementById("custom-roles").getElementsByClassName("custom-role-edit").length === 0) { document.getElementById("custom-roles").innerHTML = "

You haven't added any custom cards.

"; } - let customCardElement = CardManager.constructCustomCardIndicator(); - document.getElementById("card-select").appendChild(customCardElement); - customCardElement.addEventListener("click", function() { - displayModal("custom-card-modal"); + let customCardGood = CardManager.constructCustomCardIndicator(isCondensed, "good"); + let customCardEvil = CardManager.constructCustomCardIndicator(isCondensed, "evil"); + document.getElementById("card-select-good").appendChild(customCardGood); + document.getElementById("card-select-evil").appendChild(customCardEvil); + customCardGood.addEventListener("click", function() { + displayModal("custom-card-modal", "Good"); }); + customCardEvil.addEventListener("click", function() { + displayModal("custom-card-modal", "Evil"); + }); +} + +function renderGoodRole(cardInfo, i, isCondensed) { + const card = CardManager.createCard(cardInfo); + if (card.custom) { + renderCustomRoleInModal(card, i); + } + fullDeck.push(card); + + document.getElementById("roles").appendChild(CardManager.constructModalRoleElement(card)); + if (isCondensed) { + document.getElementById("card-select-good").appendChild(CardManager.constructCompactDeckBuilderElement(card, i)); + let cardLeft = document.getElementById("card-" + i).getElementsByClassName("compact-card-left")[0]; + let cardQuantity = document.getElementById("card-" + i).getElementsByClassName("card-quantity")[0]; + let cardRight = document.getElementById("card-" + i).getElementsByClassName("compact-card-right")[0]; + cardRight.addEventListener("click", function() { incrementCardQuantity(cardRight) }, true); + cardLeft.addEventListener("click", function() { decrementCardQuantity(cardLeft) }, true); + cardRight.card = card; + cardRight.quantityEl = cardQuantity; + cardLeft.card = card; + cardLeft.quantityEl = cardQuantity; + } else { + document.getElementById("card-select-good").appendChild(CardManager.constructDeckBuilderElement(card, i)); + // Add event listeners to the top and bottom halves of the card to change the quantity. + let cardTop = document.getElementById("card-" + i).getElementsByClassName("card-top")[0]; + let cardQuantity = document.getElementById("card-" + i).getElementsByClassName("card-quantity")[0]; + let cardBottom = document.getElementById("card-" + i).getElementsByClassName("card-bottom")[0]; + cardTop.addEventListener("click", function() { incrementCardQuantity(cardTop) }, false); + cardBottom.addEventListener("click", function() { decrementCardQuantity(cardBottom) }, false); + cardTop.card = card; + cardTop.quantityEl = cardQuantity; + cardBottom.card = card; + cardBottom.quantityEl = cardQuantity; + } +} + +function renderEvilRole(cardInfo, i, isCondensed) { + const card = CardManager.createCard(cardInfo); + if (card.custom) { + renderCustomRoleInModal(card, i); + } + fullDeck.push(card); + + document.getElementById("roles").appendChild(CardManager.constructModalRoleElement(card)); + if (isCondensed) { + document.getElementById("card-select-evil").appendChild(CardManager.constructCompactDeckBuilderElement(card, i)); + let cardLeft = document.getElementById("card-" + i).getElementsByClassName("compact-card-left")[0]; + let cardQuantity = document.getElementById("card-" + i).getElementsByClassName("card-quantity")[0]; + let cardRight = document.getElementById("card-" + i).getElementsByClassName("compact-card-right")[0]; + cardRight.addEventListener("click", function() { incrementCardQuantity(cardRight) }, false); + cardLeft.addEventListener("click", function() { decrementCardQuantity(cardLeft) }, false); + cardRight.card = card; + cardRight.quantityEl = cardQuantity; + cardLeft.card = card; + cardLeft.quantityEl = cardQuantity; + } else { + document.getElementById("card-select-evil").appendChild(CardManager.constructDeckBuilderElement(card, i)); + // Add event listeners to the top and bottom halves of the card to change the quantity. + let cardTop = document.getElementById("card-" + i).getElementsByClassName("card-top")[0]; + let cardQuantity = document.getElementById("card-" + i).getElementsByClassName("card-quantity")[0]; + let cardBottom = document.getElementById("card-" + i).getElementsByClassName("card-bottom")[0]; + cardTop.addEventListener("click", function() { incrementCardQuantity(cardTop) }, false); + cardBottom.addEventListener("click", function() { decrementCardQuantity(cardBottom) }, false); + cardTop.card = card; + cardTop.quantityEl = cardQuantity; + cardBottom.card = card; + cardBottom.quantityEl = cardQuantity; + } } function addCustomCardToRoles(e) { @@ -93,7 +152,7 @@ function addCustomCardToRoles(e) { saved: document.getElementById("custom-role-remember").checked }; cards.push(newCard); - renderAvailableCards(); + renderAvailableCards(document.getElementById("role-view-changer-list").classList.contains("selected")); if (newCard.saved === true) { let existingRoles = localStorage.getItem("play-werewolf-custom-roles"); @@ -148,7 +207,6 @@ function renderCustomRoleInModal(card, index) { let edit = document.createElement("img"); let editForm = buildRoleEditForm(index); - // TODO: add edit functionality roleName.innerText = card.role; remove.setAttribute("src", "../assets/images/delete.svg"); remove.setAttribute("title", "Delete"); @@ -183,6 +241,18 @@ function toggleEditForm(event, index) { } } +function toggleViewChanger(isCondensed) { + + if (isCondensed) { + document.getElementById("role-view-changer-gallery").classList.remove("selected"); + document.getElementById("role-view-changer-list").classList.add("selected"); + } else { + document.getElementById("role-view-changer-gallery").classList.add("selected"); + document.getElementById("role-view-changer-list").classList.remove("selected"); + } + renderAvailableCards(isCondensed); +} + function buildRoleEditForm(index) { let infoForm = document.createElement("div"); infoForm.style.display = "none"; @@ -230,7 +300,7 @@ function removeCustomRole(name) { localStorage.setItem("play-werewolf-custom-roles", JSON.stringify(userCustomRoles)); } updateCustomRoleModal(); - renderAvailableCards(); + renderAvailableCards(document.getElementById("role-view-changer-list").classList.contains("selected")); } } @@ -245,7 +315,7 @@ function updateCustomRole(event, index) { removeOrAddSavedRoleIfNeeded(cardToUpdate); toggleEditForm(event, index); - renderAvailableCards(); + renderAvailableCards(document.getElementById("role-view-changer-list").classList.contains("selected")); } } @@ -273,18 +343,18 @@ function removeOrAddSavedRoleIfNeeded(card) { function incrementCardQuantity(e) { - if(e.target.card.quantity < 25) { - e.target.card.quantity += 1; + if(e.card.quantity < 25) { + e.card.quantity += 1; } - e.target.quantityEl.innerHTML = e.target.card.quantity; + e.quantityEl.innerHTML = e.card.quantity; updateGameSize(); } function decrementCardQuantity(e) { - if(e.target.card.quantity > 0) { - e.target.card.quantity -= 1; + if(e.card.quantity > 0) { + e.card.quantity -= 1; } - e.target.quantityEl.innerHTML = e.target.card.quantity; + e.quantityEl.innerHTML = e.card.quantity; updateGameSize(); } @@ -308,7 +378,15 @@ function resetCardQuantities() { }); } -function displayModal(modalId) { +function displayModal(modalId, teamForCustomRole) { + if (teamForCustomRole === "Good") { + document.getElementById("option-evil").removeAttribute("selected"); + document.getElementById("option-good").setAttribute("selected", "selected"); + } + if (teamForCustomRole === "Evil") { + document.getElementById("option-good").removeAttribute("selected"); + document.getElementById("option-evil").setAttribute("selected", "selected"); + } document.getElementById(modalId).classList.remove("hidden"); document.getElementById("app-content").classList.add("hidden"); } @@ -366,10 +444,8 @@ function createGame() { document.getElementById("some-error").innerText = "There are problems with your above setup."; if (!atLeastOnePlayer) { document.getElementById("game-size").classList.add("error"); - document.getElementById("size-error").innerText = "Add at least one card"; } else { document.getElementById("game-size").classList.remove("error"); - document.getElementById("size-error").innerText = ""; } document.getElementById("name").classList.add("error"); document.getElementById("name-error").innerText = "Name is required."; diff --git a/static/styles.css b/static/styles.css index c4d50ac..0285750 100644 --- a/static/styles.css +++ b/static/styles.css @@ -18,6 +18,10 @@ font-size: 20px; } + textarea { + font-size: 14px; + } + #game-container { flex-direction: column; } @@ -33,6 +37,22 @@ font-size: 0.9em; } + .custom-role-edit { + font-size: 15px; + } + + .compact-card, .compact-card-header { + width: 9em; + } + + #card-select-header #role-view-changer img { + width: 20px; + } + + #role-view-changer div { + font-size: 14px; + } + .card-header > p { right: 7px; top: 19px; @@ -136,11 +156,19 @@ margin: 0.5em 0; } + #card-select-header #role-view-changer img { + width: 25px; + } + .card-header > p { right: 17px; top: 30px; } + textarea { + font-size: 1.1em; + } + #game-container #card-container { min-width: 25em; } @@ -158,6 +186,14 @@ margin: 0.5em; } + .compact-card, .compact-card-header { + width: 11em; + } + + .custom-role-edit { + font-size: 19px; + } + .disclaimer, .custom-card h1 { font-size: 18px; } @@ -288,8 +324,6 @@ html, body { margin: 0 auto; - width: 100%; - height: 100%; color: #bfb8b8; font-family: 'sitewide-sans-serif', sans-serif; background-color: #23282b !important; @@ -454,7 +488,6 @@ button { width: 100%; flex-direction: column; justify-content: space-around; - font-size: 19px; align-items: center; background-color: black; border-radius: 5px; @@ -499,7 +532,7 @@ button { filter: brightness(70%); } -.card { +.card, .compact-card { text-align: center; cursor: pointer; position: relative; @@ -511,6 +544,63 @@ button { user-select: none; } +.compact-card { + display: flex; + height: max-content; + position: relative; +} + +.compact-card h1 { + display: flex; + align-items: center; + font-size: 14px; + margin: 0 10px 0 10px; +} + +.compact-card .card-role { + color: #bfb8b8; + margin: 0; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + max-width: 8em; +} + +.compact-card-right p { + font-size: 40px; + margin: 0 10px 0 0; + display: flex; + justify-content: flex-end; +} + +.compact-card-left p { + font-size: 40px; + margin: 0 0 0 10px; + display: flex; + justify-content: flex-start; +} + +.compact-card-left, .compact-card-right { + width: 50%; +} + +.compact-card .card-quantity { + text-align: center; + margin: 0; +} + +.compact-card-header { + position: absolute; + flex-direction: column; + align-items: center; + justify-content: center; + display: flex; + top: 0; + right: 0; + pointer-events: none; + text-align: center; +} + .card-werewolf { border: 1px solid red; } @@ -523,13 +613,14 @@ button { .custom-card div { font-size: 40px; color: whitesmoke; + margin-right: 5px; } .custom-card h1 { color: whitesmoke; } -.card:hover { +.card:hover, .compact-card:hover { background-color: #55565c; } @@ -615,12 +706,24 @@ button { } #card-select { + margin-bottom: 2em; +} + +#card-select-good, #card-select-evil { display: flex; display: -webkit-flex; -webkit-flex-wrap: wrap; - margin-bottom: 3em; } +#card-select > h2:nth-child(1) { + color: #4a6bff; +} + +#card-select > h2:nth-child(3) { + color: #bd2a2a; +} + + .app-btn-secondary { display: flex; justify-content: space-around; @@ -690,8 +793,8 @@ button { #main-buttons button { width: 100%; - padding: 1.2em; - font-size: 1em; + padding: 1em; + font-size: 0.9em; box-shadow: 2px 3px 8px rgba(0, 0, 0, 0.4); background-color: #992626; color: #bfb8b8; @@ -720,6 +823,36 @@ button { align-items: center; } +#card-select-header #role-view-changer img { + margin-left: 15px; +} + +#role-view-changer div { + display: flex; + justify-content: space-around; + width: max-content; + margin: 0 15px 0 0; + padding: 5px; + border-radius: 3px; +} + +.selected { + background: #494f52; +} + +#role-view-changer div:hover { + cursor: pointer; + background-color: #494f52; +} + +#role-view-changer { + margin: 15px 0 0 0; +} + +#role-view-changer p { + margin: 0; +} + #card-select-header h3 { margin: 0; font-size: 1.2em; @@ -729,7 +862,7 @@ button { #create-game-container button { padding: 0.8em; height: 3em; - width: fit-content; + width: max-content; } #edit-role-btn > img { @@ -848,7 +981,6 @@ textarea { color: gray; padding: 0.9em; border-radius: 5px; - font-size: 1.1em; } .checkbox label::before{ diff --git a/views/create_game.html b/views/create_game.html index 7b434aa..3c03253 100644 --- a/views/create_game.html +++ b/views/create_game.html @@ -38,13 +38,13 @@

Add a Custom Role

- +
@@ -66,13 +66,13 @@
@@ -90,11 +90,23 @@
= Werewolf role (counts for parity)
-

+ + + +
+

Condensed View

+ +
- +

Good Roles

+
+

Evil Roles

+