Improve games/challenges display and fix MyGames page reactivity (using () for now...)
[vchess.git] / client / src / views / Hall.vue
index 32d5963..f9519fe 100644 (file)
@@ -227,7 +227,7 @@ export default {
         vid: parseInt(localStorage.getItem("vid")) || 0,
         to: "", //name of challenged player (if any)
         cadence: localStorage.getItem("cadence") || "",
-        randomness: parseInt(localStorage.getItem("randomness")) || 2,
+        randomness: parseInt(localStorage.getItem("challRandomness")) || 2,
         // VariantRules object, stored to not interfere with
         // diagrams of targetted challenges:
         V: null,
@@ -280,6 +280,45 @@ export default {
         pages: [{ path: "/", focus: true }]
       }
     );
+    const connectAndPoll = () => {
+      this.send("connect");
+      this.send("pollclientsandgamers");
+    };
+    // Initialize connection
+    this.connexionString =
+      params.socketUrl +
+      "/?sid=" +
+      this.st.user.sid +
+      "&id=" +
+      this.st.user.id +
+      "&tmpId=" +
+      getRandString() +
+      "&page=" +
+      // Hall: path is "/" (could be hard-coded as well)
+      encodeURIComponent(this.$route.path);
+    this.conn = new WebSocket(this.connexionString);
+    this.conn.onopen = connectAndPoll;
+    this.conn.onmessage = this.socketMessageListener;
+    this.conn.onclose = this.socketCloseListener;
+  },
+  mounted: function() {
+    document.addEventListener('visibilitychange', this.visibilityChange);
+    ["peopleWrap", "infoDiv", "newgameDiv"].forEach(eltName => {
+      document.getElementById(eltName)
+        .addEventListener("click", processModalClick);
+    });
+    document.querySelectorAll("#predefinedCadences > button").forEach(b => {
+      b.addEventListener("click", () => {
+        this.newchallenge.cadence = b.innerHTML;
+      });
+    });
+    const dispCorr = this.$route.query["disp"];
+    const showCtype =
+      dispCorr || localStorage.getItem("type-challenges") || "live";
+    const showGtype =
+      dispCorr || localStorage.getItem("type-games") || "live";
+    this.setDisplay('c', showCtype);
+    this.setDisplay('g', showGtype);
     // Ask server for current corr games (all but mines)
     ajax(
       "/games",
@@ -287,6 +326,15 @@ export default {
       {
         data: { uid: this.st.user.id, excluded: true },
         success: (response) => {
+          if (
+            response.games.length > 0 &&
+            this.games.length == 0 &&
+            this.gdisplay == "live"
+          ) {
+            document
+              .getElementById("btnGcorr")
+              .classList.add("somethingnew");
+          }
           this.games = this.games.concat(
             response.games.map(g => {
               const type = this.classifyObject(g);
@@ -311,6 +359,15 @@ export default {
       {
         data: { uid: this.st.user.id },
         success: (response) => {
+          if (
+            response.challenges.length > 0 &&
+            this.challenges.length == 0 &&
+            this.cdisplay == "live"
+          ) {
+            document
+              .getElementById("btnCcorr")
+              .classList.add("somethingnew");
+          }
           // Gather all senders names, and then retrieve full identity:
           // (TODO [perf]: some might be online...)
           let names = {};
@@ -357,45 +414,6 @@ export default {
         }
       }
     );
-    const connectAndPoll = () => {
-      this.send("connect");
-      this.send("pollclientsandgamers");
-    };
-    // Initialize connection
-    this.connexionString =
-      params.socketUrl +
-      "/?sid=" +
-      this.st.user.sid +
-      "&id=" +
-      this.st.user.id +
-      "&tmpId=" +
-      getRandString() +
-      "&page=" +
-      // Hall: path is "/" (could be hard-coded as well)
-      encodeURIComponent(this.$route.path);
-    this.conn = new WebSocket(this.connexionString);
-    this.conn.onopen = connectAndPoll;
-    this.conn.onmessage = this.socketMessageListener;
-    this.conn.onclose = this.socketCloseListener;
-  },
-  mounted: function() {
-    document.addEventListener('visibilitychange', this.visibilityChange);
-    ["peopleWrap", "infoDiv", "newgameDiv"].forEach(eltName => {
-      document.getElementById(eltName)
-        .addEventListener("click", processModalClick);
-    });
-    document.querySelectorAll("#predefinedCadences > button").forEach(b => {
-      b.addEventListener("click", () => {
-        this.newchallenge.cadence = b.innerHTML;
-      });
-    });
-    const dispCorr = this.$route.query["disp"];
-    const showCtype =
-      dispCorr || localStorage.getItem("type-challenges") || "live";
-    const showGtype =
-      dispCorr || localStorage.getItem("type-games") || "live";
-    this.setDisplay("c", showCtype);
-    this.setDisplay("g", showGtype);
   },
   beforeDestroy: function() {
     document.removeEventListener('visibilitychange', this.visibilityChange);
@@ -619,15 +637,14 @@ export default {
           } else {
             // Remove the matching live game if now unreachable
             const gid = data.page.match(/[a-zA-Z0-9]+$/)[0];
-            const gidx = this.games.findIndex(g => g.id == gid);
-            if (gidx >= 0) {
-              const game = this.games[gidx];
-              if (
-                game.type == "live" &&
-                game.rids.length == 1 &&
-                game.rids[0] == data.from
-              ) {
-                this.games.splice(gidx, 1);
+            // Corr games are always reachable:
+            if (!gid.match(/^[0-9]+$/)) {
+              const gidx = this.games.findIndex(g => g.id == gid);
+              // NOTE: gidx should always be >= 0 (TODO?)
+              if (gidx >= 0) {
+                const game = this.games[gidx];
+                ArrayFun.remove(game.rids, rid => rid == data.from);
+                if (game.rids.length == 0) this.games.splice(gidx, 1);
               }
             }
           }
@@ -658,7 +675,7 @@ export default {
           alert(this.st.tr["New connexion detected: tab now offline"]);
           break;
         case "askidentity": {
-          // Request for identification (TODO: anonymous shouldn't need to reply)
+          // Request for identification
           const me = {
             // Decompose to avoid revealing email
             name: this.st.user.name,
@@ -744,12 +761,12 @@ export default {
           }
           break;
         }
-        case "game": //individual request
-        case "newgame": {
+        case "game": {
+          // Individual request
           const game = data.data;
           // Ignore games where I play (will go in MyGames page)
           if (game.players.every(p =>
-            p.sid != this.st.user.sid || p.uid != this.st.user.id))
+            p.sid != this.st.user.sid && p.uid != this.st.user.id))
           {
             let locGame = this.games.find(g => g.id == game.id);
             if (!locGame) {
@@ -889,8 +906,9 @@ export default {
         else if (
           ctype == "live" &&
           Object.values(this.people).every(p => p.name != this.newchallenge.to)
-        )
+        ) {
           error = this.newchallenge.to + " " + this.st.tr["is not online"];
+        }
       }
       if (error) {
         alert(error);
@@ -969,7 +987,7 @@ export default {
         // Remember cadence  + vid for quicker further challenges:
         localStorage.setItem("cadence", chall.cadence);
         localStorage.setItem("vid", chall.vid);
-        localStorage.setItem("randomness", chall.randomness);
+        localStorage.setItem("challRandomness", chall.randomness);
         document.getElementById("modalNewgame").checked = false;
         // Show the challenge if not on current display
         if (
@@ -1102,10 +1120,7 @@ export default {
         if (!!oppsid)
           // Opponent is online
           this.send("startgame", { data: gameInfo, target: oppsid });
-        // Send game info (only if live) to everyone except me and opponent
-        // TODO: this double message send could be avoided.
-        this.send("newgame", { data: gameInfo, oppsid: oppsid });
-        // Also to MyGames page:
+        // Notify MyGames page:
         this.send(
           "notifynewgame",
           {
@@ -1115,6 +1130,8 @@ export default {
             })
           }
         );
+        // NOTE: no need to send the game to the room, since I'll connect
+        // on game just after, the main Hall will be notified.
       };
       if (c.type == "live") {
         notifyNewgame();