X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fviews%2FMyGames.vue;h=ad330aec802c2454a4d4377dac8ad5961b4c0015;hb=16d06164d56332bd00fb22acc5b2b2997b942d73;hp=ea9b49d39cbe7b969de9e010a2d71d70be1b6599;hpb=fef153df51fe60a5af4c5b2a05e0b1177187bf62;p=vchess.git diff --git a/client/src/views/MyGames.vue b/client/src/views/MyGames.vue index ea9b49d3..ad330aec 100644 --- a/client/src/views/MyGames.vue +++ b/client/src/views/MyGames.vue @@ -6,7 +6,7 @@ main button.tabbtn#liveGames(@click="setDisplay('live',$event)") | {{ st.tr["Live games"] }} button.tabbtn#corrGames(@click="setDisplay('corr',$event)") - | {{ st.tr["Correspondance games"] }} + | {{ st.tr["Correspondence games"] }} button.tabbtn#importGames(@click="setDisplay('import',$event)") | {{ st.tr["Imported games"] }} GameList( @@ -31,6 +31,7 @@ main v-show="display=='import'" ref="importgames" :games="importGames" + :show-both="true" @show-game="showGame" ) button#loadMoreBtn( @@ -77,17 +78,25 @@ export default { }, conn: null, connexionString: "", - socketCloseListener: 0 + reopenTimeout: 0, + reconnectTimeout: 0 }; }, watch: { $route: function(to, from) { if (to.path != "/mygames") this.cleanBeforeDestroy(); + }, + // st.variants changes only once, at loading from [] to [...] + "st.variants": function() { + // Set potential games variant names + display: + this.liveGames.concat(this.corrGames).concat(this.importGames) + .forEach(o => { + if (!o.vname) this.setVname(o); + }); } }, created: function() { window.addEventListener("beforeunload", this.cleanBeforeDestroy); - // Initialize connection this.connexionString = params.socketUrl + "/?sid=" + this.st.user.sid + @@ -95,23 +104,11 @@ export default { "&tmpId=" + getRandString() + "&page=" + encodeURIComponent(this.$route.path); - this.conn = new WebSocket(this.connexionString); - this.conn.onmessage = this.socketMessageListener; - this.socketCloseListener = setInterval( - () => { - if (this.conn.readyState == 3) { - // Connexion is closed: re-open - this.conn.removeEventListener("message", this.socketMessageListener); - this.conn = new WebSocket(this.connexionString); - this.conn.addEventListener("message", this.socketMessageListener); - } - }, - 1000 - ); + this.openConnection(); }, mounted: function() { const adjustAndSetDisplay = () => { - // showType is the last type viwed by the user (default) + // showType is the last type viewed by the user (default) let showType = localStorage.getItem("type-myGames") || "live"; // Live games, my turn: highest priority: if (this.liveGames.some(g => !!g.myTurn)) showType = "live"; @@ -148,6 +145,7 @@ export default { this.corrGames.forEach(g => { g.type = "corr"; g.score = "*"; + g.options = JSON.parse(g.options); }); this.decorate(this.corrGames); // Now ask completed games (partial list) @@ -172,17 +170,33 @@ export default { this.cleanBeforeDestroy(); }, methods: { + openConnection: function() { + // Initialize connection + this.conn = new WebSocket(this.connexionString); + this.conn.onopen = () => { this.reconnectTimeout = 250; }; + this.conn.onmessage = this.socketMessageListener; + const closeConnection = () => { + this.reopenTimeout = setTimeout( + () => { + this.openConnection(); + this.reconnectTimeout = Math.min(2*this.reconnectTimeout, 30000); + }, + this.reconnectTimeout + ); + }; + this.conn.onerror = closeConnection; + this.conn.onclose = closeConnection; + }, cleanBeforeDestroy: function() { - clearInterval(this.socketCloseListener); window.removeEventListener("beforeunload", this.cleanBeforeDestroy); - this.conn.removeEventListener("message", this.socketMessageListener); + clearTimeout(this.reopenTimeout); this.conn.send(JSON.stringify({code: "disconnect"})); this.conn = null; }, setDisplay: function(type, e) { this.display = type; localStorage.setItem("type-myGames", type); - let elt = e ? e.target : document.getElementById(type + "Games"); + let elt = (!!e ? e.target : document.getElementById(type + "Games")); elt.classList.add("active"); elt.classList.remove("somethingnew"); //in case of for (let t of ["live","corr","import"]) { @@ -190,6 +204,14 @@ export default { document.getElementById(t + "Games").classList.remove("active"); } }, + // TODO: duplicated from Hall.vue: + setVname: function(obj) { + const variant = this.st.variants.find(v => v.id == obj.vid); + if (!!variant) { + obj.vname = variant.name; + obj.vdisp = variant.display; + } + }, addGameImport(game) { game.type = "import"; ImportgameStorage.add(game, (err) => { @@ -229,6 +251,7 @@ export default { if ((rem == 0 && g.myColor == 'w') || (rem == 1 && g.myColor == 'b')) g.myTurn = true; } + this.setVname(g); }); }, socketMessageListener: function(msg) { @@ -243,7 +266,7 @@ export default { case "notifyturn": case "notifyscore": { const info = data.data; - const type = (!!parseInt(info.gid) ? "corr" : "live"); + const type = (!!parseInt(info.gid, 10) ? "corr" : "live"); let game = gamesArrays[type].find(g => g.id == info.gid); // "notifything" --> "thing": const thing = data.code.substr(6); @@ -251,22 +274,21 @@ export default { if (thing == "turn") { game.myTurn = !game.myTurn; if (game.myTurn) this.tryShowNewsIndicator(type); - } else game.myTurn = false; + } + else game.myTurn = false; // TODO: forcing refresh like that is ugly and wrong. // How to do it cleanly? this.$refs[type + "games"].$forceUpdate(); break; } case "notifynewgame": { - const gameInfo = data.data; - // st.variants might be uninitialized, - // if unlucky and newgame right after connect: - const v = this.st.variants.find(v => v.id == gameInfo.vid); - const vname = !!v ? v.name : ""; + let gameInfo = data.data; + this.setVname(gameInfo); + // TODO: remove patch on next line (options || "{}") + gameInfo.options = JSON.parse(gameInfo.options || "{}"); const type = (gameInfo.cadence.indexOf('d') >= 0 ? "corr": "live"); let game = Object.assign( { - vname: vname, type: type, score: "*", created: Date.now() @@ -353,10 +375,14 @@ export default { if (L > 0) { this.cursor["corr"] = res.games[L - 1].created; let moreGames = res.games; - moreGames.forEach(g => g.type = "corr"); + moreGames.forEach(g => { + g.type = "corr"; + g.options = JSON.parse(g.options); + }); this.decorate(moreGames); this.corrGames = this.corrGames.concat(moreGames); - } else this.hasMore["corr"] = false; + } + else this.hasMore["corr"] = false; if (!!cb) cb(); } } @@ -368,10 +394,15 @@ export default { if (L > 0) { // Add "-1" because IDBKeyRange.upperBound includes boundary this.cursor["live"] = localGames[L - 1].created - 1; - localGames.forEach(g => g.type = "live"); + localGames.forEach(g => { + g.type = "live"; + // TODO: remove patch on next line (options || "{}") + g.options = JSON.parse(g.options || "{}"); + }); this.decorate(localGames); this.liveGames = this.liveGames.concat(localGames); - } else this.hasMore["live"] = false; + } + else this.hasMore["live"] = false; if (!!cb) cb(); }); } @@ -381,9 +412,15 @@ export default { if (L > 0) { // Add "-1" because IDBKeyRange.upperBound includes boundary this.cursor["import"] = importGames[L - 1].created - 1; - importGames.forEach(g => g.type = "import"); + importGames.forEach(g => { + g.type = "import"; + // TODO: remove following patch (options || "{}") + g.options = JSON.parse(g.options || "{}"); + this.setVname(g); + }); this.importGames = this.importGames.concat(importGames); - } else this.hasMore["import"] = false; + } + else this.hasMore["import"] = false; if (!!cb) cb(); }); } @@ -392,20 +429,23 @@ export default { }; - + + +