+ }
+ else
+ // gtype == "import"
+ game.clocks = [tc.mainTime, tc.mainTime];
+ // Live games before 26/03/2020 don't have chat history:
+ if (!game.chats) game.chats = []; //TODO: remove line
+ // Sort chat messages from newest to oldest
+ game.chats.sort((c1, c2) => c2.added - c1.added);
+ if (
+ myIdx >= 0 &&
+ game.chats.length > 0 &&
+ (!game.chatRead || game.chatRead < game.chats[0].added)
+ ) {
+ // A chat message arrived since my last reading:
+ 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";
+ }
+ }
+ }
+ if (!!game.rematchOffer) {
+ if (myIdx < 0) this.rematchOffer = "received";
+ else {
+ // I play in this game:
+ if (
+ (game.rematchOffer == "w" && myIdx == 0) ||
+ (game.rematchOffer == "b" && myIdx == 1)
+ )
+ this.rematchOffer = "sent";
+ else this.rematchOffer = "received";
+ }
+ }
+ this.repeat = {}; //reset: scan past moves' FEN:
+ let repIdx = 0;
+ this.vr = new V(game.fenStart);
+ let curTurn = "n";
+ game.moves.forEach(m => {
+ playMove(m, this.vr);
+ const fenIdx = this.vr.getFenForRepeat();
+ this.repeat[fenIdx] = this.repeat[fenIdx]
+ ? this.repeat[fenIdx] + 1
+ : 1;
+ });
+ // Imported games don't have current FEN
+ if (!game.fen) game.fen = this.vr.getFen();
+ 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();
+ },
+ loadVariantThenGame: async function(game, callback) {
+ await import("@/variants/" + game.vname + ".js")
+ .then((vModule) => {
+ window.V = vModule[game.vname + "Rules"];
+ this.loadGame(game, callback);
+ });
+ },
+ // 3 cases for loading a game:
+ // - from indexedDB (running or completed live game I play)
+ // - from server (one correspondance game I play[ed] or not)
+ // - from remote peer (one live game I don't play, finished or not)
+ fetchGame: function(callback) {
+ if (Number.isInteger(this.gameRef) || !isNaN(parseInt(this.gameRef))) {
+ // corr games identifiers are integers
+ ajax(
+ "/games",
+ "GET",