th {{ st.tr["Result"] }}
tbody
tr(
- v-for="g in sortedGames"
+ v-for="g in sortedGames()"
@click="$emit('show-game',g)"
:class="{'my-turn': !!g.myTurn}"
)
}
});
},
- computed: {
+ methods: {
+ player_s: function(g) {
+ if (this.showBoth)
+ return (
+ (g.players[0].name || "@nonymous") +
+ " - " +
+ (g.players[1].name || "@nonymous")
+ );
+ if (
+ this.st.user.sid == g.players[0].sid ||
+ this.st.user.id == g.players[0].uid
+ )
+ return g.players[1].name || "@nonymous";
+ return g.players[0].name || "@nonymous";
+ },
sortedGames: function() {
// Show in order: it's my turn, running games, completed games
let minCreated = Number.MAX_SAFE_INTEGER;
);
});
},
- },
- methods: {
- player_s: function(g) {
- if (this.showBoth)
- return (
- (g.players[0].name || "@nonymous") +
- " - " +
- (g.players[1].name || "@nonymous")
- );
- if (
- this.st.user.sid == g.players[0].sid ||
- this.st.user.id == g.players[0].uid
- )
- return g.players[1].name || "@nonymous";
- return g.players[0].name || "@nonymous";
- },
scoreClass: function(g) {
if (g.score == "*" || !g.myColor) return {};
// Ok it's my finished game: determine if I won, drew or lost.
)
.card.text-center
label.modal-close(for="modalInfo")
- p(v-html="infoMessage")
+ p
+ span {{ st.tr["Rematch in progress:"] }}
+ a(
+ :href="'#/game/' + rematchId"
+ onClick="document.getElementById('modalInfo').checked=false"
+ )
+ | {{ "#/game/" + rematchId }}
input#modalChat.modal(
type="checkbox"
@click="resetChatColor()"
virtualClocks: [],
vr: null, //"variant rules" object initialized from FEN
drawOffer: "",
- infoMessage: "",
+ rematchId: "",
rematchOffer: "",
lastateAsked: false,
people: {}, //players + observers
});
urlRid += onlineSid[Math.floor(Math.random() * onlineSid.length)];
}
- this.infoMessage =
- this.st.tr["Rematch in progress:"] +
- " <a href='#/game/" +
- gameInfo.id + urlRid +
- "'>" +
- "#/game/" +
- gameInfo.id + urlRid +
- "</a>";
+ this.rematchId = gameInfo.id + urlRid;
document.getElementById("modalInfo").checked = true;
}
break;
if (!err) {
if (this.st.settings.sound)
new Audio("/sounds/newgame.flac").play().catch(() => {});
- callback();
+ if (!!callback) callback();
this.$router.push("/game/" + gameInfo.id);
}
});
} 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);
}
}
}
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,
}
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) {
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);
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",
{
})
}
);
+ // 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();
button.tabbtn#corrGames(@click="setDisplay('corr',$event)")
| {{ st.tr["Correspondance games"] }}
GameList(
+ ref="livegames"
v-show="display=='live'"
:games="liveGames"
@show-game="showGame"
@abortgame="abortGame"
)
GameList(
+ ref="corrgames"
v-show="display=='corr'"
:games="corrGames"
@show-game="showGame"
};
},
created: function() {
- GameStorage.getAll(localGames => {
- localGames.forEach(g => g.type = "live");
- this.decorate(localGames);
- this.liveGames = localGames;
- });
- if (this.st.user.id > 0) {
- ajax(
- "/games",
- "GET",
- {
- data: { uid: this.st.user.id },
- success: (res) => {
- let serverGames = res.games.filter(g => {
- const mySide =
- g.players[0].uid == this.st.user.id
- ? "White"
- : "Black";
- return !g["deletedBy" + mySide];
- });
- serverGames.forEach(g => g.type = "corr");
- this.decorate(serverGames);
- this.corrGames = serverGames;
- }
- }
- );
- }
// Initialize connection
this.connexionString =
params.socketUrl +
this.conn.onclose = this.socketCloseListener;
},
mounted: function() {
- const showType = localStorage.getItem("type-myGames") || "live";
- this.setDisplay(showType);
+ const adjustAndSetDisplay = () => {
+ // showType is the last type viwed 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";
+ // Then corr games, my turn:
+ else if (this.corrGames.some(g => !!g.myTurn)) showType = "corr";
+ else {
+ // If a listing is empty, try showing the other (if non-empty)
+ const types = ["corr", "live"];
+ for (let i of [0,1]) {
+ if (
+ this[types[i] + "Games"].length > 0 &&
+ this[types[1-i] + "Games"].length == 0
+ ) {
+ showType = types[i];
+ }
+ }
+ }
+ this.setDisplay(showType);
+ };
+ GameStorage.getAll(localGames => {
+ localGames.forEach(g => g.type = "live");
+ this.decorate(localGames);
+ this.liveGames = localGames;
+ if (this.st.user.id > 0) {
+ ajax(
+ "/games",
+ "GET",
+ {
+ data: { uid: this.st.user.id },
+ success: (res) => {
+ let serverGames = res.games.filter(g => {
+ const mySide =
+ g.players[0].uid == this.st.user.id
+ ? "White"
+ : "Black";
+ return !g["deletedBy" + mySide];
+ });
+ serverGames.forEach(g => g.type = "corr");
+ this.decorate(serverGames);
+ this.corrGames = serverGames;
+ adjustAndSetDisplay();
+ }
+ }
+ );
+ } else adjustAndSetDisplay();
+ });
},
beforeDestroy: function() {
this.conn.send(JSON.stringify({code: "disconnect"}));
// "notifything" --> "thing":
const thing = data.code.substr(6);
game[thing] = info[thing];
- if (thing == "turn") game.myTurn = !game.myTurn;
- this.$forceUpdate();
- this.tryShowNewsIndicator(type);
+ if (thing == "turn") {
+ game.myTurn = !game.myTurn;
+ if (game.myTurn) this.tryShowNewsIndicator(type);
+ }
+ // TODO: forcing refresh like that is ugly and wrong.
+ // How to do it cleanly?
+ this.$refs[type + "games"].$forceUpdate();
break;
}
case "notifynewgame": {
(type == "corr" && game.players[0].uid == this.st.user.id) ||
(type == "live" && game.players[0].sid == this.st.user.sid);
gamesArrays[type].push(game);
- this.$forceUpdate();
- this.tryShowNewsIndicator(type);
+ if (game.myTurn) this.tryShowNewsIndicator(type);
+ // TODO: cleaner refresh
+ this.$refs[type + "games"].$forceUpdate();
break;
}
}
case "drawoffer":
case "rematchoffer":
case "draw":
- if (!!obj.oppsid)
- // "newgame" message from Hall: do not target players
- notifyAllBut(page, "newgame", {data: obj.data}, [sid, obj.oppsid]);
- else notifyRoom(page, obj.code, {data: obj.data});
+ notifyRoom(page, obj.code, {data: obj.data});
break;
case "rnewgame":
- // A rematch game started: players are already informed
+ // A rematch game started:
+ // NOTE: no need to explicitely notify Hall: the game will be sent
notifyAllBut(page, "newgame", {data: obj.data}, [sid]);
- notifyAllBut("/", "newgame", {data: obj.data}, [sid, obj.oppsid]);
notifyRoom("/mygames", "newgame", {data: obj.data});
break;