Show cards on client side
This commit is contained in:
parent
cdf079698e
commit
4fe71136a2
@ -60,6 +60,12 @@ async function performLeaveTableRequest(token) {
|
||||
.then(function(value) {})
|
||||
}
|
||||
|
||||
async function performDealCardsRequest(token) {
|
||||
return fetch("/deal", { method: 'POST', body: token })
|
||||
.then(convertServerResponse)
|
||||
.then(function(value) {})
|
||||
}
|
||||
|
||||
function convertServerResponse(response) {
|
||||
switch (response.status) {
|
||||
case 200: // Success
|
||||
|
@ -2,38 +2,65 @@
|
||||
* This file acts as an abstraction layer between HTML and JS.
|
||||
*/
|
||||
|
||||
function hideLoginWindow() {
|
||||
document.getElementById("signup-window").style.display = "none"
|
||||
var playerName = ""
|
||||
|
||||
function setDisplayStyle(id, style) {
|
||||
document.getElementById(id).style.display = style
|
||||
}
|
||||
|
||||
function showLoginWindow() {
|
||||
document.getElementById("signup-window").style.display = "table"
|
||||
}
|
||||
|
||||
function hideTableListElements() {
|
||||
document.getElementById("table-list-bar").style.display = "none"
|
||||
document.getElementById("table-list").style.display = "none"
|
||||
function showLoginElements() {
|
||||
setDisplayStyle("login-window", "table")
|
||||
setDisplayStyle("top-bar", "none")
|
||||
setDisplayStyle("table-list-bar", "none")
|
||||
setDisplayStyle("table-list", "none")
|
||||
setDisplayStyle("game-bar", "none")
|
||||
setDisplayStyle("table-players", "none")
|
||||
setDisplayStyle("player-cards", "none")
|
||||
}
|
||||
|
||||
function showTableListElements() {
|
||||
document.getElementById("table-list-bar").style.display = "grid"
|
||||
document.getElementById("table-list").style.display = "inherit"
|
||||
setDisplayStyle("login-window", "none")
|
||||
setDisplayStyle("top-bar", "inherit")
|
||||
setDisplayStyle("table-list-bar", "grid")
|
||||
setDisplayStyle("table-list", "inherit")
|
||||
setDisplayStyle("game-bar", "none")
|
||||
setDisplayStyle("table-players", "none")
|
||||
setDisplayStyle("player-cards", "none")
|
||||
}
|
||||
|
||||
function showGameElements() {
|
||||
document.getElementById("game-bar").style.display = "grid"
|
||||
setDisplayStyle("login-window", "none")
|
||||
setDisplayStyle("top-bar", "inherit")
|
||||
setDisplayStyle("table-list-bar", "none")
|
||||
setDisplayStyle("table-list", "none")
|
||||
setDisplayStyle("game-bar", "grid")
|
||||
setDisplayStyle("table-players", "grid")
|
||||
setDisplayStyle("player-cards", "grid")
|
||||
}
|
||||
|
||||
function hideGameElements() {
|
||||
document.getElementById("game-bar").style.display = "none"
|
||||
function showConnectedState() {
|
||||
const label = document.getElementById("table-connected-label")
|
||||
label.innerHTML = "Connected"
|
||||
label.style.color = "var(--text-color)"
|
||||
}
|
||||
|
||||
function showDisconnectedState() {
|
||||
const label = document.getElementById("table-connected-label")
|
||||
label.innerHTML = "Disconnected"
|
||||
label.style.color = "var(--alert-color)"
|
||||
}
|
||||
|
||||
function showDealButton() {
|
||||
setDisplayStyle("deal-button", "inherit")
|
||||
}
|
||||
|
||||
function hideDealButton() {
|
||||
setDisplayStyle("deal-button", "none")
|
||||
}
|
||||
|
||||
function setPlayerName(name) {
|
||||
document.getElementById("player-name").innerHTML = name
|
||||
}
|
||||
|
||||
function getPlayerName() {
|
||||
return document.getElementById("player-name").innerHTML
|
||||
playerName = name
|
||||
}
|
||||
|
||||
function getLoginName() {
|
||||
@ -83,3 +110,41 @@ function getTableVisibility() {
|
||||
function setTableListContent(content) {
|
||||
document.getElementById("table-list").innerHTML = content
|
||||
}
|
||||
|
||||
function setTablePlayerInfo(nr, name, connected, active) {
|
||||
const infoElement = "table-player-name" + nr.toString()
|
||||
const connectionElement = "table-player-state" + nr
|
||||
const nameElement = document.getElementById(infoElement)
|
||||
if (name == "") {
|
||||
nameElement.innerHTML = "Empty"
|
||||
nameElement.style.color = "var(--secondary-text-color)"
|
||||
setDisplayStyle(connectionElement, "none")
|
||||
return
|
||||
}
|
||||
nameElement.innerHTML = name
|
||||
nameElement.style.color = active ? "var(--button-color)" : "var(--text-color)"
|
||||
if (connected) {
|
||||
setDisplayStyle(connectionElement, "none")
|
||||
} else {
|
||||
setDisplayStyle(connectionElement, "inherit")
|
||||
}
|
||||
}
|
||||
|
||||
function setTableCard(index, card) {
|
||||
const id = "table-player-card" + index.toString()
|
||||
setCard(id, card)
|
||||
}
|
||||
|
||||
function setHandCard(index, card, playable) {
|
||||
const id = "player-card" + index.toString()
|
||||
setCard(id, card)
|
||||
document.getElementById(id).disabled = true
|
||||
}
|
||||
|
||||
function setCard(id, card) {
|
||||
if (card == "") {
|
||||
document.getElementById(id).style.backgroundColor = "var(--element-background)"
|
||||
} else {
|
||||
document.getElementById(id).style.backgroundImage = "url('/cards/" + card + ".jpeg')"
|
||||
}
|
||||
}
|
@ -10,9 +10,12 @@ function closeSocketIfNeeded() {
|
||||
}
|
||||
}
|
||||
|
||||
function didLeaveTable() {
|
||||
tableId = ""
|
||||
}
|
||||
|
||||
function didCloseSocket() {
|
||||
socket = null
|
||||
tableId = ""
|
||||
}
|
||||
|
||||
function setTableId(table) {
|
||||
@ -21,25 +24,20 @@ function setTableId(table) {
|
||||
|
||||
function showBlankLoginScreen(text) {
|
||||
closeSocketIfNeeded()
|
||||
didLeaveTable()
|
||||
clearLoginPassword()
|
||||
clearLoginName()
|
||||
deleteSessionToken()
|
||||
showLoginWindow()
|
||||
showLoginElements()
|
||||
setLoginError(text)
|
||||
}
|
||||
|
||||
function showTableList() {
|
||||
showTableListElements()
|
||||
hideLoginWindow()
|
||||
}
|
||||
|
||||
function showGame(tableId) {
|
||||
setTableId(tableId)
|
||||
const token = getSessionToken()
|
||||
if (token) {
|
||||
openSocket(token)
|
||||
hideTableListElements()
|
||||
showGameElements()
|
||||
openSocket(token)
|
||||
// TODO: Show interface
|
||||
console.log("Show table " + tableId)
|
||||
} else {
|
||||
@ -62,7 +60,7 @@ function registerUser() {
|
||||
.then(function(token) {
|
||||
setSessionToken(token)
|
||||
setPlayerName(username)
|
||||
showTableList()
|
||||
showTableListElements()
|
||||
loadCurrentTable(token)
|
||||
}).catch(function(error) {
|
||||
setLoginError(error.message)
|
||||
@ -79,6 +77,7 @@ function deletePlayerAccount() {
|
||||
console.log("Player deleted")
|
||||
} else {
|
||||
closeSocketIfNeeded()
|
||||
didLeaveTable()
|
||||
deleteSessionToken()
|
||||
alert(error)
|
||||
console.log(error)
|
||||
@ -101,7 +100,7 @@ function loginUser() {
|
||||
.then(function(token) {
|
||||
setSessionToken(token)
|
||||
setPlayerName(username)
|
||||
showTableList()
|
||||
showTableListElements()
|
||||
loadCurrentTable(token)
|
||||
}).catch(function(error) {
|
||||
setLoginError(error.message)
|
||||
@ -129,7 +128,7 @@ function loadExistingSession() {
|
||||
resumeSessionRequest(token)
|
||||
.then(function(name) {
|
||||
setPlayerName(name)
|
||||
showTableList()
|
||||
showTableListElements()
|
||||
loadCurrentTable(token)
|
||||
}).catch(function(error) {
|
||||
showBlankLoginScreen(error.message)
|
||||
@ -143,9 +142,11 @@ function loadCurrentTable(token) {
|
||||
performGetCurrentTableRequest(token)
|
||||
.then(function(tableId) {
|
||||
if (tableId == "") {
|
||||
didLeaveTable()
|
||||
refreshTables()
|
||||
return
|
||||
}
|
||||
console.log("Loaded table " + tableId)
|
||||
showGame(tableId)
|
||||
}).catch(function(error) {
|
||||
showBlankLoginScreen(error.message)
|
||||
@ -192,8 +193,10 @@ function leaveTable() {
|
||||
if (token) {
|
||||
performLeaveTableRequest(token)
|
||||
.then(function() {
|
||||
showTableList()
|
||||
hideGameElements()
|
||||
showTableListElements()
|
||||
closeSocketIfNeeded()
|
||||
didLeaveTable()
|
||||
refreshTables()
|
||||
})
|
||||
.catch(function(error) {
|
||||
showBlankLoginScreen(error.message)
|
||||
@ -208,22 +211,26 @@ function openSocket(token) {
|
||||
|
||||
socket.onopen = function(e) {
|
||||
socket.send(token);
|
||||
showConnectedState()
|
||||
};
|
||||
|
||||
socket.onmessage = function(event) {
|
||||
// TODO: Handle server data
|
||||
//event.data
|
||||
handleServerUpdates(event.data)
|
||||
};
|
||||
|
||||
socket.onclose = function(event) {
|
||||
if (event.wasClean) {
|
||||
didCloseSocket()
|
||||
|
||||
} else {
|
||||
// e.g. server process killed or network down
|
||||
// event.code is usually 1006 in this case
|
||||
// TODO: Retry several times to open socket,
|
||||
// stop after too many failed attempts
|
||||
}
|
||||
didCloseSocket()
|
||||
showDisconnectedState()
|
||||
};
|
||||
|
||||
socket.onerror = function(error) {
|
||||
@ -231,6 +238,39 @@ function openSocket(token) {
|
||||
};
|
||||
}
|
||||
|
||||
function handleServerUpdates(data) {
|
||||
const info = JSON.parse(data.substring(1))
|
||||
if (data.startsWith("t")) {
|
||||
handleTableInfoUpdate(info)
|
||||
} else if (data.startsWith("c")) {
|
||||
handleCardInfoUpdate(info)
|
||||
} else {
|
||||
console.log("Unhandled update: " + data)
|
||||
}
|
||||
}
|
||||
|
||||
function handleTableInfoUpdate(info) {
|
||||
for (let i = 0, len = info.players.length; i < len; i += 1) {
|
||||
const player = info.players[i]
|
||||
// TODO: Mark active player
|
||||
setTablePlayerInfo(i + 1, player.name, player.connected, false)
|
||||
}
|
||||
if (info.tableIsFull) {
|
||||
showDealButton()
|
||||
} else {
|
||||
hideDealButton()
|
||||
}
|
||||
}
|
||||
|
||||
function handleCardInfoUpdate(info) {
|
||||
for (let i = 0, len = info.cards.length; i < len; i += 1) {
|
||||
setHandCard(i+1, info.cards[i].card, info.cards[i].playable)
|
||||
}
|
||||
for (let i = 0, len = info.tableCards.length; i < len; i += 1) {
|
||||
setTableCard(i+1, info.tableCards[i])
|
||||
}
|
||||
}
|
||||
|
||||
function refreshTables() {
|
||||
const token = getSessionToken()
|
||||
if (token) {
|
||||
@ -240,7 +280,6 @@ function refreshTables() {
|
||||
setTableListContent(html)
|
||||
}).catch(function(error) {
|
||||
showBlankLoginScreen(error.message)
|
||||
return
|
||||
})
|
||||
} else {
|
||||
showBlankLoginScreen()
|
||||
@ -258,8 +297,25 @@ function processTableList(tables) {
|
||||
html += "<button class=\"table-join-btn\" disabled>Full</button>"
|
||||
}
|
||||
html += "<div class=\"table-title\">" + tableInfo.name + "</div>"
|
||||
html += "<div class=\"table-subtitle\">Players: " + tableInfo.players.join(", ") + "</div>"
|
||||
if (tableInfo.players.length == 0) {
|
||||
html += "<div class=\"table-subtitle\">No players</div>"
|
||||
} else {
|
||||
const names = tableInfo.players.map(function(player) { return player.name }).join(", ")
|
||||
html += "<div class=\"table-subtitle\">Players: " + names + "</div>"
|
||||
}
|
||||
html += "</div>" // table-row
|
||||
}
|
||||
return html
|
||||
}
|
||||
|
||||
function dealCards() {
|
||||
const token = getSessionToken()
|
||||
if (token) {
|
||||
performDealCardsRequest(token)
|
||||
.catch(function(error) {
|
||||
showBlankLoginScreen(error.message)
|
||||
})
|
||||
} else {
|
||||
showBlankLoginScreen()
|
||||
}
|
||||
}
|
@ -24,11 +24,50 @@
|
||||
</div>
|
||||
<div id="game-bar">
|
||||
<button id="leave-table" class="standard-button" onclick="leaveTable()">Leave table</button>
|
||||
<span id="table-connected-label">Disconnected</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
<div id="main-spacer"></div>
|
||||
<div id="table-list">
|
||||
</div>
|
||||
<div id="table-players">
|
||||
<button id="deal-button" class="standard-button" onclick="dealCards()">Deal cards</button>
|
||||
<button id="bid-button" class="standard-button" onclick="increaseBid()">Bid</button>
|
||||
<button id="fold-button" class="standard-button" onclick="fold()">Fold</button>
|
||||
<div id="table-player-card1" class="table-card"></div>
|
||||
<div id="table-player-card2" class="table-card"></div>
|
||||
<div id="table-player-card3" class="table-card"></div>
|
||||
<div id="table-player-card4" class="table-card"></div>
|
||||
<div id="table-player-info1">
|
||||
<div id="table-player-name1">Player 1</div>
|
||||
<div id="table-player-state1" class="player-connection-state">Offline</div>
|
||||
</div>
|
||||
<div id="table-player-info2">
|
||||
<div id="table-player-name2">Player 2</div>
|
||||
<div id="table-player-state2" class="player-connection-state">Offline</div>
|
||||
</div>
|
||||
<div id="table-player-info3">
|
||||
<div id="table-player-name3">Player 3</div>
|
||||
<div id="table-player-state3" class="player-connection-state">Offline</div>
|
||||
</div>
|
||||
<div id="table-player-info4">
|
||||
<div id="table-player-name4">Player 4</div>
|
||||
<div id="table-player-state4" class="player-connection-state">Offline</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="player-cards">
|
||||
<button id="player-card1" class="player-card" disabled></button>
|
||||
<button id="player-card2" class="player-card" disabled></button>
|
||||
<button id="player-card3" class="player-card" disabled></button>
|
||||
<button id="player-card4" class="player-card" disabled></button>
|
||||
<button id="player-card5" class="player-card" disabled></button>
|
||||
<button id="player-card6" class="player-card" disabled></button>
|
||||
<button id="player-card7" class="player-card" disabled></button>
|
||||
<button id="player-card8" class="player-card" disabled></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="login-window">
|
||||
<div id="login-window-vertical-center">
|
||||
|
211
Public/style.css
211
Public/style.css
@ -1,13 +1,16 @@
|
||||
:root {
|
||||
/* Color definitions for light mode */
|
||||
--button-color: rgb(255, 172, 39);
|
||||
--button-hover: rgb(255, 185, 72);
|
||||
--button-color: rgb(233, 144, 0);
|
||||
--button-hover: rgb(255, 191, 89);
|
||||
--button-disabled: rgb(128, 88, 24);
|
||||
--button-text: rgb(0,0,0);
|
||||
--standard-background: rgb(54, 54, 54);
|
||||
--element-background: rgb(42, 42, 42);
|
||||
--element-border: rgb(27, 27, 27);
|
||||
--text-color: rgb(255,255,255);
|
||||
--secondary-text-color: rgb(27, 27, 27);
|
||||
--card-color: rgb(255,255,255);
|
||||
--alert-color: rgb(255,0,0);
|
||||
}
|
||||
|
||||
/* Style all input fields */
|
||||
@ -47,10 +50,15 @@ html * {
|
||||
body, html {
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0px;
|
||||
background-color: var(--standard-background);
|
||||
}
|
||||
|
||||
body {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#login-window {
|
||||
background-color: var(--standard-background);
|
||||
height: 100%;
|
||||
@ -91,15 +99,19 @@ body, html {
|
||||
height: 50px;
|
||||
background-color: var(--element-background);
|
||||
padding: 0px;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#player-info {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
height: 50px;
|
||||
width: 205px;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-template-columns: auto auto;
|
||||
grid-template-columns: 120px 80px;
|
||||
column-gap: 5px;
|
||||
}
|
||||
|
||||
@ -107,6 +119,7 @@ body, html {
|
||||
text-align: right;
|
||||
grid-column: 1;
|
||||
padding-right: 5px;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
#logout-button {
|
||||
@ -164,12 +177,12 @@ body, html {
|
||||
|
||||
#game-bar {
|
||||
position: absolute;
|
||||
width: 120px;
|
||||
width: 270px;
|
||||
height: 40px;
|
||||
top: 5px;
|
||||
left: 10px;
|
||||
display: none;
|
||||
grid-template-columns: 1200px;
|
||||
grid-template-columns: 120px 140px;
|
||||
column-gap: 10px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@ -183,6 +196,26 @@ body, html {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
#table-connected-label {
|
||||
grid-column: 2;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
#main {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#main-spacer {
|
||||
height: 50px;
|
||||
position: relative;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
#table-list {
|
||||
margin: 20px;
|
||||
padding-right: 20px;
|
||||
@ -236,3 +269,171 @@ body, html {
|
||||
grid-row: 2;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
#table-players {
|
||||
display: none;
|
||||
margin-top: 20px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 549px;
|
||||
height: 437px;
|
||||
grid-template-columns: 150px 71px 36px 35px 36px 71px 150px;
|
||||
grid-template-rows: 111px 76px 35px 76px 111px;
|
||||
column-gap: 0px;
|
||||
row-gap: 0px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#deal-button {
|
||||
display: none;
|
||||
grid-column: 7;
|
||||
grid-row: 5;
|
||||
}
|
||||
|
||||
#fold-button {
|
||||
display: none;
|
||||
grid-column: 1;
|
||||
grid-row: 5;
|
||||
}
|
||||
|
||||
#bid-button {
|
||||
display: none;
|
||||
grid-column: 7;
|
||||
grid-row: 5;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
height: 187px;
|
||||
border-radius: 17px;
|
||||
background-color: var(--element-background);
|
||||
}
|
||||
|
||||
#table-player-card1 { /* bottom */
|
||||
grid-column: 3 / span 3;
|
||||
grid-row: 4 / span 2;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#table-player-card2 { /* left */
|
||||
grid-column: 2 / span 2;
|
||||
grid-row: 2 / span 3;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#table-player-card3 { /* top */
|
||||
grid-column: 3 / span 3;
|
||||
grid-row: 1 / span 2;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
#table-player-card4 { /* right */
|
||||
grid-column: 5 / span 2;
|
||||
grid-row: 2 / span 3;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
#table-player-info1 { /* bottom */
|
||||
grid-column: 1 / span 2;
|
||||
grid-row: 5;
|
||||
font-size: large;
|
||||
text-align: right;
|
||||
margin-right: 15px;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
#table-player-info2 { /* left */
|
||||
grid-column: 1;
|
||||
grid-row: 3;
|
||||
font-size: large;
|
||||
text-align: right;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
#table-player-info3 { /* top */
|
||||
grid-column: 1 / span 2;
|
||||
grid-row: 1;
|
||||
font-size: large;
|
||||
text-align: right;
|
||||
margin-right: 15px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
#table-player-info4 { /* right */
|
||||
grid-column: 7;
|
||||
grid-row: 3;
|
||||
font-size: large;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.player-connection-state {
|
||||
font-size: x-small;
|
||||
color: var(--alert-color);
|
||||
}
|
||||
|
||||
#table-player-state1 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#table-player-state2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#player-cards {
|
||||
display: none;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 923px;
|
||||
grid-template-columns: 111px 111px 111px 111px 111px 111px 111px 111px;
|
||||
column-gap: 5px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.player-card {
|
||||
width: 111px;
|
||||
height: 191px;
|
||||
border: 2px solid var(--standard-background);
|
||||
background-color: var(--element-background);
|
||||
border-radius: 17px;
|
||||
transition-duration: 0.2s;
|
||||
}
|
||||
|
||||
.player-card:disabled,
|
||||
.player-card[disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.player-card:hover:enabled {
|
||||
border-color: var(--button-hover);
|
||||
}
|
||||
|
||||
#player-card1 {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
#player-card2 {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
#player-card3 {
|
||||
grid-column: 3;
|
||||
}
|
||||
|
||||
#player-card4 {
|
||||
grid-column: 4;
|
||||
}
|
||||
|
||||
#player-card5 {
|
||||
grid-column: 5;
|
||||
}
|
||||
|
||||
#player-card6 {
|
||||
grid-column: 6;
|
||||
}
|
||||
|
||||
#player-card7 {
|
||||
grid-column: 7;
|
||||
}
|
||||
|
||||
#player-card8 {
|
||||
grid-column: 8;
|
||||
}
|
Loading…
Reference in New Issue
Block a user