From 1112f1fdd39a4599cebc4b0b03bee1d28f1236ee Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Sun, 22 Mar 2020 13:59:22 +0100
Subject: [PATCH] Attempt to get rid of the weird trans-pages errors
 (especially in Game)

---
 client/src/views/Game.vue    | 27 +++++++++++++++------------
 client/src/views/Hall.vue    | 14 +++++++++++---
 client/src/views/MyGames.vue | 12 +++++++++++-
 server/models/Game.js        |  2 +-
 4 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue
index ddbd3309..f7e55494 100644
--- a/client/src/views/Game.vue
+++ b/client/src/views/Game.vue
@@ -192,7 +192,10 @@ export default {
   },
   watch: {
     $route: function(to, from) {
-      if (from.params["id"] != to.params["id"]) {
+      if (to.path.length < 6 || to.path.substr(6) != "/game/")
+        // Page change
+        this.cleanBeforeDestroy();
+      else if (from.params["id"] != to.params["id"]) {
         // Change everything:
         this.cleanBeforeDestroy();
         let boardDiv = document.querySelector(".game");
@@ -210,7 +213,6 @@ export default {
     this.atCreation();
   },
   mounted: function() {
-    document.addEventListener('visibilitychange', this.visibilityChange);
     ["chatWrap", "infoDiv"].forEach(eltName => {
       document.getElementById(eltName)
         .addEventListener("click", processModalClick);
@@ -223,10 +225,19 @@ export default {
     }
   },
   beforeDestroy: function() {
-    document.removeEventListener('visibilitychange', this.visibilityChange);
     this.cleanBeforeDestroy();
   },
   methods: {
+    cleanBeforeDestroy: function() {
+      document.removeEventListener('visibilitychange', this.visibilityChange);
+      if (!!this.askLastate)
+        clearInterval(this.askLastate);
+      if (!!this.retrySendmove)
+        clearInterval(this.retrySendmove);
+      if (!!this.clockUpdate)
+        clearInterval(this.clockUpdate);
+      this.send("disconnect");
+    },
     visibilityChange: function() {
       // TODO: Use document.hidden? https://webplatform.news/issues/2019-03-27
       this.send(
@@ -236,6 +247,7 @@ export default {
       );
     },
     atCreation: function() {
+      document.addEventListener('visibilitychange', this.visibilityChange);
       // 0] (Re)Set variables
       this.gameRef = this.$route.params["id"];
       // next = next corr games IDs to navigate faster (if applicable)
@@ -310,15 +322,6 @@ export default {
           socketInit(() => { this.send("askfullgame"); });
       });
     },
-    cleanBeforeDestroy: function() {
-      if (!!this.askLastate)
-        clearInterval(this.askLastate);
-      if (!!this.retrySendmove)
-        clearInterval(this.retrySendmove);
-      if (!!this.clockUpdate)
-        clearInterval(this.clockUpdate);
-      this.send("disconnect");
-    },
     roomInit: function() {
       if (!this.roomInitialized) {
         // Notify the room only now that I connected, because
diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue
index 28635469..f401c6ef 100644
--- a/client/src/views/Hall.vue
+++ b/client/src/views/Hall.vue
@@ -267,9 +267,14 @@ export default {
       });
       if (!this.newchallenge.V && this.newchallenge.vid > 0)
         this.loadNewchallVariant();
+    },
+    $route: function(to, from) {
+      if (to.path != "/") this.cleanBeforeDestroy();
     }
   },
   created: function() {
+    document.addEventListener('visibilitychange', this.visibilityChange);
+    window.addEventListener("beforeunload", this.cleanBeforeDestroy);
     if (this.st.variants.length > 0 && this.newchallenge.vid > 0)
       this.loadNewchallVariant();
     const my = this.st.user;
@@ -304,7 +309,6 @@ export default {
     this.conn.addEventListener("close", this.socketCloseListener);
   },
   mounted: function() {
-    document.addEventListener('visibilitychange', this.visibilityChange);
     ["peopleWrap", "infoDiv", "newgameDiv"].forEach(eltName => {
       document.getElementById(eltName)
         .addEventListener("click", processModalClick);
@@ -388,10 +392,14 @@ export default {
     );
   },
   beforeDestroy: function() {
-    document.removeEventListener('visibilitychange', this.visibilityChange);
-    this.send("disconnect");
+    this.cleanBeforeDestroy();
   },
   methods: {
+    cleanBeforeDestroy: function() {
+      document.removeEventListener('visibilitychange', this.visibilityChange);
+      window.removeEventListener("beforeunload", this.cleanBeforeDestroy);
+      this.send("disconnect");
+    },
     getRandomnessClass: function(pc) {
       return {
         ["random-" + pc.randomness]: true
diff --git a/client/src/views/MyGames.vue b/client/src/views/MyGames.vue
index 60783941..3c2f460b 100644
--- a/client/src/views/MyGames.vue
+++ b/client/src/views/MyGames.vue
@@ -58,7 +58,13 @@ export default {
       connexionString: ""
     };
   },
+  watch: {
+    $route: function(to, from) {
+      if (to.path != "/mygames") this.cleanBeforeDestroy();
+    }
+  },
   created: function() {
+    window.addEventListener("beforeunload", this.cleanBeforeDestroy);
     // Initialize connection
     this.connexionString =
       params.socketUrl +
@@ -132,9 +138,13 @@ export default {
     });
   },
   beforeDestroy: function() {
-    this.conn.send(JSON.stringify({code: "disconnect"}));
+    this.cleanBeforeDestroy();
   },
   methods: {
+    cleanBeforeDestroy: function() {
+      window.removeEventListener("beforeunload", this.cleanBeforeDestroy);
+      this.conn.send(JSON.stringify({code: "disconnect"}));
+    },
     setDisplay: function(type, e) {
       this.display = type;
       localStorage.setItem("type-myGames", type);
diff --git a/server/models/Game.js b/server/models/Game.js
index 85119722..aec80a01 100644
--- a/server/models/Game.js
+++ b/server/models/Game.js
@@ -380,7 +380,7 @@ const GameModel =
                 "FROM Games " +
                 "WHERE id = " + id;
               db.get(query, (err2, ret2) => {
-                const daysTc = parseInt(ret2.cadence.match(/\(^[0-9]+\)/)[0]);
+                const daysTc = parseInt(ret2.cadence.match(/^[0-9]+/)[0]);
                 if (Date.now() - ret.lastPlayed > daysTc * 24 * 3600 * 1000)
                   finishAndSendQuery();
                 else cb({ errmsg: "Time not over" });
-- 
2.44.0