let inputName = document.getElementById("myName");
let formField = document.getElementById("ng-name");
const setActive = (active) => {
- if (active) formField.classList.add("form-field--is-active");
+ if (active)
+ formField.classList.add("form-field--is-active");
else {
formField.classList.remove("form-field--is-active");
inputName.value == ''
// Turn a "tab" on, and "close" all others
function toggleVisible(element) {
for (elt of document.querySelectorAll("main > div")) {
- if (elt.id != element) elt.style.display = "none";
- else elt.style.display = "block";
+ if (elt.id != element)
+ elt.style.display = "none";
+ else
+ elt.style.display = "block";
}
if (element == "boardContainer") {
// Avoid smartphone scrolling effects (TODO?)
document.querySelector("html").style.overflow = "visible";
document.body.style.overflow = "visible";
// Workaround "superposed texts" effect:
- if (element == "newGame") setActive(false);
+ if (element == "newGame")
+ setActive(false);
}
}
}
}
function cancelSeek() {
- if (send("cancelseek", {vname: seek_vname})) toggleVisible("newGame");
+ if (send("cancelseek", {vname: seek_vname}))
+ toggleVisible("newGame");
}
function sendRematch(random) {
toggleVisible("pendingRematch");
}
function cancelRematch() {
- if (send("norematch", {gid: gid})) toggleVisible("newGame");
+ if (send("norematch", {gid: gid}))
+ toggleVisible("newGame");
}
// Play with a friend (or not ^^)
function showNewGameForm() {
const vname = $.getElementById("selectVariant").value;
- if (vname == "_random") alert("Select a variant first");
+ if (vname == "_random")
+ alert("Select a variant first");
else {
$.getElementById("gameLink").innerHTML = "";
$.getElementById("selectColor").selectedIndex = 0;
toggleVisible("newGameForm");
import(`/variants/${vname}/class.js`).then(module => {
window.V = module.default;
- for (const [k, v] of Object.entries(V.Aliases)) window[k] = v;
+ for (const [k, v] of Object.entries(V.Aliases))
+ window[k] = v;
prepareOptions();
});
}
let options;
function prepareOptions() {
options = {};
- let optHtml = V.Options.select.map(select => { return `
+ let optHtml = "";
+ if (V.Options.select) {
+ optHtml += V.Options.select.map(select => { return `
<div class="option-select">
<label for="var_${select.variable}">${select.label}</label>
<div class="select">
- <select id="var_${select.variable}" data-numeric="1">` +
+ <select id="var_${select.variable}">` +
select.options.map(option => { return `
<option
value="${option.value}"
<span class="focus"></span>
</div>
</div>`;
- }).join("");
- optHtml += V.Options.check.map(check => {
- return `
- <div class="option-check">
- <label class="checkbox">
- <input id="var_${check.variable}"
- type="checkbox"${check.defaut ? " checked" : ""}/>
+ }).join("");
+ }
+ if (V.Options.input) {
+ optHtml += V.Options.input.map(input => { return `
+ <div class="option-input">
+ <label class="input">
+ <input id="var_${input.variable}"
+ type="${input.type}"
+ ${input.type == "checkbox" && input.defaut
+ ? "checked"
+ : 'value="' + input.defaut + '"'}
+ />
<span class="spacer"></span>
- <span>${check.label}</span>
+ <span>${input.label}</span>
</label>
</div>`;
- }).join("");
- if (V.Options.styles.length >= 1) {
+ }).join("");
+ }
+ if (V.Options.styles) {
optHtml += '<div class="words">';
let i = 0;
const stylesLength = V.Options.styles.length;
while (i < stylesLength) {
optHtml += '<div class="row">';
for (let j=i; j<i+4; j++) {
- if (j == stylesLength) break;
+ if (j == stylesLength)
+ break;
const style = V.Options.styles[j];
optHtml += `<span onClick="toggleStyle(event, this)">${style}</span>`;
}
const vname = $.getElementById("selectVariant").value;
const color = $.getElementById("selectColor").value;
for (const select of $.querySelectorAll("#gameOptions select")) {
- let value = select.value;
- if (select.attributes["data-numeric"]) value = parseInt(value, 10);
- if (value) options[ select.id.split("_")[1] ] = value;
+ let value = parseInt(select.value, 10);
+ if (isNaN(value)) //not an integer
+ value = select.value;
+ options[ select.id.split("_")[1] ] = value;
}
- for (const check of $.querySelectorAll("#gameOptions input")) {
- if (check.checked) options[ check.id.split("_")[1] ] = check.checked;
+ for (const input of $.querySelectorAll("#gameOptions input")) {
+ const variable = input.id.split("_")[1];
+ if (input.type == "number")
+ options[variable] = parseInt(input.value, 10); //TODO: real numbers?
+ else if (input.type == "checkbox")
+ options[variable] = input.checked;
}
send("creategame", {
vname: vname,
while (i < options.length) {
htmlContent += '<div class="row">';
for (let j=i; j<i+4; j++) {
- if (j == options.length) break;
+ if (j == options.length)
+ break;
const opt = options[j];
- if (!opt[1]) continue;
+ if (!opt[1]) //includes 0 and false (lighter display)
+ continue;
htmlContent +=
'<span class="option">' +
(opt[1] === true ? opt[0] : `${opt[0]}:${opt[1]}`) + " " +
const trySend = () => {
if (socket.readyState == 1) {
socket.send(JSON.stringify(Object.assign({code: code}, data)));
- if (opts.success) opts.success();
+ if (opts.success)
+ opts.success();
return true;
}
return false;
let sendAttempt = 1;
const retryLoop = setInterval(
() => {
- if (trySend() || ++sendAttempt >= 3) clearInterval(retryLoop);
- if (sendAttempt >= 3 && opts.error) opts.error();
+ if (trySend() || ++sendAttempt >= 3)
+ clearInterval(retryLoop);
+ if (sendAttempt >= 3 && opts.error)
+ opts.error();
},
1000
);
}
- else if (opt.error) opts.error();
+ else if (opts.error)
+ opts.error();
}
return firstTry;
}
switch (obj.code) {
// Start new game:
case "gamestart": {
- if (document.hidden) notifyMe("game");
+ if (document.hidden)
+ notifyMe("game");
gid = obj.gid;
initializeGame(obj);
break;
// Receive opponent's move:
case "newmove":
// Basic check: was it really opponent's turn?
- if (vr.turn == playerColor) break;
- if (document.hidden) notifyMe("move");
+ if (vr.turn == playerColor)
+ break;
+ if (document.hidden)
+ notifyMe("move");
vr.playReceivedMove(obj.moves, () => {
if (vr.getCurrentScore(obj.moves[obj.moves.length-1]) != "*") {
localStorage.removeItem("gid");
setTimeout( () => toggleVisible("gameStopped"), 2000 );
}
- else toggleTurnIndicator(true);
+ else
+ toggleTurnIndicator(true);
});
break;
// Opponent stopped game (draw, abort, resign...)
function toggleTurnIndicator(myTurn) {
let indicator =
$.getElementById("boardContainer").querySelector(".chessboard");
- if (myTurn) indicator.style.outline = "thick solid green";
- else indicator.style.outline = "thick solid lightgrey";
+ if (myTurn)
+ indicator.style.outline = "thick solid green";
+ else
+ indicator.style.outline = "thick solid lightgrey";
}
function notifyMe(code) {
new Notification("New " + code, { vibrate: [200, 100, 200] });
new Audio("/assets/new_" + code + ".mp3").play();
}
- if (Notification.permission === "granted") doNotify();
+ if (Notification.permission === "granted")
+ doNotify();
else if (Notification.permission !== "denied") {
Notification.requestPermission().then(permission => {
- if (permission === "granted") doNotify();
+ if (permission === "granted")
+ doNotify();
});
}
}
let curMoves = [],
lastFen;
-const afterPlay = (move) => {
+const afterPlay = (move_s) => {
const callbackAfterSend = () => {
curMoves = [];
- const result = vr.getCurrentScore(move);
+ const result = vr.getCurrentScore(move_s);
if (result != "*") {
setTimeout(() => {
toggleVisible("gameStopped");
}
};
// Pack into one moves array, then send
- curMoves.push(move);
+ if (Array.isArray(move_s))
+ // Array of simple moves (e.g. Chakart)
+ Array.prototype.push.apply(curMoves, move_s);
+ else
+ // Usual case
+ curMoves.push(move_s);
if (vr.turn != playerColor) {
toggleTurnIndicator(false);
send("newmove",
const options = obj.options || {};
import(`/variants/${obj.vname}/class.js`).then(module => {
window.V = module.default;
- for (const [k, v] of Object.entries(V.Aliases)) window[k] = v;
+ for (const [k, v] of Object.entries(V.Aliases))
+ window[k] = v;
// Load CSS. Avoid loading twice the same stylesheet:
const allIds = [].slice.call($.styleSheets).map(s => s.id);
const newId = obj.vname + "_css";
</g>
</svg>
</div>
- <div class="resizeable chessboard"></div>`;
+ <div class="chessboard"></div>`;
vr = new V({
seed: obj.seed, //may be null if FEN already exists (running game)
fen: obj.fen,
break;
}
}
- fillGameInfos(obj, playerColor == "w" ? 1 : 0);
- if (obj.randvar) toggleVisible("gameInfos");
- else toggleVisible("boardContainer");
+ const playerIndex = (playerColor == "w" ? 0 : 1);
+ fillGameInfos(obj, 1 - playerIndex);
+ if (obj.players[playerIndex].randvar)
+ toggleVisible("gameInfos");
+ else
+ toggleVisible("boardContainer");
toggleTurnIndicator(vr.turn == playerColor);
});
}
function toggleGameInfos() {
if ($.getElementById("gameInfos").style.display == "none")
toggleVisible("gameInfos");
- else toggleVisible("boardContainer");
+ else
+ toggleVisible("boardContainer");
}
$.body.addEventListener("keydown", (e) => {
- if (!localStorage.getItem("gid")) return;
- if (e.keyCode == 27) confirmStopGame();
+ if (!localStorage.getItem("gid"))
+ return;
+ if (e.keyCode == 27)
+ confirmStopGame();
else if (e.keyCode == 32) {
e.preventDefault();
toggleGameInfos();