<script>
import { store } from "@/store";
import { checkChallenge } from "@/data/challengeCheck";
+import { notify } from "@/utils/notifications";
import { ArrayFun } from "@/utils/array";
import { ajax } from "@/utils/ajax";
import params from "@/parameters";
diag: "", //visualizing FEN
memorize: false //put settings in localStorage
},
+ focus: true,
tchallDiag: "",
curChallToAccept: {from: {}},
presetChalls: JSON.parse(localStorage.getItem("presetChalls") || "[]"),
conn: null,
connexionString: "",
+ socketCloseListener: 0,
// Related to (killing of) self multi-connects:
newConnect: {},
killed: {}
},
created: function() {
document.addEventListener('visibilitychange', this.visibilityChange);
+ window.addEventListener('focus', this.onFocus);
+ window.addEventListener('blur', this.onBlur);
window.addEventListener("beforeunload", this.cleanBeforeDestroy);
if (this.st.variants.length > 0 && this.newchallenge.vid > 0)
this.loadNewchallVariant();
this.conn = new WebSocket(this.connexionString);
this.conn.onopen = connectAndPoll;
this.conn.addEventListener("message", this.socketMessageListener);
- this.conn.addEventListener("close", this.socketCloseListener);
+ 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
+ );
},
mounted: function() {
["peopleWrap", "infoDiv", "newgameDiv"].forEach(eltName => {
},
methods: {
cleanBeforeDestroy: function() {
+ clearInterval(this.socketCloseListener);
document.removeEventListener('visibilitychange', this.visibilityChange);
+ window.removeEventListener('focus', this.onFocus);
+ window.removeEventListener('blur', this.onBlur);
window.removeEventListener("beforeunload", this.cleanBeforeDestroy);
this.conn.removeEventListener("message", this.socketMessageListener);
- this.conn.removeEventListener("close", this.socketCloseListener);
this.send("disconnect");
this.conn = null;
},
},
visibilityChange: function() {
// TODO: Use document.hidden? https://webplatform.news/issues/2019-03-27
- this.send(
- document.visibilityState == "visible"
- ? "getfocus"
- : "losefocus"
- );
+ 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");
},
partialResetNewchallenge: function() {
// Reset potential target and custom FEN:
},
removePresetChall: function(e, pchall) {
e.stopPropagation();
- const pchallIdx = this.presetChalls.findIndex(pc => pc.index == pchall.index);
+ const pchallIdx =
+ this.presetChalls.findIndex(pc => pc.index == pchall.index);
this.presetChalls.splice(pchallIdx, 1);
localStorage.setItem("presetChalls", JSON.stringify(this.presetChalls));
},
// This is meant to challenge people, thus the next 2 conditions:
this.st.user.id > 0 &&
sid != this.st.user.sid &&
- Object.values(this.people[sid].tmpIds).some(v => v.focus && v.page == "/")
+ Object.values(this.people[sid].tmpIds)
+ .some(v => v.focus && v.page == "/")
);
},
challenge: function(sid) {
// TODO: shuffling and random filtering on server,
// if the room is really crowded.
Object.keys(data.sockIds).forEach(sid => {
- // TODO: test sid != user.sid was already done on server
if (sid != this.st.user.sid) {
// Pick a target tmpId (+page) at random:
const pt = Object.values(data.sockIds[sid]);
// Do not set name or id: identity unknown yet
this.people[sid] = { tmpIds: data.sockIds[sid] };
else
- Object.assign(this.people[s.sid].tmpIds, data.sockIds[sid]);
+ Object.assign(this.people[sid].tmpIds, data.sockIds[sid]);
if (Object.values(data.sockIds[sid]).some(v => v.page == "/"))
// Peer is in Hall
this.send("askchallenges", { target: sid });
}
case "disconnect":
case "gdisconnect": {
- // If the user reloads the page twice very quickly (experienced with Firefox),
- // the first reload won't have time to connect but will trigger a "close" event anyway.
+ // If the user reloads the page twice very quickly
+ // (experienced with Firefox), the first reload won't have time to
+ // connect but will trigger a "close" event anyway.
// ==> Next check is required.
if (!this.people[data.from[0]]) return;
delete this.people[data.from[0]].tmpIds[data.from[1]];
const gid = data.page.match(/[a-zA-Z0-9]+$/)[0];
// Corr games are always reachable:
if (!gid.match(/^[0-9]+$/)) {
- // Live games are reachable as long as someone is on the game page
+ // Live games are reachable if someone is on the game page
if (Object.values(this.people).every(p =>
Object.values(p.tmpIds).every(v => v.page != data.page))
) {
c.from.sid == this.st.user.sid && c.type == "live"
)
.map(c => {
- // NOTE: in principle, should only send targeted challenge to the target.
- // But we may not know yet the identity of the target (just name),
- // so cannot decide if data.from is the target or not.
+ // NOTE: in principle, should only send targeted challenge to the
+ // target. But we may not know yet the identity of the target
+ // (just name), so can't decide if data.from is the target.
return {
id: c.id,
from: this.st.user.sid,
case "deletechallenge_s": {
// NOTE: the challenge(s) may be already removed
const cref = data.data;
- if (!!cref.cid) ArrayFun.remove(this.challenges, c => c.id == cref.cid);
+ if (!!cref.cid)
+ ArrayFun.remove(this.challenges, c => c.id == cref.cid);
else if (!!cref.sids) {
cref.sids.forEach(s => {
ArrayFun.remove(
break;
}
},
- socketCloseListener: function() {
- if (!this.conn) return;
- this.conn = new WebSocket(this.connexionString);
- this.conn.addEventListener("message", this.socketMessageListener);
- this.conn.addEventListener("close", this.socketCloseListener);
- },
loadMoreCorr: function() {
ajax(
"/observedgames",
name: this.st.user.name
};
chall.added = Date.now();
- // NOTE: vname and type are redundant (can be deduced from cadence + vid)
+ // NOTE: vname and type are redundant (deduced from cadence + vid)
chall.type = ctype;
chall.vname = this.newchallenge.vname;
this.challenges.push(chall);
name: this.st.user.name
};
this.launchGame(c);
- if (c.type == "live")
+ if (c.type == "live") {
// Remove all live challenges of both players
- this.send("deletechallenge_s", { data: { sids: [c.from.sid, c.seat.sid] } });
+ this.send(
+ "deletechallenge_s",
+ { data: { sids: [c.from.sid, c.seat.sid] } }
+ );
+ }
else
// Corr challenge: just remove the challenge
this.send("deletechallenge_s", { data: { cid: c.id } });
// Game state (including FEN): will be updated
moves: [],
clocks: [-1, -1], //-1 = unstarted
+ chats: [],
score: "*"
}
);
setTimeout(
() => {
+ const myIdx = (game.players[0].sid == this.st.user.sid ? 0 : 1);
GameStorage.add(game, (err) => {
// If an error occurred, game is not added: a tab already
// added the game. Maybe a focused one, maybe not.
// ==> Do not play it again.
if (!err && this.st.settings.sound)
new Audio("/sounds/newgame.flac").play().catch(() => {});
+ if (!this.focus) {
+ notify(
+ "New live game",
+ { body: "vs " + game.players[1-myIdx].name || "@nonymous" }
+ );
+ }
this.$router.push("/game/" + gameInfo.id);
});
},
- document.hidden ? 500 + 1000 * Math.random() : 0
+ this.focus ? 500 + 1000 * Math.random() : 0
);
}
}