Refactor Games structure on server: no longer use an extra 'Players' table
[vchess.git] / client / src / views / Game.vue
index e909f70..0182352 100644 (file)
@@ -7,7 +7,11 @@ 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()"
@@ -89,7 +93,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,7 +165,7 @@ export default {
       virtualClocks: [],
       vr: null, //"variant rules" object initialized from FEN
       drawOffer: "",
-      infoMessage: "",
+      rematchId: "",
       rematchOffer: "",
       lastateAsked: false,
       people: {}, //players + observers
@@ -216,12 +220,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");
       });
     }
@@ -345,7 +350,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);
@@ -358,9 +363,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)
         )
       );
     },
@@ -408,7 +413,7 @@ export default {
         {
           data: data,
           targets: this.game.players.map(p => {
-            return { sid: p.sid, uid: p.uid };
+            return { sid: p.sid, id: p.id };
           })
         }
       );
@@ -686,7 +691,7 @@ export default {
             this.addAndGotoLiveGame(gameInfo);
           } else if (
             gameType == "corr" &&
-            gameInfo.players.some(p => p.uid == this.st.user.id)
+            gameInfo.players.some(p => p.id == this.st.user.id)
           ) {
             this.$router.push("/game/" + gameInfo.id);
           } else {
@@ -700,14 +705,7 @@ export default {
               });
               urlRid += onlineSid[Math.floor(Math.random() * onlineSid.length)];
             }
-            this.infoMessage =
-              this.st.tr["Rematch in progress:"] +
-              " <a href='#/game/" +
-              gameInfo.id + urlRid +
-              "'>" +
-              "#/game/" +
-              gameInfo.id + urlRid +
-              "</a>";
+            this.rematchId = gameInfo.id + urlRid;
             document.getElementById("modalInfo").checked = true;
           }
           break;
@@ -757,7 +755,7 @@ export default {
           drawSent: this.drawOffer == "sent",
           rematchSent: this.rematchOffer == "sent",
           score: this.game.score,
-          score: this.game.scoreMsg,
+          scoreMsg: this.game.scoreMsg,
           movesCount: L,
           initime: this.game.initime[1 - myIdx] //relevant only if I played
         };
@@ -832,7 +830,7 @@ export default {
         if (!err) {
           if (this.st.settings.sound)
             new Audio("/sounds/newgame.flac").play().catch(() => {});
-          callback();
+          if (!!callback) callback();
           this.$router.push("/game/" + gameInfo.id);
         }
       });
@@ -849,8 +847,11 @@ export default {
           cadence: this.game.cadence
         };
         const notifyNewGame = () => {
-          let oppsid = this.getOppsid(); //may be null
+          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);
         };
@@ -918,33 +919,21 @@ export default {
         const gtype = this.getGameType(game);
         const tc = extractTime(game.cadence);
         const myIdx = 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;
         });
         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;
-              }
-            }
+            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.
           }
           // Sort chat messages from newest to oldest
           game.chats.sort((c1, c2) => {
@@ -971,17 +960,15 @@ export default {
           game.moves = game.moves.map(m => m.squares);
         }
         if (gtype == "live" && game.clocks[0] < 0) {
-          // Game is unstarted
+          // Game is unstarted. clocks and initime are ignored until move 2
           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
-              });
-            }
+          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
+            });
           }
         }
         // TODO: merge next 2 "if" conditions
@@ -1036,15 +1023,12 @@ export default {
             // 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
+            oppid: myIdx < 0 ? undefined : game.players[1 - myIdx].id
           },
           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();
-        else {
+        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
@@ -1374,7 +1358,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