Fix anonymous games which started with same color
[vchess.git] / client / src / views / Game.vue
index cab813e..e0eb1be 100644 (file)
@@ -287,11 +287,6 @@ export default {
     visibilityChange: function() {
       // TODO: Use document.hidden? https://webplatform.news/issues/2019-03-27
       this.focus = (document.visibilityState == "visible");
-      if (!this.focus && !!this.rematchOffer) {
-        this.rematchOffer = "";
-        this.send("rematchoffer", { data: false });
-        // Do not remove rematch offer from (local) storage
-      }
       this.send(this.focus ? "getfocus" : "losefocus");
     },
     onFocus: function() {
@@ -300,10 +295,6 @@ export default {
     },
     onBlur: function() {
       this.focus = false;
-      if (!!this.rematchOffer) {
-        this.rematchOffer = "";
-        this.send("rematchoffer", { data: false });
-      }
       this.send("losefocus");
     },
     isLargeScreen: function() {
@@ -438,10 +429,14 @@ 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.id)
+      if (
+        this.st.user.sid == player.sid ||
+        (!!player.name && 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);
+      }
       // Try to find a match in people:
       return (
         (
@@ -455,7 +450,7 @@ export default {
         )
         ||
         (
-          !!player.id &&
+          player.id > 0 &&
           Object.values(this.people).some(p => {
             return (
               p.id == player.id &&
@@ -679,7 +674,6 @@ export default {
             !this.gotLastate &&
             !!this.game.mycolor &&
             this.game.type == "live" &&
-            this.game.score == "*" &&
             this.game.players.some(p => p.sid == user.sid)
           ) {
             this.send("asklastate", { target: user.sid });
@@ -817,10 +811,25 @@ export default {
                 }
               }
               this.$refs["basegame"].play(movePlus.move, "received");
-              this.game.clocks[moveColIdx] = movePlus.clock;
-              this.processMove(
-                movePlus.move,
-                { receiveMyMove: receiveMyMove }
+              // Freeze time while the move is being play
+              // (TODO: a callback would be cleaner here)
+              clearInterval(this.clockUpdate);
+              this.clockUpdate = null;
+              const freezeDuration = ["all", "highlight"].includes(V.ShowMoves)
+                // 250 = length of animation, 500 = delay between sub-moves
+                ? 250 + 750 *
+                  (Array.isArray(movePlus.move) ? movePlus.move.length - 1 : 0)
+                // Incomplete information: no move animation
+                : 0;
+              setTimeout(
+                () => {
+                  this.game.clocks[moveColIdx] = movePlus.clock;
+                  this.processMove(
+                    movePlus.move,
+                    { receiveMyMove: receiveMyMove }
+                  );
+                },
+                freezeDuration
               );
             }
           }
@@ -863,7 +872,7 @@ export default {
           if (!!this.game.mycolor && this.game.type == "live") {
             GameStorage.update(
               this.gameRef,
-              { rematchOffer: V.GetOppCol(this.game.mycolor) }
+              { rematchOffer: data.data ? V.GetOppCol(this.game.mycolor) : "" }
             );
           }
           break;
@@ -878,6 +887,7 @@ export default {
             this.addAndGotoLiveGame(gameInfo);
           } else if (
             gameType == "corr" &&
+            this.st.user.id > 0 &&
             gameInfo.players.some(p => p.id == this.st.user.id)
           ) {
             this.$router.push("/game/" + gameInfo.id);
@@ -930,8 +940,8 @@ export default {
         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",
+        drawSent: this.drawOffer == "sent" ? true : undefined,
+        rematchSent: this.rematchOffer == "sent" ? true : undefined,
         score: this.game.score != "*" ? this.game.score : undefined,
         scoreMsg: this.game.score != "*" ? this.game.scoreMsg : undefined,
         movesCount: L
@@ -942,23 +952,47 @@ export default {
     processLastate: function() {
       const data = this.lastate;
       this.lastate = undefined; //security...
-      const L = this.game.moves.length;
-      const oppIdx = 1 - ["w", "b"].indexOf(this.game.mycolor);
-      this.game.clocks[oppIdx] = data.clock;
-      if (data.movesCount > L) {
-        // Just got last move from him
-        this.$refs["basegame"].play(data.lastMove, "received");
-        this.processMove(data.lastMove);
-      } else {
-        if (!!this.clockUpdate) clearInterval(this.clockUpdate);
-        this.re_setClocks();
-      }
-      if (data.drawSent) this.drawOffer = "received";
-      if (data.rematchSent) this.rematchOffer = "received";
       if (!!data.score) {
-        this.drawOffer = "";
-        if (this.game.score == "*")
-          this.gameOver(data.score, data.scoreMsg);
+        const oppCol = V.GetOppCol(this.game.mycolor);
+        if (!!data.rematchSent) {
+          if (this.game.rematchOffer != oppCol) {
+            // Opponent sended rematch offer while we were offline:
+            this.rematchOffer = "received";
+            GameStorage.update(
+              this.gameRef,
+              { rematchOffer: oppCol }
+            );
+          }
+        }
+        else {
+          if (this.game.rematchOffer == oppCol) {
+            // Opponent cancelled rematch offer while we were offline:
+            this.rematchOffer = "";
+            GameStorage.update(
+              this.gameRef,
+              { rematchOffer: "" }
+            );
+          }
+        }
+      }
+      else {
+        const L = this.game.moves.length;
+        const oppIdx = 1 - ["w", "b"].indexOf(this.game.mycolor);
+        this.game.clocks[oppIdx] = data.clock;
+        if (data.movesCount > L) {
+          // Just got last move from him
+          this.$refs["basegame"].play(data.lastMove, "received");
+          this.processMove(data.lastMove);
+        } else {
+          if (!!this.clockUpdate) clearInterval(this.clockUpdate);
+          this.re_setClocks();
+        }
+        if (!!data.drawSent) this.drawOffer = "received";
+        if (!!data.score) {
+          this.drawOffer = "";
+          if (this.game.score == "*")
+            this.gameOver(data.score, data.scoreMsg);
+        }
       }
     },
     clickDraw: function() {
@@ -1090,7 +1124,10 @@ export default {
       const gtype = game.type || 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;
+        return (
+          p.sid == this.st.user.sid ||
+          (!!p.name && p.id == this.st.user.id)
+        );
       });
       // Sometimes the name isn't stored yet (TODO: why?)
       if (
@@ -1182,8 +1219,9 @@ export default {
           if (
             (game.rematchOffer == "w" && myIdx == 0) ||
             (game.rematchOffer == "b" && myIdx == 1)
-          )
+          ) {
             this.rematchOffer = "sent";
+          }
           else this.rematchOffer = "received";
         }
       }
@@ -1573,7 +1611,10 @@ export default {
       document.getElementById("modalScore").checked = true;
       this.$set(this.game, "scoreMsg", scoreMsg);
       const myIdx = this.game.players.findIndex(p => {
-        return p.sid == this.st.user.sid || p.id == this.st.user.id;
+        return (
+          p.sid == this.st.user.sid ||
+          (!!p.name && p.id == this.st.user.id)
+        );
       });
       if (myIdx >= 0) {
         // OK, I play in this game