X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=public%2Fjavascripts%2Fcomponents%2Fgame.js;h=d8fbe47d1c61c77c3a81aae4f1c514805c26e250;hb=748eef1fe9eb666318e2a4c84c1627085666ab07;hp=80a8e7cbd302a772b5f29b016b3a5ee71a51ec0b;hpb=e6dcb115eab52abefa1d54a65af546cf5a0153e9;p=vchess.git diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js index 80a8e7cb..d8fbe47d 100644 --- a/public/javascripts/components/game.js +++ b/public/javascripts/components/game.js @@ -40,7 +40,6 @@ Vue.component('my-game', { }, render(h) { const [sizeX,sizeY] = [V.size.x,V.size.y]; - const smallScreen = (window.innerWidth <= 420); // Precompute hints squares to facilitate rendering let hintSquares = doubleArray(sizeX, sizeY, false); this.possibleMoves.forEach(m => { hintSquares[m.end.x][m.end.y] = true; }); @@ -53,13 +52,13 @@ Vue.component('my-game', { h('button', { on: { click: this.clickGameSeek }, - attrs: { "aria-label": 'New online game' }, + attrs: { "aria-label": translations['New online game'] }, 'class': { "tooltip": true, - "bottom": true, //display below + "play": true, "seek": this.seek, "playing": this.mode == "human", - "small": smallScreen, + "spaceright": true, }, }, [h('i', { 'class': { "material-icons": true } }, "accessibility")]) @@ -70,12 +69,12 @@ Vue.component('my-game', { h('button', { on: { click: this.clickComputerGame }, - attrs: { "aria-label": 'New game VS computer' }, + attrs: { "aria-label": translations['New game versus computer'] }, 'class': { "tooltip":true, - "bottom": true, + "play": true, "playing": this.mode == "computer", - "small": smallScreen, + "spaceright": true, }, }, [h('i', { 'class': { "material-icons": true } }, "computer")]) @@ -87,12 +86,12 @@ Vue.component('my-game', { h('button', { on: { click: this.clickFriendGame }, - attrs: { "aria-label": 'New IRL game' }, + attrs: { "aria-label": translations['Analysis mode'] }, 'class': { "tooltip":true, - "bottom": true, + "play": true, "playing": this.mode == "friend", - "small": smallScreen, + "spaceright": true, }, }, [h('i', { 'class': { "material-icons": true } }, "people")]) @@ -105,27 +104,33 @@ Vue.component('my-game', { ? parseFloat(window.getComputedStyle(square00).width.slice(0,-2)) : 0; const settingsBtnElt = document.getElementById("settingsBtn"); - const indicWidth = !!settingsBtnElt //-2 for border: - ? parseFloat(window.getComputedStyle(settingsBtnElt).height.slice(0,-2)) - 2 - : (smallScreen ? 31 : 37); + const settingsStyle = !!settingsBtnElt + ? window.getComputedStyle(settingsBtnElt) + : {width:"46px", height:"26px"}; + const [indicWidth,indicHeight] = //[44,24]; + [ + // NOTE: -2 for border + parseFloat(settingsStyle.width.slice(0,-2)) - 2, + parseFloat(settingsStyle.height.slice(0,-2)) - 2 + ]; + let aboveBoardElts = []; if (["chat","human"].includes(this.mode)) { const connectedIndic = h( 'div', { "class": { - "topindicator": true, "indic-left": true, "connected": this.oppConnected, "disconnected": !this.oppConnected, }, style: { "width": indicWidth + "px", - "height": indicWidth + "px", + "height": indicHeight + "px", }, } ); - elementArray.push(connectedIndic); + aboveBoardElts.push(connectedIndic); } if (this.mode == "chat") { @@ -134,20 +139,19 @@ Vue.component('my-game', { { on: { click: this.startChat }, attrs: { - "aria-label": 'Start chat', + "aria-label": translations['Start chat'], "id": "chatBtn", }, 'class': { "tooltip": true, - "topindicator": true, + "play": true, + "above-board": true, "indic-left": true, - "settings-btn": !smallScreen, - "settings-btn-small": smallScreen, }, }, [h('i', { 'class': { "material-icons": true } }, "chat")] ); - elementArray.push(chatButton); + aboveBoardElts.push(chatButton); } else if (this.mode == "computer") { @@ -156,56 +160,59 @@ Vue.component('my-game', { { on: { click: this.clearComputerGame }, attrs: { - "aria-label": 'Clear computer game', + "aria-label": translations['Clear game versus computer'], "id": "clearBtn", }, 'class': { "tooltip": true, - "topindicator": true, + "play": true, + "above-board": true, "indic-left": true, - "settings-btn": !smallScreen, - "settings-btn-small": smallScreen, }, }, [h('i', { 'class': { "material-icons": true } }, "clear")] ); - elementArray.push(clearButton); + aboveBoardElts.push(clearButton); } const turnIndic = h( 'div', { "class": { - "topindicator": true, "indic-right": true, "white-turn": this.vr.turn=="w", "black-turn": this.vr.turn=="b", }, style: { "width": indicWidth + "px", - "height": indicWidth + "px", + "height": indicHeight + "px", }, } ); - elementArray.push(turnIndic); + aboveBoardElts.push(turnIndic); const settingsBtn = h( 'button', { on: { click: this.showSettings }, attrs: { - "aria-label": 'Settings', + "aria-label": translations['Settings'], "id": "settingsBtn", }, 'class': { "tooltip": true, - "topindicator": true, + "play": true, + "above-board": true, "indic-right": true, - "settings-btn": !smallScreen, - "settings-btn-small": smallScreen, }, }, [h('i', { 'class': { "material-icons": true } }, "settings")] ); - elementArray.push(settingsBtn); + aboveBoardElts.push(settingsBtn); + elementArray.push( + h('div', + { "class": { "aboveboard-wrapper": true } }, + aboveBoardElts + ) + ); if (this.mode == "problem") { // Show problem instructions @@ -273,7 +280,10 @@ Vue.component('my-game', { (!["idle","chat"].includes(this.mode) || this.cursor==this.vr.moves.length); const gameDiv = h('div', { - 'class': { 'game': true }, + 'class': { + 'game': true, + 'clearer': true, + }, }, [_.range(sizeX).map(i => { let ci = (this.mycolor=='w' ? i : sizeX-i-1); @@ -351,11 +361,10 @@ Vue.component('my-game', { h('button', { on: { click: this.resign }, - attrs: { "aria-label": 'Resign' }, + attrs: { "aria-label": translations['Resign'] }, 'class': { "tooltip":true, - "bottom": true, - "small": smallScreen, + "play": true, }, }, [h('i', { 'class': { "material-icons": true } }, "flag")]) @@ -368,9 +377,9 @@ Vue.component('my-game', { h('button', { on: { click: e => this.undo() }, - attrs: { "aria-label": 'Undo' }, + attrs: { "aria-label": translations['Undo'] }, "class": { - "small": smallScreen, + "play": true, "spaceleft": true, }, }, @@ -378,8 +387,11 @@ Vue.component('my-game', { h('button', { on: { click: e => this.play() }, - attrs: { "aria-label": 'Play' }, - "class": { "small": smallScreen }, + attrs: { "aria-label": translations['Play'] }, + "class": { + "play": true, + "spaceleft": true, + }, }, [h('i', { 'class': { "material-icons": true } }, "fast_forward")]), ] @@ -392,9 +404,9 @@ Vue.component('my-game', { h('button', { on: { click: this.undoInGame }, - attrs: { "aria-label": 'Undo' }, + attrs: { "aria-label": translations['Undo'] }, "class": { - "small": smallScreen, + "play": true, "spaceleft": true, }, }, @@ -403,8 +415,11 @@ Vue.component('my-game', { h('button', { on: { click: () => { this.mycolor = this.vr.getOppCol(this.mycolor) } }, - attrs: { "aria-label": 'Flip' }, - "class": { "small": smallScreen }, + attrs: { "aria-label": translations['Flip'] }, + "class": { + "play": true, + "spaceleft": true, + }, }, [h('i', { 'class': { "material-icons": true } }, "cached")] ), @@ -419,13 +434,13 @@ Vue.component('my-game', { { myReservePiecesArray.push(h('div', { - 'class': {'board':true, ['board'+sizeY]:true}, + 'class': {'board':true, ['board'+sizeY+'-reserve']:true}, attrs: { id: this.getSquareId({x:sizeX+shiftIdx,y:i}) } }, [ h('img', { - 'class': {"piece":true}, + 'class': {"piece":true, "reserve":true}, attrs: { "src": "/images/pieces/" + this.vr.getReservePpath(this.mycolor,i) + ".svg", @@ -443,13 +458,13 @@ Vue.component('my-game', { { oppReservePiecesArray.push(h('div', { - 'class': {'board':true, ['board'+sizeY]:true}, + 'class': {'board':true, ['board'+sizeY+'-reserve']:true}, attrs: { id: this.getSquareId({x:sizeX+(1-shiftIdx),y:i}) } }, [ h('img', { - 'class': {"piece":true}, + 'class': {"piece":true, "reserve":true}, attrs: { "src": "/images/pieces/" + this.vr.getReservePpath(oppCol,i) + ".svg", @@ -499,7 +514,12 @@ Vue.component('my-game', { [ h('div', { - "class": { "card": true, "smallpad": true }, + "class": { + "card": true, + "smallpad": true, + "small-modal": true, + "text-center": true, + }, }, [ h('label', @@ -548,7 +568,7 @@ Vue.component('my-game', { { attrs: { "id": "titleFenedit" }, "class": { "section": true }, - domProps: { innerHTML: "Position + flags (FEN):" }, + domProps: { innerHTML: translations["Position + flags (FEN):"] }, } ), h('input', @@ -569,7 +589,7 @@ Vue.component('my-game', { this.newGame("friend", fen); } }, - domProps: { innerHTML: "Ok" }, + domProps: { innerHTML: translations["Ok"] }, } ), h('button', @@ -580,7 +600,7 @@ Vue.component('my-game', { VariantRules.GenRandInitFen(); } }, - domProps: { innerHTML: "Random" }, + domProps: { innerHTML: translations["Random"] }, } ), ] @@ -615,7 +635,7 @@ Vue.component('my-game', { { attrs: { "id": "settingsTitle" }, "class": { "section": true }, - domProps: { innerHTML: "Preferences" }, + domProps: { innerHTML: translations["Preferences"] }, } ), h('fieldset', @@ -624,7 +644,7 @@ Vue.component('my-game', { h('label', { attrs: { for: "nameSetter" }, - domProps: { innerHTML: "My name is..." }, + domProps: { innerHTML: translations["My name is..."] }, }, ), h('input', @@ -645,7 +665,7 @@ Vue.component('my-game', { h('label', { attrs: { for: "setHints" }, - domProps: { innerHTML: "Show hints?" }, + domProps: { innerHTML: translations["Show hints?"] }, }, ), h('input', @@ -666,7 +686,7 @@ Vue.component('my-game', { h('label', { attrs: { for: "selectColor" }, - domProps: { innerHTML: "Board colors" }, + domProps: { innerHTML: translations["Board colors"] }, }, ), h("select", @@ -679,7 +699,7 @@ Vue.component('my-game', { { domProps: { "value": "lichess", - innerHTML: "brown" + innerHTML: translations["brown"] }, attrs: { "selected": this.color=="lichess" }, } @@ -688,7 +708,7 @@ Vue.component('my-game', { { domProps: { "value": "chesscom", - innerHTML: "green" + innerHTML: translations["green"] }, attrs: { "selected": this.color=="chesscom" }, } @@ -697,7 +717,7 @@ Vue.component('my-game', { { domProps: { "value": "chesstempo", - innerHTML: "blue" + innerHTML: translations["blue"] }, attrs: { "selected": this.color=="chesstempo" }, } @@ -712,7 +732,7 @@ Vue.component('my-game', { h('label', { attrs: { for: "selectSound" }, - domProps: { innerHTML: "Play sounds?" }, + domProps: { innerHTML: translations["Play sounds?"] }, }, ), h("select", @@ -725,7 +745,7 @@ Vue.component('my-game', { { domProps: { "value": "0", - innerHTML: "None" + innerHTML: translations["None"] }, attrs: { "selected": this.sound==0 }, } @@ -734,7 +754,7 @@ Vue.component('my-game', { { domProps: { "value": "1", - innerHTML: "Newgame" + innerHTML: translations["New game"] }, attrs: { "selected": this.sound==1 }, } @@ -743,7 +763,7 @@ Vue.component('my-game', { { domProps: { "value": "2", - innerHTML: "All" + innerHTML: translations["All"] }, attrs: { "selected": this.sound==2 }, } @@ -770,7 +790,7 @@ Vue.component('my-game', { { attrs: { "id": "titleChat" }, "class": { "section": true }, - domProps: { innerHTML: "Chat with " + this.oppName }, + domProps: { innerHTML: translations["Chat with "] + this.oppName }, } ) ]; @@ -794,15 +814,16 @@ Vue.component('my-game', { attrs: { "id": "input-chat", type: "text", - placeholder: "Type here", + placeholder: translations["Type here"], }, on: { keyup: this.trySendChat }, //if key is 'enter' } ), h('button', { + attrs: { id: "sendChatBtn"}, on: { click: this.sendChat }, - domProps: { innerHTML: "Send" }, + domProps: { innerHTML: translations["Send"] }, } ) ]); @@ -862,7 +883,7 @@ Vue.component('my-game', { { attrs: { "id": "downloadBtn" }, on: { click: this.download }, - domProps: { innerHTML: "Download game" }, + domProps: { innerHTML: translations["Download game"] }, } ), ] @@ -883,7 +904,8 @@ Vue.component('my-game', { [ h('h3', { - domProps: { innerHTML: "Show solution" }, + "class": { clickable: true }, + domProps: { innerHTML: translations["Show solution"] }, on: { click: this.toggleShowSolution }, } ), @@ -908,7 +930,8 @@ Vue.component('my-game', { h('p', { attrs: { id: "fen-string" }, - domProps: { innerHTML: this.vr.getBaseFen() } + domProps: { innerHTML: this.vr.getBaseFen() }, + "class": { "text-center": true }, } ) ] @@ -920,10 +943,10 @@ Vue.component('my-game', { { 'class': { "col-sm-12":true, - "col-md-8":true, - "col-md-offset-2":true, - "col-lg-6":true, - "col-lg-offset-3":true, + "col-md-10":true, + "col-md-offset-1":true, + "col-lg-8":true, + "col-lg-offset-2":true, }, // NOTE: click = mousedown + mouseup on: { @@ -944,13 +967,13 @@ Vue.component('my-game', { switch (this.score) { case "1-0": - eogMessage = "White win"; + eogMessage = translations["White win"]; break; case "0-1": - eogMessage = "Black win"; + eogMessage = translations["Black win"]; break; case "1/2": - eogMessage = "Draw"; + eogMessage = translations["Draw"]; break; } return eogMessage; @@ -985,7 +1008,8 @@ Vue.component('my-game', { // We opened another tab on the same game this.mode = "idle"; this.vr = null; - alert("Already playing a game in this variant on another tab!"); + alert(translations[ + "Already playing a game in this variant on another tab!"]); break; case "newgame": //opponent found // oppid: opponent socket ID @@ -1255,7 +1279,10 @@ Vue.component('my-game', { { const storageVariant = localStorage.getItem("variant"); if (!!storageVariant && storageVariant !== variant) - return alert("Finish your " + storageVariant + " game first!"); + { + return alert(translations["Finish your "] + + storageVariant + translations[" game first!"]); + } // Send game request and wait.. try { this.conn.send(JSON.stringify({code:"newgame", fen:fen})); @@ -1281,8 +1308,8 @@ Vue.component('my-game', { const score = localStorage.getItem("comp-score"); if (storageVariant !== variant && score == "*") { - if (!confirm("Unfinished " + storageVariant + - " computer game will be erased")) + if (!confirm(storageVariant + + translations[": unfinished computer game will be erased"])) { return; } @@ -1329,6 +1356,7 @@ Vue.component('my-game', { const fen = localStorage.getItem(prefix+"fen"); const score = localStorage.getItem(prefix+"score"); //set in "endGame()" this.fenStart = localStorage.getItem(prefix+"fenStart"); + this.vr = new VariantRules(fen, moves); if (mode == "human") { this.gameId = localStorage.getItem("gameId"); @@ -1337,8 +1365,11 @@ Vue.component('my-game', { code:"ping",oppid:this.oppid,gameId:this.gameId})); } else + { this.compWorker.postMessage(["init",fen]); - this.vr = new VariantRules(fen, moves); + if (this.mycolor != this.vr.turn) + this.playComputerMove(); + } if (moves.length > 0) { const lastMove = moves[moves.length-1];