X-Git-Url: https://git.auder.net/?p=vchess.git;a=blobdiff_plain;f=client%2Fsrc%2Fviews%2FGame.vue;h=5785abdd481e50d19d0b109af1063b053898e33a;hp=a7cb6a90f676b8ee54e31f6b386b15e5bdcff5a3;hb=059228c9fd737361dc97de69811daed5abbd6254;hpb=c292ebb2a014646005b01e27253c162f1d639387 diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue index a7cb6a90..5785abdd 100644 --- a/client/src/views/Game.vue +++ b/client/src/views/Game.vue @@ -7,10 +7,14 @@ main ) .card.text-center label.modal-close(for="modalInfo") - p(v-html="infoMessage") + a( + :href="'#/game/' + rematchId" + onClick="document.getElementById('modalInfo').checked=false" + ) + | {{ st.tr["Rematch in progress"] }} input#modalChat.modal( type="checkbox" - @click="resetChatColor()" + @click="toggleChat()" ) div#chatWrap( role="dialog" @@ -33,7 +37,6 @@ main ref="chatcomp" :players="game.players" :pastChats="game.chats" - :newChat="newChat" @mychat="processChat" @chatcleared="clearChat" ) @@ -89,7 +92,7 @@ main ) img(src="/images/icons/resign.svg") button.tooltip( - v-else-if="!!game.mycolor" + v-else @click="clickRematch()" :class="{['rematch-' + rematchOffer]: true}" :aria-label="st.tr['Rematch']" @@ -161,13 +164,13 @@ export default { virtualClocks: [], vr: null, //"variant rules" object initialized from FEN drawOffer: "", + rematchId: "", rematchOffer: "", + lastateAsked: false, people: {}, //players + observers - onMygames: [], //opponents (or me) on "MyGames" page lastate: undefined, //used if opponent send lastate before game is ready repeat: {}, //detect position repetition curDiag: "", //for corr moves confirmation - newChat: "", conn: null, roomInitialized: false, // If newmove has wrong index: ask fullgame again: @@ -205,7 +208,7 @@ export default { this.gameRef.id = to.params["id"]; this.gameRef.rid = to.query["rid"]; this.nextIds = JSON.parse(this.$route.query["next"] || "[]"); - this.loadGame(); + this.fetchGame(); } } }, @@ -215,12 +218,13 @@ export default { }, mounted: function() { document.addEventListener('visibilitychange', this.visibilityChange); - document - .getElementById("chatWrap") - .addEventListener("click", processModalClick); + ["chatWrap", "infoDiv"].forEach(eltName => { + document.getElementById(eltName) + .addEventListener("click", processModalClick); + }); if ("ontouchstart" in window) { // Disable tooltips on smartphones: - document.getElementsByClassName("tooltip").forEach(elt => { + document.querySelectorAll("#aboveBoard .tooltip").forEach(elt => { elt.classList.remove("tooltip"); }); } @@ -267,10 +271,9 @@ export default { this.virtualClocks = [[0,0], [0,0]]; this.vr = null; this.drawOffer = ""; + this.lastateAsked = false; this.rematchOffer = ""; - this.onMygames = []; this.lastate = undefined; - this.newChat = ""; this.roomInitialized = false; this.askGameTime = 0; this.gameIsLoading = false; @@ -287,6 +290,8 @@ export default { params.socketUrl + "/?sid=" + this.st.user.sid + + "&id=" + + this.st.user.id + "&tmpId=" + getRandString() + "&page=" + @@ -303,17 +308,17 @@ export default { else // Socket not ready yet (initial loading) // NOTE: it's important to call callback without arguments, - // otherwise first arg is Websocket object and loadGame fails. + // otherwise first arg is Websocket object and fetchGame fails. this.conn.onopen = () => callback(); }; if (!this.gameRef.rid) // Game stored locally or on server - this.loadGame(null, () => socketInit(this.roomInit)); + this.fetchGame(null, () => socketInit(this.roomInit)); else // Game stored remotely: need socket to retrieve it // NOTE: the callback "roomInit" will be lost, so we don't provide it. // --> It will be given when receiving "fullgame" socket event. - socketInit(this.loadGame); + socketInit(this.fetchGame); }, cleanBeforeDestroy: function() { if (!!this.askLastate) @@ -342,7 +347,7 @@ export default { isConnected: function(index) { const player = this.game.players[index]; // Is it me ? In this case no need to bother with focus - if (this.st.user.sid == player.sid || this.st.user.id == player.uid) + if (this.st.user.sid == player.sid || this.st.user.id == player.id) // Still have to check for name (because of potential multi-accounts // on same browser, although this should be rare...) return (!this.st.user.name || this.st.user.name == player.name); @@ -355,9 +360,9 @@ export default { ) || ( - player.uid && + !!player.id && Object.values(this.people).some(p => - p.id == player.uid && p.focus) + p.id == player.id && p.focus) ) ); }, @@ -372,8 +377,12 @@ export default { if (!!oppsid && !!this.people[oppsid]) return oppsid; return null; }, - resetChatColor: function() { - // TODO: this is called twice, once on opening an once on closing + toggleChat: function() { + if (document.getElementById("modalChat").checked) + // Entering chat + document.getElementById("inputChat").focus(); + // TODO: next line is only required when exiting chat, + // but the event for now isn't well detected. document.getElementById("chatBtn").classList.remove("somethingnew"); }, processChat: function(chat) { @@ -395,17 +404,20 @@ export default { this.$set(this.game, "chats", []); } }, - // Notify turn after a new move (to opponent and me on MyGames page) - notifyTurn: function(sid) { - const player = this.people[sid]; - const colorIdx = this.game.players.findIndex( - p => p.sid == sid || p.uid == player.id); - const color = ["w","b"][colorIdx]; - const movesCount = this.game.moves.length; - const yourTurn = - (color == "w" && movesCount % 2 == 0) || - (color == "b" && movesCount % 2 == 1); - this.send("turnchange", { target: sid, yourTurn: yourTurn }); + getGameType: function(game) { + return game.cadence.indexOf("d") >= 0 ? "corr" : "live"; + }, + // Notify something after a new move (to opponent and me on MyGames page) + notifyMyGames: function(thing, data) { + this.send( + "notify" + thing, + { + data: data, + targets: this.game.players.map(p => { + return { sid: p.sid, id: p.id }; + }) + } + ); }, showNextGame: function() { // Did I play in current game? If not, add it to nextIds list @@ -422,7 +434,7 @@ export default { if (document.location.href != currentUrl) return; //page change if (!this.gameRef.rid) // This is my game: just reload. - this.loadGame(); + this.fetchGame(); else // Just ask fullgame again (once!), this is much simpler. // If this fails, the user could just reload page :/ @@ -456,22 +468,6 @@ export default { case "disconnect": this.$delete(this.people, data.from); break; - case "mconnect": { - // TODO: from MyGames page : send mconnect message with the list of gid (live and corr) - // Either me (another tab) or opponent - const sid = data.from; - if (!this.onMygames.some(s => s == sid)) - { - this.onMygames.push(sid); - this.notifyTurn(sid); //TODO: this may require server ID (so, notify after receiving identity) - } - break; - if (!this.people[sid]) - this.send("askidentity", { target: sid }); - } - case "mdisconnect": - ArrayFun.remove(this.onMygames, sid => sid == data.from); - break; case "getfocus": { let player = this.people[data.from]; if (!!player) { @@ -591,35 +587,13 @@ export default { break; case "fullgame": // Callback "roomInit" to poll clients only after game is loaded - this.loadGame(data.data, this.roomInit); + this.fetchGame(data.data, this.roomInit); break; case "asklastate": // Sending informative last state if I played a move or score != "*" - if ( - (this.game.moves.length > 0 && this.vr.turn != this.game.mycolor) || - this.game.score != "*" || - this.drawOffer == "sent" || - this.rematchOffer == "sent" - ) { - // Send our "last state" informations to opponent - const L = this.game.moves.length; - const myIdx = ["w", "b"].indexOf(this.game.mycolor); - const myLastate = { - lastMove: L > 0 ? this.game.moves[L - 1] : undefined, - clock: this.game.clocks[myIdx], - // Since we played a move (or abort or resign), - // only drawOffer=="sent" is possible - drawSent: this.drawOffer == "sent", - rematchSent: this.rematchOffer == "sent", - score: this.game.score, - score: this.game.scoreMsg, - movesCount: L, - initime: this.game.initime[1 - myIdx] //relevant only if I played - }; - this.send("lastate", { data: myLastate, target: data.from }); - } else { - this.send("lastate", { data: {nothing: true}, target: data.from }); - } + // If the game or moves aren't loaded yet, delay the sending: + if (!this.game || !this.game.moves) this.lastateAsked = true; + else this.sendLastate(data.from); break; case "lastate": { // Got opponent infos about last move @@ -689,8 +663,8 @@ export default { break; } case "resign": - const score = data.side == "b" ? "1-0" : "0-1"; - const side = data.side == "w" ? "White" : "Black"; + const score = (data.data == "b" ? "1-0" : "0-1"); + const side = (data.data == "w" ? "White" : "Black"); this.gameOver(score, side + " surrender"); break; case "abort": @@ -710,9 +684,15 @@ export default { case "newgame": { // A game started, redirect if I'm playing in const gameInfo = data.data; + const gameType = this.getGameType(gameInfo); if ( - gameInfo.players.some(p => - p.sid == this.st.user.sid || p.uid == this.st.user.id) + gameType == "live" && + gameInfo.players.some(p => p.sid == this.st.user.sid) + ) { + this.addAndGotoLiveGame(gameInfo); + } else if ( + gameType == "corr" && + gameInfo.players.some(p => p.id == this.st.user.id) ) { this.$router.push("/game/" + gameInfo.id); } else { @@ -726,20 +706,13 @@ export default { }); urlRid += onlineSid[Math.floor(Math.random() * onlineSid.length)]; } - this.infoMessage = - this.st.tr["Rematch in progress:"] + - " " + - "#/game/" + - gameInfo.id + urlRid + - ""; + this.rematchId = gameInfo.id + urlRid; document.getElementById("modalInfo").checked = true; } break; } case "newchat": - this.newChat = data.data; + this.$refs["chatcomp"].newChat(data.data); if (!document.getElementById("modalChat").checked) document.getElementById("chatBtn").classList.add("somethingnew"); break; @@ -765,6 +738,33 @@ export default { } ); }, + sendLastate: function(target) { + if ( + (this.game.moves.length > 0 && this.vr.turn != this.game.mycolor) || + this.game.score != "*" || + this.drawOffer == "sent" || + this.rematchOffer == "sent" + ) { + // Send our "last state" informations to opponent + const L = this.game.moves.length; + const myIdx = ["w", "b"].indexOf(this.game.mycolor); + const myLastate = { + lastMove: L > 0 ? this.game.moves[L - 1] : undefined, + clock: this.game.clocks[myIdx], + // Since we played a move (or abort or resign), + // only drawOffer=="sent" is possible + drawSent: this.drawOffer == "sent", + rematchSent: this.rematchOffer == "sent", + score: this.game.score, + scoreMsg: this.game.scoreMsg, + movesCount: L, + initime: this.game.initime[1 - myIdx] //relevant only if I played + }; + this.send("lastate", { data: myLastate, target: target }); + } else { + this.send("lastate", { data: {nothing: true}, target: target }); + } + }, // lastate was received, but maybe game wasn't ready yet: processLastate: function() { const data = this.lastate; @@ -810,6 +810,32 @@ export default { } else this.updateCorrGame({ drawOffer: this.game.mycolor }); } }, + addAndGotoLiveGame: function(gameInfo, callback) { + const game = Object.assign( + {}, + gameInfo, + { + // (other) Game infos: constant + fenStart: gameInfo.fen, + vname: this.game.vname, + created: Date.now(), + // Game state (including FEN): will be updated + moves: [], + clocks: [-1, -1], //-1 = unstarted + initime: [0, 0], //initialized later + score: "*" + } + ); + GameStorage.add(game, (err) => { + // No error expected. + if (!err) { + if (this.st.settings.sound) + new Audio("/sounds/newgame.flac").play().catch(() => {}); + if (!!callback) callback(); + this.$router.push("/game/" + gameInfo.id); + } + }); + }, clickRematch: function() { if (!this.game.mycolor) return; //I'm just spectator if (this.rematchOffer == "received") { @@ -821,33 +847,17 @@ export default { vid: this.game.vid, cadence: this.game.cadence }; - let oppsid = this.getOppsid(); //may be null - this.send("rnewgame", { data: gameInfo, oppsid: oppsid }); - if (this.game.type == "live") { - const game = Object.assign( - {}, - gameInfo, - { - // (other) Game infos: constant - fenStart: gameInfo.fen, - vname: this.game.vname, - created: Date.now(), - // Game state (including FEN): will be updated - moves: [], - clocks: [-1, -1], //-1 = unstarted - initime: [0, 0], //initialized later - score: "*" - } - ); - GameStorage.add(game, (err) => { - // No error expected. - if (!err) { - if (this.st.settings.sound) - new Audio("/sounds/newgame.flac").play().catch(() => {}); - this.$router.push("/game/" + gameInfo.id); - } - }); - } + const notifyNewGame = () => { + const oppsid = this.getOppsid(); //may be null + this.send("rnewgame", { data: gameInfo, oppsid: oppsid }); + // To main Hall if corr game: + if (this.game.type == "corr") + this.send("newgame", { data: gameInfo }); + // Also to MyGames page: + this.notifyMyGames("newgame", gameInfo); + }; + if (this.game.type == "live") + this.addAndGotoLiveGame(gameInfo, notifyNewGame); else { // corr game ajax( @@ -858,6 +868,7 @@ export default { data: { gameInfo: gameInfo }, success: (response) => { gameInfo.id = response.gameId; + notifyNewGame(); this.$router.push("/game/" + response.gameId); } } @@ -893,8 +904,8 @@ export default { if (!this.game.mycolor || !confirm(this.st.tr["Resign the game?"])) return; this.send("resign", { data: this.game.mycolor }); - const score = this.game.mycolor == "w" ? "0-1" : "1-0"; - const side = this.game.mycolor == "w" ? "White" : "Black"; + const score = (this.game.mycolor == "w" ? "0-1" : "1-0"); + const side = (this.game.mycolor == "w" ? "White" : "Black"); this.gameOver(score, side + " surrender"); }, // 3 cases for loading a game: @@ -902,169 +913,161 @@ export default { // - from server (one correspondance game I play[ed] or not) // - from remote peer (one live game I don't play, finished or not) loadGame: function(game, callback) { - const afterRetrieval = async game => { - const vModule = await import("@/variants/" + game.vname + ".js"); - window.V = vModule.VariantRules; - this.vr = new V(game.fen); - const gtype = game.cadence.indexOf("d") >= 0 ? "corr" : "live"; - const tc = extractTime(game.cadence); - const myIdx = game.players.findIndex(p => { - return p.sid == this.st.user.sid || p.uid == this.st.user.id; - }); - const mycolor = [undefined, "w", "b"][myIdx + 1]; //undefined for observers - if (!game.chats) game.chats = []; //live games don't have chat history - if (gtype == "corr") { - if (game.players[0].color == "b") { - // Adopt the same convention for live and corr games: [0] = white - [game.players[0], game.players[1]] = [ - game.players[1], - game.players[0] - ]; - } - // NOTE: clocks in seconds, initime in milliseconds - game.moves.sort((m1, m2) => m1.idx - m2.idx); //in case of - game.clocks = [tc.mainTime, tc.mainTime]; - const L = game.moves.length; - if (game.score == "*") { - // Set clocks + initime - game.initime = [0, 0]; - if (L >= 1) { - const gameLastupdate = game.moves[L-1].played; - game.initime[L % 2] = gameLastupdate; - if (L >= 2) { - game.clocks[L % 2] = - tc.mainTime - (Date.now() - gameLastupdate) / 1000; - } - } - } - // Sort chat messages from newest to oldest - game.chats.sort((c1, c2) => { - return c2.added - c1.added; - }); - if (myIdx >= 0 && game.score == "*" && game.chats.length > 0) { - // Did a chat message arrive after my last move? - let dtLastMove = 0; - if (L == 1 && myIdx == 0) - dtLastMove = game.moves[0].played; - else if (L >= 2) { - if (L % 2 == 0) { - // It's now white turn - dtLastMove = game.moves[L-1-(1-myIdx)].played; - } else { - // Black turn: - dtLastMove = game.moves[L-1-myIdx].played; - } - } - if (dtLastMove < game.chats[0].added) - document.getElementById("chatBtn").classList.add("somethingnew"); - } - // Now that we used idx and played, re-format moves as for live games - game.moves = game.moves.map(m => m.squares); + this.vr = new V(game.fen); + const gtype = this.getGameType(game); + const tc = extractTime(game.cadence); + const myIdx = game.players.findIndex(p => { + return p.sid == this.st.user.sid || p.id == this.st.user.id; + }); + const mycolor = [undefined, "w", "b"][myIdx + 1]; //undefined for observers + if (!game.chats) game.chats = []; //live games don't have chat history + if (gtype == "corr") { + // NOTE: clocks in seconds, initime in milliseconds + game.moves.sort((m1, m2) => m1.idx - m2.idx); //in case of + game.clocks = [tc.mainTime, tc.mainTime]; + const L = game.moves.length; + if (game.score == "*") { + // Set clocks + initime + game.initime = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]; + if (L >= 1) game.initime[L % 2] = game.moves[L-1].played; + // NOTE: game.clocks shouldn't be computed right now: + // job will be done in re_setClocks() called soon below. } - if (gtype == "live" && game.clocks[0] < 0) { - // Game is unstarted - game.clocks = [tc.mainTime, tc.mainTime]; - if (game.score == "*") { - game.initime[0] = Date.now(); - if (myIdx >= 0) { - // I play in this live game; corr games don't have clocks+initime - GameStorage.update(game.id, { - clocks: game.clocks, - initime: game.initime - }); + // Sort chat messages from newest to oldest + game.chats.sort((c1, c2) => { + return c2.added - c1.added; + }); + if (myIdx >= 0 && game.score == "*" && game.chats.length > 0) { + // Did a chat message arrive after my last move? + let dtLastMove = 0; + if (L == 1 && myIdx == 0) + dtLastMove = game.moves[0].played; + else if (L >= 2) { + if (L % 2 == 0) { + // It's now white turn + dtLastMove = game.moves[L-1-(1-myIdx)].played; + } else { + // Black turn: + dtLastMove = game.moves[L-1-myIdx].played; } } + if (dtLastMove < game.chats[0].added) + document.getElementById("chatBtn").classList.add("somethingnew"); } - // TODO: merge next 2 "if" conditions - if (!!game.drawOffer) { - if (game.drawOffer == "t") - // Three repetitions - this.drawOffer = "threerep"; - else { - // Draw offered by any of the players: - if (myIdx < 0) this.drawOffer = "received"; - else { - // I play in this game: - if ( - (game.drawOffer == "w" && myIdx == 0) || - (game.drawOffer == "b" && myIdx == 1) - ) - this.drawOffer = "sent"; - else this.drawOffer = "received"; - } - } + // Now that we used idx and played, re-format moves as for live games + game.moves = game.moves.map(m => m.squares); + } + if (gtype == "live" && game.clocks[0] < 0) { + // Game is unstarted. clocks and initime are ignored until move 2 + game.clocks = [tc.mainTime, tc.mainTime]; + game.initime = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]; + if (myIdx >= 0) { + // I play in this live game + GameStorage.update(game.id, { + clocks: game.clocks, + initime: game.initime + }); } - if (!!game.rematchOffer) { - if (myIdx < 0) this.rematchOffer = "received"; + } + // TODO: merge next 2 "if" conditions + if (!!game.drawOffer) { + if (game.drawOffer == "t") + // Three repetitions + this.drawOffer = "threerep"; + else { + // Draw offered by any of the players: + if (myIdx < 0) this.drawOffer = "received"; else { // I play in this game: if ( - (game.rematchOffer == "w" && myIdx == 0) || - (game.rematchOffer == "b" && myIdx == 1) + (game.drawOffer == "w" && myIdx == 0) || + (game.drawOffer == "b" && myIdx == 1) ) - this.rematchOffer = "sent"; - else this.rematchOffer = "received"; + this.drawOffer = "sent"; + else this.drawOffer = "received"; } } - this.repeat = {}; //reset: scan past moves' FEN: - let repIdx = 0; - let vr_tmp = new V(game.fenStart); - let curTurn = "n"; - game.moves.forEach(m => { - playMove(m, vr_tmp); - const fenIdx = vr_tmp.getFen().replace(/ /g, "_"); - this.repeat[fenIdx] = this.repeat[fenIdx] - ? this.repeat[fenIdx] + 1 - : 1; - }); - if (this.repeat[repIdx] >= 3) this.drawOffer = "threerep"; - this.game = Object.assign( - // NOTE: assign mycolor here, since BaseGame could also be VS computer - { - type: gtype, - increment: tc.increment, - mycolor: mycolor, - // opponent sid not strictly required (or available), but easier - // at least oppsid or oppid is available anyway: - oppsid: myIdx < 0 ? undefined : game.players[1 - myIdx].sid, - oppid: myIdx < 0 ? undefined : game.players[1 - myIdx].uid - }, - game, - ); - if (this.gameIsLoading) - // Re-load game because we missed some moves: - // artificially reset BaseGame (required if moves arrived in wrong order) - this.$refs["basegame"].re_setVariables(); + } + if (!!game.rematchOffer) { + if (myIdx < 0) this.rematchOffer = "received"; else { - // Initial loading: - this.gotMoveIdx = game.moves.length - 1; - // If we arrive here after 'nextGame' action, the board might be hidden - let boardDiv = document.querySelector(".game"); - if (!!boardDiv && boardDiv.style.visibility == "hidden") - boardDiv.style.visibility = "visible"; + // I play in this game: + if ( + (game.rematchOffer == "w" && myIdx == 0) || + (game.rematchOffer == "b" && myIdx == 1) + ) + this.rematchOffer = "sent"; + else this.rematchOffer = "received"; } - this.re_setClocks(); - this.$nextTick(() => { - this.game.rendered = true; - // Did lastate arrive before game was rendered? - if (this.lastate) this.processLastate(); + } + this.repeat = {}; //reset: scan past moves' FEN: + let repIdx = 0; + let vr_tmp = new V(game.fenStart); + let curTurn = "n"; + game.moves.forEach(m => { + playMove(m, vr_tmp); + const fenIdx = vr_tmp.getFen().replace(/ /g, "_"); + this.repeat[fenIdx] = this.repeat[fenIdx] + ? this.repeat[fenIdx] + 1 + : 1; + }); + if (this.repeat[repIdx] >= 3) this.drawOffer = "threerep"; + this.game = Object.assign( + // NOTE: assign mycolor here, since BaseGame could also be VS computer + { + type: gtype, + increment: tc.increment, + mycolor: mycolor, + // opponent sid not strictly required (or available), but easier + // at least oppsid or oppid is available anyway: + oppsid: myIdx < 0 ? undefined : game.players[1 - myIdx].sid, + oppid: myIdx < 0 ? undefined : game.players[1 - myIdx].id + }, + game + ); + this.$refs["basegame"].re_setVariables(this.game); + if (!this.gameIsLoading) { + // Initial loading: + this.gotMoveIdx = game.moves.length - 1; + // If we arrive here after 'nextGame' action, the board might be hidden + let boardDiv = document.querySelector(".game"); + if (!!boardDiv && boardDiv.style.visibility == "hidden") + boardDiv.style.visibility = "visible"; + } + this.re_setClocks(); + this.$nextTick(() => { + this.game.rendered = true; + // Did lastate arrive before game was rendered? + if (this.lastate) this.processLastate(); + }); + if (this.lastateAsked) { + this.lastateAsked = false; + this.sendLastate(game.oppsid); + } + if (this.gameIsLoading) { + this.gameIsLoading = false; + if (this.gotMoveIdx >= game.moves.length) + // Some moves arrived meanwhile... + this.askGameAgain(); + } + if (!!callback) callback(); + }, + fetchGame: function(game, callback) { + const afterRetrieval = async (game) => { + await import("@/variants/" + game.vname + ".js") + .then((vModule) => { + window.V = vModule[game.vname + "Rules"]; + this.loadGame(game, callback); }); - if (this.gameIsLoading) { - this.gameIsLoading = false; - if (this.gotMoveIdx >= game.moves.length) - // Some moves arrived meanwhile... - this.askGameAgain(); - } - if (!!callback) callback(); }; if (!!game) { afterRetrieval(game); return; } - if (this.gameRef.rid) { + if (this.gameRef.rid) // Remote live game: forgetting about callback func... (TODO: design) this.send("askfullgame", { target: this.gameRef.rid }); - } else { + else { // Local or corr game on server. // NOTE: afterRetrieval() is never called if game not found const gid = this.gameRef.id; @@ -1076,11 +1079,10 @@ export default { { data: { gid: gid }, success: (res) => { - let g = res.game; - g.moves.forEach(m => { + res.game.moves.forEach(m => { m.squares = JSON.parse(m.squares); }); - afterRetrieval(g); + afterRetrieval(res.game); } } ); @@ -1158,15 +1160,13 @@ export default { const score = this.vr.getCurrentScore(); if (score != "*") this.gameOver(score); } -// TODO: notifyTurn: "changeturn" message this.game.moves.push(move); this.game.fen = this.vr.getFen(); if (this.game.type == "live") { if (!!data.clock) this.game.clocks[colorIdx] = data.clock; else this.game.clocks[colorIdx] += addTime; - } - // In corr games, just reset clock to mainTime: - else { + } else { + // In corr games, just reset clock to mainTime: this.game.clocks[colorIdx] = extractTime(this.game.cadence).mainTime; } // NOTE: opponent's initime is reset after "gotmove" is received @@ -1189,6 +1189,16 @@ export default { // NOTE: 'var' to see that variable outside this block var filtered_move = getFilteredMove(move); } + if (moveCol == this.game.mycolor && !data.receiveMyMove) { + // Notify turn on MyGames page: + this.notifyMyGames( + "turn", + { + gid: this.gameRef.id, + turn: this.vr.turn + } + ); + } // Since corr games are stored at only one location, update should be // done only by one player for each move: if ( @@ -1214,7 +1224,6 @@ export default { fen: this.game.fen, move: { squares: filtered_move, - played: Date.now(), idx: origMovescount }, // Code "n" for "None" to force reset (otherwise it's ignored) @@ -1352,7 +1361,7 @@ export default { this.game.scoreMsg = scoreMsg; this.$set(this.game, "scoreMsg", scoreMsg); const myIdx = this.game.players.findIndex(p => { - return p.sid == this.st.user.sid || p.uid == this.st.user.id; + return p.sid == this.st.user.sid || p.id == this.st.user.id; }); if (myIdx >= 0) { // OK, I play in this game @@ -1367,6 +1376,14 @@ export default { else this.updateCorrGame(scoreObj, callback); // Notify the score to main Hall. TODO: only one player (currently double send) this.send("result", { gid: this.game.id, score: score }); + // Also to MyGames page (TODO: doubled as well...) + this.notifyMyGames( + "score", + { + gid: this.gameRef.id, + score: score + } + ); } else if (!!callback) callback(); }