+ cleanBeforeDestroy: function() {
+ clearInterval(this.socketCloseListener);
+ document.removeEventListener('visibilitychange', this.visibilityChange);
+ window.removeEventListener('focus', this.onFocus);
+ window.removeEventListener('blur', this.onBlur);
+ if (!!this.askLastate) clearInterval(this.askLastate);
+ if (!!this.retrySendmove) clearInterval(this.retrySendmove);
+ if (!!this.clockUpdate) clearInterval(this.clockUpdate);
+ this.conn.removeEventListener("message", this.socketMessageListener);
+ this.send("disconnect");
+ this.conn = null;
+ },
+ visibilityChange: function() {
+ // TODO: Use document.hidden? https://webplatform.news/issues/2019-03-27
+ this.focus = (document.visibilityState == "visible");
+ this.send(this.focus ? "getfocus" : "losefocus");
+ },
+ onFocus: function() {
+ this.focus = true;
+ this.send("getfocus");
+ },
+ onBlur: function() {
+ this.focus = false;
+ this.send("losefocus");
+ },
+ isLargeScreen: function() {
+ return window.innerWidth >= 768;
+ },
+ btnTooltipClass: function(thing) {
+ let append = {};
+ if (!!thing) append = { [thing + "-" + this[thing + "Offer"]]: true };
+ return (
+ Object.assign(
+ { tooltip: !("ontouchstart" in window) },
+ append
+ )
+ );
+ },
+ gotoRules: function() {
+ this.$router.push("/variants/" + this.game.vname);
+ },
+ participateInChat: function(p) {
+ return Object.keys(p.tmpIds).some(x => p.tmpIds[x].focus) && !!p.name;
+ },
+ someAnonymousPresent: function() {
+ return (
+ Object.values(this.people).some(p =>
+ !p.name && Object.keys(p.tmpIds).some(x => p.tmpIds[x].focus)
+ )
+ );
+ },
+ atCreation: function() {
+ document.addEventListener('visibilitychange', this.visibilityChange);
+ window.addEventListener('focus', this.onFocus);
+ window.addEventListener('blur', this.onBlur);
+ // 0] (Re)Set variables
+ this.gameRef = this.$route.params["id"];
+ // next = next corr games IDs to navigate faster (if applicable)
+ this.nextIds = JSON.parse(this.$route.query["next"] || "[]");
+ // Always add myself to players' list
+ const my = this.st.user;
+ const tmpId = getRandString();
+ this.$set(
+ this.people,
+ my.sid,
+ {
+ id: my.id,
+ name: my.name,
+ tmpIds: {
+ tmpId: { focus: true }
+ }
+ }
+ );
+ this.game = {
+ players: [{ name: "" }, { name: "" }],
+ chats: [],
+ rendered: false
+ };
+ let chatComp = this.$refs["chatcomp"];
+ if (!!chatComp) chatComp.chats = [];
+ this.virtualClocks = [[0,0], [0,0]];
+ this.vr = null;
+ this.rulesContent = "";
+ this.drawOffer = "";
+ this.lastateAsked = false;
+ this.rematchOffer = "";
+ this.lastate = undefined;
+ this.roomInitialized = false;
+ this.askGameTime = 0;
+ this.gameIsLoading = false;
+ this.gotLastate = false;
+ this.gotMoveIdx = -1;
+ this.opponentGotMove = false;
+ this.askLastate = null;
+ this.retrySendmove = null;
+ this.clockUpdate = null;
+ this.newConnect = {};
+ // 1] Initialize connection
+ this.connexionString =
+ params.socketUrl +
+ "/?sid=" + this.st.user.sid +
+ "&id=" + this.st.user.id +
+ "&tmpId=" + tmpId +
+ "&page=" +
+ // Discard potential "/?next=[...]" for page indication:
+ encodeURIComponent(this.$route.path.match(/\/game\/[a-zA-Z0-9]+/)[0]);
+ this.conn = new WebSocket(this.connexionString);
+ this.conn.addEventListener("message", this.socketMessageListener);
+ this.socketCloseListener = setInterval(
+ () => {
+ if (this.conn.readyState == 3) {
+ this.conn.removeEventListener(
+ "message", this.socketMessageListener);
+ this.conn = new WebSocket(this.connexionString);
+ this.conn.addEventListener("message", this.socketMessageListener);
+ }
+ },
+ 1000
+ );
+ // Socket init required before loading remote game:
+ const socketInit = callback => {
+ if (this.conn.readyState == 1)
+ // 1 == OPEN state
+ callback();
+ else
+ // Socket not ready yet (initial loading)
+ // NOTE: first arg is Websocket object, unused here:
+ this.conn.onopen = () => callback();
+ };
+ this.fetchGame((game) => {
+ if (!!game)
+ this.loadVariantThenGame(game, () => socketInit(this.roomInit));
+ else
+ // Live game stored remotely: need socket to retrieve it
+ // NOTE: the callback "roomInit" will be lost, so it's not provided.
+ // --> It will be given when receiving "fullgame" socket event.
+ socketInit(() => { this.send("askfullgame"); });
+ });
+ },