X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fcomponents%2FBaseGame.vue;h=0e0f37208858c87f933b209be4a963dc5e167da7;hb=677fe285f1137d1d3e672dcf2dae3ac6e943be37;hp=dd8c5c86fee436bc02a4cbb25b3d84089382bc41;hpb=0e16cb26f6380f57f1079ece9bdb654243073bde;p=vchess.git diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index dd8c5c86..0e0f3720 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -2,16 +2,23 @@ div#baseGame(tabindex=-1 @click="() => focusBg()" @keydown="handleKeys" @wheel="handleScroll") input#modalEog.modal(type="checkbox") - div(role="dialog" data-checkbox="modalEog" aria-labelledby="eogMessage") + div#eogDiv(role="dialog" data-checkbox="modalEog" aria-labelledby="eogMessage") .card.smallpad.small-modal.text-center label.modal-close(for="modalEog") h3#eogMessage.section {{ endgameMessage }} + input#modalAdjust.modal(type="checkbox") + div#adjuster(role="dialog" data-checkbox="modalAdjust" aria-labelledby="labelAdjust") + .card.smallpad.small-modal.text-center + label.modal-close(for="modalAdjust") + label#labelAdjust(for="boardSize") {{ st.tr["Board size"] }} + input#boardSize.slider(type="range" min="0" max="100" value="50" + @input="adjustBoard") #gameContainer #boardContainer - Board(:vr="vr" :last-move="lastMove" :analyze="game.mode=='analyze'" + Board(:vr="vr" :last-move="lastMove" :analyze="analyze" :user-color="game.mycolor" :orientation="orientation" - :vname="game.vname" @play-move="play") - #turnIndicator(v-if="game.vname=='Dark' && game.mode!='analyze'") + :vname="game.vname" :incheck="incheck" @play-move="play") + #turnIndicator(v-if="game.vname=='Dark' && game.score=='*'") | {{ turn }} #controls button(@click="gotoBegin") << @@ -20,12 +27,16 @@ div#baseGame(tabindex=-1 @click="() => focusBg()" button(@click="() => play()") > button(@click="gotoEnd") >> #pgnDiv - a#download(href="#") - button(@click="download") {{ st.tr["Download PGN"] }} + #downloadDiv(v-if="game.vname!='Dark' || game.score!='*'") + a#download(href="#") + button(@click="download") {{ st.tr["Download"] }} PGN + button(onClick="doClick('modalAdjust')") ⤢ button(v-if="game.vname!='Dark' && game.mode!='analyze'" @click="analyzePosition") - | {{ st.tr["Analyze"] }} - button(@click="showRules") {{ st.tr["Rules"] }} + | {{ st.tr["Analyse"] }} + // NOTE: rather ugly hack to avoid showing twice "rules" link... + button(v-if="!$route.path.match('/variants/')" @click="showRules") + | {{ st.tr["Rules"] }} #movesList MoveList(v-if="showMoves" :score="game.score" :message="game.scoreMsg" :firstNum="firstMoveNumber" :moves="moves" :cursor="cursor" @@ -39,6 +50,8 @@ import MoveList from "@/components/MoveList.vue"; import { store } from "@/store"; import { getSquareId } from "@/utils/squareId"; import { getDate } from "@/utils/datetime"; +import { processModalClick } from "@/utils/modalClick"; +import { getScoreMessage } from "@/utils/scoring"; export default { name: 'my-base-game', @@ -59,6 +72,7 @@ export default { cursor: -1, //index of the move just played lastMove: null, firstMoveNumber: 0, //for printing + incheck: [], //for Board }; }, watch: { @@ -74,7 +88,7 @@ export default { }, computed: { showMoves: function() { - return this.game.vname != "Dark" || this.game.mode=="analyze"; + return this.game.vname != "Dark" || this.game.score != "*"; }, turn: function() { let color = ""; @@ -83,7 +97,12 @@ export default { color = "White"; else //if (this.moves[L-1].color == "w") color = "Black"; - return color + " turn"; + return this.st.tr[color + " to move"]; + }, + analyze: function() { + return this.game.mode=="analyze" || + // From Board viewpoint, a finished Dark game == analyze (TODO: unclear) + (this.game.vname == "Dark" && this.game.score != "*"); }, }, created: function() { @@ -91,6 +110,8 @@ export default { this.re_setVariables(); }, mounted: function() { + [document.getElementById("eogDiv"),document.getElementById("adjuster")] + .forEach(elt => elt.addEventListener("click", processModalClick)); // Take full width on small screens: let boardSize = parseInt(localStorage.getItem("boardSize")); if (!boardSize) @@ -103,12 +124,41 @@ export default { document.getElementById("boardContainer").style.width = boardSize + "px"; let gameContainer = document.getElementById("gameContainer"); gameContainer.style.width = (boardSize + movesWidth) + "px"; + // TODO: find the right formula here: + //document.getElementById("boardSize").value = Math.floor(boardSize / 10); + // timeout to avoid calling too many time the adjust method + let timeoutLaunched = false; + window.addEventListener("resize", (e) => { + if (!timeoutLaunched) + { + timeoutLaunched = true; + setTimeout( () => { + this.adjustBoard(); + timeoutLaunched = false; + }, 500); + } + }); }, methods: { focusBg: function() { // NOTE: small blue border appears... document.getElementById("baseGame").focus(); }, + adjustBoard: function() { + const boardContainer = document.getElementById("boardContainer"); + if (!boardContainer) + return; //no board on page + const k = document.getElementById("boardSize").value; + const movesWidth = (window.innerWidth >= 768 ? 280 : 0); + const minBoardWidth = 240; //TODO: these 240 and 280 are arbitrary... + // Value of 0 is board min size; 100 is window.width [- movesWidth] + const boardSize = minBoardWidth + + k * (window.innerWidth - (movesWidth+minBoardWidth)) / 100; + localStorage.setItem("boardSize", boardSize); + boardContainer.style.width = boardSize + "px"; + document.getElementById("gameContainer").style.width = + (boardSize + movesWidth) + "px"; + }, handleKeys: function(e) { if ([32,37,38,39,40].includes(e.keyCode)) e.preventDefault(); @@ -132,7 +182,8 @@ export default { } }, handleScroll: function(e) { - if (this.game.mode == "analyze" || this.game.score != "*") + // NOTE: since game.mode=="analyze" => no score, next condition is enough + if (this.game.score != "*") { e.preventDefault(); if (e.deltaY < 0) @@ -171,9 +222,10 @@ export default { const L = this.moves.length; this.cursor = L-1; this.lastMove = (L > 0 ? this.moves[L-1] : null); + this.incheck = []; }, analyzePosition: function() { - const newUrl = "/analyze/" + this.game.vname + + const newUrl = "/analyse/" + this.game.vname + "/?fen=" + this.vr.getFen().replace(/ /g, "_"); if (this.game.type == "live") this.$router.push(newUrl); //open in same tab: against cheating... @@ -213,25 +265,6 @@ export default { } return pgn + "\n"; }, - getScoreMessage: function(score) { - let eogMessage = "Undefined"; - switch (score) - { - case "1-0": - eogMessage = this.st.tr["White win"]; - break; - case "0-1": - eogMessage = this.st.tr["Black win"]; - break; - case "1/2": - eogMessage = this.st.tr["Draw"]; - break; - case "?": - eogMessage = this.st.tr["Unfinished"]; - break; - } - return eogMessage; - }, showEndgameMsg: function(message) { this.endgameMessage = message; let modalBox = document.getElementById("modalEog"); @@ -240,12 +273,18 @@ export default { }, animateMove: function(move, callback) { let startSquare = document.getElementById(getSquareId(move.start)); + // TODO: error "flush nextTick callbacks" when observer reloads page: + // this late check is not a fix! + if (!startSquare) + return; let endSquare = document.getElementById(getSquareId(move.end)); let rectStart = startSquare.getBoundingClientRect(); let rectEnd = endSquare.getBoundingClientRect(); let translation = {x:rectEnd.x-rectStart.x, y:rectEnd.y-rectStart.y}; let movingPiece = document.querySelector("#" + getSquareId(move.start) + " > img.piece"); + if (!movingPiece) //TODO: shouldn't happen + return; // HACK for animation (with positive translate, image slides "under background") // Possible improvement: just alter squares on the piece's way... const squares = document.getElementsByClassName("board"); @@ -272,7 +311,7 @@ export default { // Forbid playing outside analyze mode, except if move is received. // Sufficient condition because Board already knows which turn it is. if (!navigate && this.game.mode!="analyze" && !receive - && this.cursor < this.moves.length-1) + && (this.game.score != "*" || this.cursor < this.moves.length-1)) { return; } @@ -304,19 +343,19 @@ export default { else this.moves = this.moves.slice(0,this.cursor).concat([move]); } - if (!navigate && this.game.mode!="analyze") - this.$emit("newmove", move); //post-processing (e.g. computer play) // Is opponent in check? this.incheck = this.vr.getCheckSquares(this.vr.turn); const score = this.vr.getCurrentScore(); if (score != "*") { - const message = this.getScoreMessage(score); + const message = getScoreMessage(score); if (this.game.mode != "analyze") this.$emit("gameover", score, message); else //just show score on screen (allow undo) this.showEndgameMsg(score + " . " + message); } + if (!navigate && this.game.mode!="analyze") + this.$emit("newmove", move); //post-processing (e.g. computer play) }; if (!!receive && this.game.vname != "Dark") this.animateMove(move, doPlayMove); @@ -375,11 +414,16 @@ export default {