X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fcomponents%2FBaseGame.vue;h=0d5a3bbce3e4d457349020685c01a0143b78a090;hb=28b32b4fc7c23b1c72bed68e1897576c5be46c3d;hp=4af4e1536884e3105f6359f360dd5b33670581ca;hpb=7ba4a5bc5b64e19a1e7f26aa232d5c50770d07ad;p=vchess.git diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index 4af4e153..0d5a3bbc 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -33,29 +33,19 @@ div#baseGame img.inline(src="/images/icons/play.svg") button(@click="gotoEnd()") img.inline(src="/images/icons/fast-forward.svg") - #belowControls - #downloadDiv(v-if="allowDownloadPGN") - a#download(href="#") - button(@click="download()") {{ st.tr["Download"] }} PGN - button( - v-if="canAnalyze" - @click="analyzePosition()" - ) - | {{ st.tr["Analyse"] }} - // NOTE: variants pages already have a "Rules" link on top - button( - v-if="!$route.path.match('/variants/')" - @click="showRules()" - ) - | {{ st.tr["Rules"] }} #movesList MoveList( :show="showMoves" + :canAnalyze="canAnalyze" + :canDownload="allowDownloadPGN" :score="game.score" :message="game.scoreMsg" :firstNum="firstMoveNumber" :moves="moves" :cursor="cursor" + @download="download" + @showrules="showRules" + @analyze="analyzePosition" @goto-move="gotoMove" ) .clearer @@ -87,18 +77,20 @@ export default { orientation: "w", score: "*", //'*' means 'unfinished' moves: [], - // TODO: later, use subCursor to navigate intra-multimoves? cursor: -1, //index of the move just played lastMove: null, firstMoveNumber: 0, //for printing incheck: [], //for Board - inMultimove: false + inMultimove: false, + inPlay: false, + stackToPlay: [] }; }, watch: { - // game initial FEN changes when a new game starts - "game.fenStart": function() { - this.re_setVariables(); + // game initial FEN changes when a new game starts. + // NOTE: when game ID change on Game page, fenStart may be temporarily undefined + "game.fenStart": function(fenStart) { + if (!!fenStart) this.re_setVariables(); }, }, computed: { @@ -265,15 +257,12 @@ export default { }, showEndgameMsg: function(message) { this.endgameMessage = message; - let modalBox = document.getElementById("modalEog"); - modalBox.checked = true; - setTimeout(() => { - modalBox.checked = false; - }, 2000); + document.getElementById("modalEog").checked = true; }, // Animate an elementary move animateMove: function(move, callback) { let startSquare = document.getElementById(getSquareId(move.start)); + if (!startSquare) return; //shouldn't happen but... let endSquare = document.getElementById(getSquareId(move.end)); let rectStart = startSquare.getBoundingClientRect(); let rectEnd = endSquare.getBoundingClientRect(); @@ -284,6 +273,9 @@ export default { let movingPiece = document.querySelector( "#" + getSquareId(move.start) + " > img.piece" ); + // For some unknown reasons Opera get "movingPiece == null" error + // TOOO: is it calling 'animate()' twice ? One extra time ? + if (!movingPiece) 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"); @@ -312,8 +304,15 @@ export default { } }, // "light": if gotoMove() or gotoEnd() - // data: some custom data (addTime) to be re-emitted - play: function(move, received, light, data) { + play: function(move, received, light, noemit) { + if (!!noemit) { + if (this.inPlay) { + // Received moves in observed games can arrive too fast: + this.stackToPlay.unshift(move); + return; + } + this.inPlay = true; + } const navigate = !move; const playSubmove = (smove) => { if (!navigate) smove.notation = this.vr.getNotation(smove); @@ -369,19 +368,27 @@ export default { this.emitFenIfAnalyze(); } this.inMultimove = false; - const score = this.vr.getCurrentScore(); - if (score != "*") { - const message = getScoreMessage(score); - if (!navigate && this.game.mode != "analyze") - this.$emit("gameover", score, message); - else if (this.game.mode == "analyze") + if (!noemit) { + var score = this.vr.getCurrentScore(); + if (score != "*" && this.game.mode == "analyze") { + const message = getScoreMessage(score); // Just show score on screen (allow undo) this.showEndgameMsg(score + " . " + this.st.tr[message]); + } } if (!navigate && this.game.mode != "analyze") { const L = this.moves.length; - // Post-processing (e.g. computer play) - this.$emit("newmove", this.moves[L-1], data); + if (!noemit) + // Post-processing (e.g. computer play). + // NOTE: always emit the score, even in unfinished, + // to tell Game::processMove() that it's not a received move. + this.$emit("newmove", this.moves[L-1], { score: score }); + else { + this.inPlay = false; + if (this.stackToPlay.length > 0) + // Move(s) arrived in-between + this.play(this.stackToPlay.pop(), received, light, noemit); + } } } }; @@ -509,6 +516,7 @@ export default { display: inline-block #controls + user-select: none margin: 0 auto text-align: center display: flex @@ -516,29 +524,19 @@ export default { display: inline-block width: 20% margin: 0 - img.inline - height: 24px - padding-top: 5px - @media screen and (max-width: 767px) - img.inline - height: 18px + padding-top: 5px + padding-bottom: 5px + +img.inline + height: 24px + padding-top: 5px + @media screen and (max-width: 767px) + height: 18px #turnIndicator text-align: center font-weight: bold -#belowControls - border-top: 1px solid #2f4f4f - text-align: center - margin: 0 auto - & > #downloadDiv - margin: 0 - & > button - margin: 0 - & > button - border-left: 1px solid #2f4f4f - margin: 0 - #boardContainer float: left // TODO: later, maybe, allow movesList of variable width