"flatTernaryExpressions": true
}
],
- "no-else-return" : [
+ "no-else-return": [
1,
{
"allowElseIf": false
}
],
- "semi" : [1, "always"]
+ "semi": [1, "always"]
}
},
"postcss": {
router-link(to="/problems")
| {{ st.tr["Problems"] }}
#rightMenu
- .clickable(onClick="doClick('modalUser')")
+ .clickable(onClick="window.doClick('modalUser')")
| {{ st.user.id > 0 ? (st.user.name || "@nonymous") : "Login" }}
- .clickable(onClick="doClick('modalSettings')")
+ .clickable(onClick="window.doClick('modalSettings')")
| {{ st.tr["Settings"] }}
- .clickable#flagContainer(onClick="doClick('modalLang')")
- img(v-if="!!st.lang" :src="flagImage")
+ .clickable#flagContainer(onClick="window.doClick('modalLang')")
+ img(
+ v-if="!!st.lang"
+ :src="flagImage"
+ )
router-view
.row
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
footer
router-link.menuitem(to="/about") {{ st.tr["About"] }}
router-link.menuitem(to="/news") {{ st.tr["News"] }}
- p.clickable(onClick="doClick('modalContact')")
+ p.clickable(onClick="window.doClick('modalContact')")
| {{ st.tr["Contact"] }}
</template>
import { ArrayFun } from "@/utils/array";
import { randInt, shuffle } from "@/utils/alea";
+// class "PiPo": Piece + Position
export const PiPo = class PiPo {
- //Piece+Position
// o: {piece[p], color[c], posX[x], posY[y]}
constructor(o) {
this.p = o.p;
}
};
-// TODO: for animation, moves should contains "moving" and "fading" maybe...
export const Move = class Move {
// o: {appear, vanish, [start,] [end,]}
// appear,vanish = arrays of PiPo
#downloadDiv(v-if="game.vname!='Dark' || game.score!='*'")
a#download(href="#")
button(@click="download()") {{ st.tr["Download"] }} PGN
- button(onClick="doClick('modalAdjust')") ⤢
+ button(onClick="window.doClick('modalAdjust')") ⤢
button(
v-if="game.vname!='Dark' && game.mode!='analyze'"
@click="analyzePosition()"
},
methods: {
focusBg: function() {
- // NOTE: small blue border appears...
document.getElementById("baseGame").focus();
},
adjustBoard: function() {
this.game.vname +
"/?fen=" +
this.vr.getFen().replace(/ /g, "_");
+ // Open in same tab in live games (against cheating)
if (this.game.type == "live") this.$router.push(newUrl);
- //open in same tab: against cheating...
- else window.open("#" + newUrl); //open in a new tab: more comfortable
+ else window.open("#" + newUrl);
},
download: function() {
const content = this.getPgn();
},
animateMove: function(move, callback) {
let startSquare = document.getElementById(getSquareId(move.start));
- // TODO: error "flush nextTick callbacks" when observer reloads page:
- // this late check is not a fix!
- if (!startSquare) return;
let endSquare = document.getElementById(getSquareId(move.end));
let rectStart = startSquare.getBoundingClientRect();
let rectEnd = endSquare.getBoundingClientRect();
let movingPiece = document.querySelector(
"#" + getSquareId(move.start) + " > img.piece"
);
- if (!movingPiece)
- //TODO: shouldn't happen
- return;
// HACK for animation (with positive translate, image slides "under background")
// Possible improvement: just alter squares on the piece's way...
const squares = document.getElementsByClassName("board");
}
movingPiece.style.transform =
"translate(" + translation.x + "px," + translation.y + "px)";
- movingPiece.style.transitionDuration = "0.2s";
+ movingPiece.style.transitionDuration = "0.25s";
movingPiece.style.zIndex = "3000";
setTimeout(() => {
for (let i = 0; i < squares.length; i++)
return;
}
const doPlayMove = () => {
- if (!!receive && this.cursor < this.moves.length - 1) this.gotoEnd(); //required to play the move
+ // To play a move, cursor must be at the end of the game:
+ if (!!receive && this.cursor < this.moves.length - 1) this.gotoEnd();
if (navigate) {
if (this.cursor == this.moves.length - 1) return; //no more moves
move = this.moves[this.cursor + 1];
<style lang="sass" scoped>
[type="checkbox"]#modalEog+div .card
min-height: 45px
+
[type="checkbox"]#modalAdjust+div .card
padding: 5px
display: inline-block
width: 20%
margin: 0
+
#turnIndicator
text-align: center
+
#belowControls
border-top: 1px solid #2f4f4f
text-align: center
& > button
border-left: 1px solid #2f4f4f
margin: 0
+
#boardContainer
float: left
// TODO: later, maybe, allow movesList of variable width
// or e.g. between 250 and 350px (but more complicated)
+
#movesList
width: 280px
float: left
+
@media screen and (max-width: 767px)
#movesList
width: 100%
th {{ st.tr["From"] }}
th {{ st.tr["Cadence"] }}
tbody
- tr(v-for="c in sortedChallenges" :class="{toyou:c.priority==1,fromyou:c.priority==2}" @click="$emit('click-challenge',c)")
+ tr(
+ v-for="c in sortedChallenges"
+ :class="{toyou:c.priority==1,fromyou:c.priority==2}"
+ @click="$emit('click-challenge',c)"
+ )
td {{ c.vname }}
td {{ c.from.name || "@nonymous" }}
td {{ c.cadence }}
</script>
<style lang="sass" scoped>
-// TODO: understand why the style applied to <tr> element doesn't work
+// NOTE: the style applied to <tr> element doesn't work
tr.fromyou > td
font-style: italic
tr.toyou > td
<template lang="pug">
div
- input#inputChat(type="text" :placeholder="st.tr['Chat here']"
- @keyup.enter="sendChat()")
+ input#inputChat(
+ type="text"
+ :placeholder="st.tr['Chat here']"
+ @keyup.enter="sendChat()"
+ )
button(@click="sendChat()") {{ st.tr["Send"] }}
p(v-for="chat in chats.concat(pastChats)")
span.name {{ chat.name }} :
- span(:class="classObject(chat)" v-html="chat.msg")
+ span(
+ :class="classObject(chat)"
+ v-html="chat.msg"
+ )
</template>
<script>
<style lang="sass" scoped>
.name
color: #abb2b9
+
.my-chatmsg
color: #7d3c98
.opp-chatmsg
<template lang="pug">
-BaseGame(:game="game" :vr="vr" @newmove="processMove" @gameover="gameOver")
+BaseGame(
+ :game="game"
+ :vr="vr"
+ @newmove="processMove"
+ @gameover="gameOver"
+)
</template>
<script>
this.$emit("game-stopped"); //no more moves: mate or stalemate
return; //after game ends, no more moves, nothing to do
}
- if (!Array.isArray(compMove)) compMove = [compMove]; //to deal with MarseilleRules
+ if (!Array.isArray(compMove)) compMove = [compMove]; //potential multi-move
// Small delay for the bot to appear "more human"
const delay = Math.max(500 - (Date.now() - this.timeStart), 0);
setTimeout(() => {
<template lang="pug">
div
- input#modalContact.modal(type="checkbox" @change="trySetEnterTime($event)")
- div(role="dialog" data-checkbox="modalContact")
+ input#modalContact.modal(
+ type="checkbox"
+ @change="trySetEnterTime($event)"
+ )
+ div(
+ role="dialog"
+ data-checkbox="modalContact"
+ )
.card
label.modal-close(for="modalContact")
form(@submit.prevent="trySendMessage()" @keyup.enter="trySendMessage()")
!confirm(this.st.tr["No subject. Send anyway?"])
)
return;
-
// Message sending:
ajax(
"/messages",
[type="checkbox"].modal+div .card
max-width: 767px
max-height: 100%
+
textarea#mailContent
width: 100%
min-height: 100px
+
#dialog
padding: 5px
color: blue
th(v-if="showCadence") {{ st.tr["Cadence"] }}
th {{ st.tr["Result"] }}
tbody
- tr(v-for="g in sortedGames" @click="$emit('show-game',g)"
- :class="{'my-turn': g.myTurn}")
+ tr(
+ v-for="g in sortedGames"
+ @click="$emit('show-game',g)"
+ :class="{'my-turn': g.myTurn}"
+ )
td {{ g.vname }}
td {{ player_s(g) }}
td(v-if="showCadence") {{ g.cadence }}
- td(:class="{finished: g.score!='*'}" @click="deleteGame(g,$event)")
+ td(
+ :class="{finished: g.score!='*'}"
+ @click="deleteGame(g,$event)"
+ )
| {{ g.score }}
</template>
</script>
<style lang="sass" scoped>
-// TODO: understand why the style applied to <tr> element doesn't work
+// NOTE: the style applied to <tr> element doesn't work
tr.my-turn > td
background-color: #fcd785
tr td.finished
"fr": "Français",
};
input#modalLang.modal(type="checkbox")
- div(role="dialog" data-checkbox="modalLang")
+ div(
+ role="dialog"
+ data-checkbox="modalLang"
+ )
.card
label.modal-close(for="modalLang")
form(@change="setLanguage($event)")
props: ["moves", "cursor", "score", "message", "firstNum"],
watch: {
cursor: function(newCursor) {
- if (window.innerWidth <= 767) return; //moves list is below: scrolling would hide chessboard
+ if (window.innerWidth <= 767) return; //scrolling would hide chessboard
// Count grouped moves until the cursor (if multi-moves):
let groupsCount = -1;
let curCol = undefined;
<style lang="sass" scoped>
.moves-list
min-width: 250px
+
td.highlight-lm
background-color: plum
</style>
+
+<!-- TODO: use template function + multi-moves: much easier
+<template lang="pug">
+div
+ #scoreInfo(v-if="score!='*'")
+ p {{ score }}
+ p {{ message }}
+ table.moves-list
+ tbody
+ tr(v-for="moveIdx in evenNumbers")
+ td {{ firstNum + moveIdx / 2 + 1 }}
+ td(:class="{'highlight-lm': cursor == moveIdx}"
+ @click="() => gotoMove(moveIdx)")
+ | {{ moves[moveIdx].notation }}
+ td(v-if="moveIdx < moves.length-1"
+ :class="{'highlight-lm': cursor == moveIdx+1}"
+ @click="() => gotoMove(moveIdx+1)")
+ | {{ moves[moveIdx+1].notation }}
+ // Else: just add an empty cell
+ td(v-else)
+</template>
+
+<script>
+// Component for moves list on the right
+export default {
+ name: 'my-move-list',
+ props: ["moves","cursor","score","message","firstNum"],
+ watch: {
+ cursor: function(newValue) {
+ if (window.innerWidth <= 767)
+ return; //moves list is below: scrolling would hide chessboard
+ if (newValue < 0)
+ newValue = 0; //avoid rows[-1] => error
+ // $nextTick to wait for table > tr to be rendered
+ this.$nextTick( () => {
+ let rows = document.querySelectorAll('#movesList tr');
+ if (rows.length > 0)
+ {
+ rows[Math.floor(newValue/2)].scrollIntoView({
+ behavior: "auto",
+ block: "nearest",
+ });
+ }
+ });
+ },
+ },
+ computed: {
+ evenNumbers: function() {
+ return [...Array(this.moves.length).keys()].filter(i => i%2==0);
+ },
+ },
+ methods: {
+ gotoMove: function(index) {
+ this.$emit("goto-move", index);
+ },
+ },
+};
+</script>
+-->
<template lang="pug">
div
input#modalSettings.modal(type="checkbox")
- div(role="dialog" data-checkbox="modalSettings")
+ div(
+ role="dialog"
+ data-checkbox="modalSettings"
+ )
.card(@change="updateSettings($event)")
label.modal-close(for="modalSettings")
form
fieldset
label(for="setHints") {{ st.tr["Show possible moves?"] }}
- input#setHints(type="checkbox" v-model="st.settings.hints")
+ input#setHints(
+ type="checkbox"
+ v-model="st.settings.hints"
+ )
fieldset
label(for="setHighlight")
| {{ st.tr["Highlight last move and checks?"] }}
- input#setHighlight(type="checkbox" v-model="st.settings.highlight")
+ input#setHighlight(
+ type="checkbox"
+ v-model="st.settings.highlight"
+ )
fieldset
label(for="setBcolor") {{ st.tr["Board colors"] }}
select#setBcolor(v-model="st.settings.bcolor")
<template lang="pug">
div
- input#modalUser.modal(type="checkbox" @change="trySetEnterTime($event)")
- div(role="dialog" data-checkbox="modalUser")
+ input#modalUser.modal(
+ type="checkbox"
+ @change="trySetEnterTime($event)"
+ )
+ div(
+ role="dialog"
+ data-checkbox="modalUser"
+ )
.card
label.modal-close(for="modalUser")
h3.section {{ st.tr[stage] }}
div(v-show="stage!='Login'")
fieldset
label(for="username") {{ st.tr["User name"] }}
- input#username(type="text" v-model="st.user.name")
+ input#username(
+ type="text"
+ v-model="st.user.name"
+ )
fieldset
label(for="useremail") {{ st.tr["Email"] }}
- input#useremail(type="email" v-model="st.user.email")
+ input#useremail(
+ type="email"
+ v-model="st.user.email"
+ )
fieldset
label(for="notifyNew") {{ st.tr["Notifications by email"] }}
- input#notifyNew(type="checkbox" v-model="st.user.notify")
+ input#notifyNew(
+ type="checkbox"
+ v-model="st.user.notify"
+ )
div(v-show="stage=='Login'")
fieldset
label(for="nameOrEmail") {{ st.tr["Name or Email"] }}
- input#nameOrEmail(type="text" v-model="nameOrEmail")
+ input#nameOrEmail(
+ type="text"
+ v-model="nameOrEmail"
+ )
.button-group
button(@click="onSubmit()")
span {{ st.tr[submitMessage] }}
- button(v-if="stage!='Update'" type="button" @click="toggleStage()")
+ button(
+ v-if="stage!='Update'"
+ type="button"
+ @click="toggleStage()"
+ )
span {{ st.tr[stage=="Login" ? "Register" : "Login"] }}
- button(v-else type="button" @click="doLogout()")
+ button(
+ v-else type="button"
+ @click="doLogout()"
+ )
span {{ st.tr["Logout"] }}
#dialog.text-center {{ st.tr[infoMsg] }}
</template>
[type="checkbox"].modal+div .card
max-width: 370px
max-height: 100%
+
#dialog
padding: 5px
color: blue
if (o.name.length == 0) return "Empty name";
if (!o.name.match(/^[\w]+$/)) return "Bad characters in name";
}
+
if (typeof o.email === "string") {
if (o.email.length == 0) return "Empty email";
if (!o.email.match(/^[\w.+-]+@[\w.+-]+$/)) return "Bad characters in email";
}
+
return "";
}
this.state.variants = res.variantArray;
});
let mysid = localStorage.getItem("mysid");
+ // Assign mysid only once (until next time user clear browser data)
if (!mysid) {
mysid = getRandString();
- localStorage.setItem("mysid", mysid); //done only once (unless user clear browser data)
+ localStorage.setItem("mysid", mysid);
}
// Quick user setup using local storage:
this.state.user = {
this.state.user.id = res.id;
const storedId = localStorage.getItem("myid");
if (res.id > 0 && !storedId)
- //user cleared localStorage
+ // User cleared localStorage
localStorage.setItem("myid", res.id);
else if (res.id == 0 && !!storedId)
- //user cleared cookie
+ // User cleared cookie
localStorage.removeItem("myid");
this.state.user.name = res.name;
const storedName = localStorage.getItem("myname");
if (!!res.name && !storedName)
- //user cleared localStorage
+ // User cleared localStorage
localStorage.setItem("myname", res.name);
else if (!res.name && !!storedName)
- //user cleared cookie
+ // User cleared cookie
localStorage.removeItem("myname");
this.state.user.email = res.email;
this.state.user.notify = res.notify;
// Source: https://www.quirksmode.org/js/cookies.html
export function setCookie(name, value) {
- var date = new Date();
+ const date = new Date();
date.setTime(date.getTime() + 183 * 24 * 60 * 60 * 1000); //6 months
- var expires = "; expires=" + date.toGMTString();
+ const expires = "; expires=" + date.toGMTString();
document.cookie = name + "=" + value + expires + "; path=/";
}
export function getCookie(name, defaut) {
- var nameEQ = name + "=";
- var ca = document.cookie.split(";");
+ const nameEQ = name + "=";
+ const ca = document.cookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == " ") c = c.substring(1, c.length);
// players: array of sid+id+name,
// cadence: string,
// increment: integer (seconds),
-// mode: string ("live" or "corr")
+// type: string ("live" or "corr")
// imported: boolean (optional, default false)
// // Game (dynamic) state:
// fen: string,
return 2;
}
- // TODO: this function could be generalized and shared better (how ?!...)
static GenRandInitFen() {
let pieces = { w: new Array(10), b: new Array(10) };
// Shuffle pieces on first and last rank
// Complete a move with magnetic actions
// TODO: job is done multiple times for (normal) promotions.
applyMagneticLaws(move) {
- if (move.appear[0].p == V.KING && move.appear.length == 1) return [move]; //kings are not charged
- const aIdx = move.appear[0].p != V.KING ? 0 : 1; //if castling, rook is charged
+ // Exception: kings are not charged
+ if (move.appear[0].p == V.KING && move.appear.length == 1) return [move];
+ // If castling, rook is charged:
+ const aIdx = move.appear[0].p != V.KING ? 0 : 1;
const [x, y] = [move.appear[aIdx].x, move.appear[aIdx].y];
const color = this.turn;
const lastRank = color == "w" ? 0 : 7;
.row
.col-sm-12
.text-center
- input#fen(v-model="curFen" @input="adjustFenSize()")
+ input#fen(
+ v-model="curFen"
+ @input="adjustFenSize()"
+ )
button(@click="gotoFen()") {{ st.tr["Go"] }}
- BaseGame(:game="game" :vr="vr")
+ BaseGame(
+ :game="game"
+ :vr="vr"
+ )
</template>
<script>
main
.row
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
- p(:class="{warn:!!this.errmsg}")
- | {{ errmsg || st.tr["Authentication successful!"] }}
+ p {{ st.tr["Authentication successful!"] }}
</template>
<script>
name: "my-auth",
data: function() {
return {
- st: store.state,
- errmsg: ""
+ st: store.state
};
},
created: function() {
"GET",
{ token: this.$route.params["token"] },
res => {
- if (!res.errmsg) {
- //if not already logged in
- this.st.user.id = res.id;
- this.st.user.name = res.name;
- this.st.user.email = res.email;
- this.st.user.notify = res.notify;
- localStorage["myname"] = res.name;
- localStorage["myid"] = res.id;
- } else this.errmsg = res.errmsg;
+ this.st.user.id = res.id;
+ this.st.user.name = res.name;
+ this.st.user.email = res.email;
+ this.st.user.notify = res.notify;
+ localStorage["myname"] = res.name;
+ localStorage["myid"] = res.id;
}
);
}
};
</script>
-
-<style lang="sass" scoped>
-.warn
- padding: 3px
- color: red
- background-color: lightgrey
- font-weight: bold
-</style>
<template lang="pug">
main
- input#modalChat.modal(type="checkbox" @click="resetChatColor()")
- div#chatWrap(role="dialog" data-checkbox="modalChat")
+ input#modalChat.modal(
+ type="checkbox"
+ @click="resetChatColor()"
+ )
+ div#chatWrap(
+ role="dialog"
+ data-checkbox="modalChat"
+ )
#chat.card
label.modal-close(for="modalChat")
#participants
span {{ Object.keys(people).length + " " + st.tr["participant(s):"] }}
- span(v-for="p in Object.values(people)" v-if="!!p.name")
+ span(
+ v-for="p in Object.values(people)"
+ v-if="!!p.name"
+ )
| {{ p.name }}
span.anonymous(v-if="Object.values(people).some(p => !p.name)")
| + @nonymous
- Chat(:players="game.players" :pastChats="game.chats"
- :newChat="newChat" @mychat="processChat")
+ Chat(
+ :players="game.players"
+ :pastChats="game.chats"
+ :newChat="newChat"
+ @mychat="processChat"
+ )
.row
#aboveBoard.col-sm-12.col-md-9.col-md-offset-3.col-lg-10.col-lg-offset-2
span.variant-cadence {{ game.cadence }}
span.variant-name {{ game.vname }}
- button#chatBtn(onClick="doClick('modalChat')") Chat
+ button#chatBtn(onClick="window.doClick('modalChat')") Chat
#actions(v-if="game.score=='*'")
- button(@click="clickDraw()" :class="{['draw-' + drawOffer]: true}")
+ button(
+ @click="clickDraw()"
+ :class="{['draw-' + drawOffer]: true}"
+ )
| {{ st.tr["Draw"] }}
- button(v-if="!!game.mycolor" @click="abortGame()") {{ st.tr["Abort"] }}
- button(v-if="!!game.mycolor" @click="resign()") {{ st.tr["Resign"] }}
+ button(
+ v-if="!!game.mycolor"
+ @click="abortGame()"
+ )
+ | {{ st.tr["Abort"] }}
+ button(
+ v-if="!!game.mycolor"
+ @click="resign()"
+ )
+ | {{ st.tr["Resign"] }}
#playersInfo
p
span.name(:class="{connected: isConnected(0)}")
span.name(:class="{connected: isConnected(1)}")
| {{ game.players[1].name || "@nonymous" }}
span.time(v-if="game.score=='*'") {{ virtualClocks[1] }}
- BaseGame(:game="game" :vr="vr" @newmove="processMove" @gameover="gameOver")
+ BaseGame(
+ :game="game"
+ :vr="vr"
+ @newmove="processMove"
+ @gameover="gameOver"
+ )
</template>
<script>
case "identity": {
const user = data.data;
if (user.name) {
- //otherwise anonymous
// If I multi-connect, kill current connexion if no mark (I'm older)
if (
this.newConnect[user.sid] &&
}
}
if (game.scoreMsg) game.scoreMsg = this.st.tr[game.scoreMsg]; //stored in english
+ delete game["moveToPlay"]; //in case of!
this.game = Object.assign(
{},
game,
<template lang="pug">
main
input#modalInfo.modal(type="checkbox")
- div#infoDiv(role="dialog" data-checkbox="modalInfo")
+ div#infoDiv(
+ role="dialog"
+ data-checkbox="modalInfo"
+ )
.card.text-center
label.modal-close(for="modalInfo")
p(v-html="infoMessage")
input#modalNewgame.modal(type="checkbox")
- div#newgameDiv(role="dialog" data-checkbox="modalNewgame")
+ div#newgameDiv(
+ role="dialog"
+ data-checkbox="modalNewgame"
+ )
.card
label#closeNewgame.modal-close(for="modalNewgame")
form(@submit.prevent="newChallenge()" @keyup.enter="newChallenge()")
fieldset
label(for="selectVariant") {{ st.tr["Variant"] }} *
select#selectVariant(v-model="newchallenge.vid")
- option(v-for="v in st.variants" :value="v.id"
- :selected="newchallenge.vid==v.id")
+ option(
+ v-for="v in st.variants"
+ :value="v.id"
+ :selected="newchallenge.vid==v.id"
+ )
| {{ v.name }}
fieldset
label(for="cadence") {{ st.tr["Cadence"] }} *
button 3+2
button 5+3
button 15+5
- input#cadence(type="text" v-model="newchallenge.cadence"
- placeholder="5+0, 1h+30s, 7d+1d ...")
+ input#cadence(
+ type="text"
+ v-model="newchallenge.cadence"
+ placeholder="5+0, 1h+30s, 7d+1d ..."
+ )
fieldset(v-if="st.user.id > 0")
label(for="selectPlayers") {{ st.tr["Play with?"] }}
- input#selectPlayers(type="text" v-model="newchallenge.to")
+ input#selectPlayers(
+ type="text"
+ v-model="newchallenge.to"
+ )
fieldset(v-if="st.user.id > 0 && newchallenge.to.length > 0")
label(for="inputFen") FEN
- input#inputFen(type="text" v-model="newchallenge.fen")
+ input#inputFen(
+ type="text"
+ v-model="newchallenge.fen"
+ )
button(@click="newChallenge()") {{ st.tr["Send challenge"] }}
- input#modalPeople.modal(type="checkbox" @click="resetChatColor()")
- div#peopleWrap(role="dialog" data-checkbox="modalPeople")
+ input#modalPeople.modal(
+ type="checkbox"
+ @click="resetChatColor()"
+ )
+ div#peopleWrap(
+ role="dialog"
+ data-checkbox="modalPeople"
+ )
.card
label.modal-close(for="modalPeople")
#people
#players
- p(v-for="sid in Object.keys(people)" v-if="!!people[sid].name")
+ p(
+ v-for="sid in Object.keys(people)"
+ v-if="!!people[sid].name"
+ )
span {{ people[sid].name }}
- button.player-action(v-if="sid!=st.user.sid || isGamer(sid)" @click="challOrWatch(sid)")
+ button.player-action(
+ v-if="sid!=st.user.sid || isGamer(sid)"
+ @click="challOrWatch(sid)"
+ )
| {{ getActionLabel(sid) }}
p.anonymous @nonymous ({{ anonymousCount }})
#chat
- Chat(:newChat="newChat" @mychat="processChat" :pastChats="[]")
+ Chat(
+ :newChat="newChat"
+ @mychat="processChat"
+ :pastChats="[]"
+ )
.clearer
.row
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
.button-group
- button#peopleBtn(onClick="doClick('modalPeople')") {{ st.tr["Social"] }}
- button(onClick="doClick('modalNewgame')") {{ st.tr["New game"] }}
+ button#peopleBtn(onClick="window.doClick('modalPeople')")
+ | {{ st.tr["Social"] }}
+ button(onClick="window.doClick('modalNewgame')")
+ | {{ st.tr["New game"] }}
.row
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
div#div2
| {{ st.tr["Live challenges"] }}
button.tabbtn#btnCcorr(@click="setDisplay('c','corr',$event)")
| {{ st.tr["Correspondance challenges"] }}
- ChallengeList(v-show="cdisplay=='live'"
- :challenges="filterChallenges('live')" @click-challenge="clickChallenge")
- ChallengeList(v-show="cdisplay=='corr'"
- :challenges="filterChallenges('corr')" @click-challenge="clickChallenge")
+ ChallengeList(
+ v-show="cdisplay=='live'"
+ :challenges="filterChallenges('live')"
+ @click-challenge="clickChallenge"
+ )
+ ChallengeList(
+ v-show="cdisplay=='corr'"
+ :challenges="filterChallenges('corr')"
+ @click-challenge="clickChallenge"
+ )
div#div3
.button-group
button.tabbtn#btnGlive(@click="setDisplay('g','live',$event)")
| {{ st.tr["Live games"] }}
button.tabbtn#btnGcorr(@click="setDisplay('g','corr',$event)")
| {{ st.tr["Correspondance games"] }}
- GameList(v-show="gdisplay=='live'" :games="filterGames('live')"
- :showBoth="true" @show-game="showGame")
- GameList(v-show="gdisplay=='corr'" :games="filterGames('corr')"
- :showBoth="true" @show-game="showGame")
+ GameList(
+ v-show="gdisplay=='live'"
+ :games="filterGames('live')"
+ :showBoth="true"
+ @show-game="showGame"
+ )
+ GameList(
+ v-show="gdisplay=='corr'"
+ :games="filterGames('corr')"
+ :showBoth="true"
+ @show-game="showGame"
+ )
</template>
<script>
case "identity": {
const user = data.data;
if (user.name) {
- //otherwise anonymous
// If I multi-connect, kill current connexion if no mark (I'm older)
if (
this.newConnect[user.sid] &&
width: 50%
position: relative
float: left
+
#chat
width: 50%
float: left
position: relative
+
@media screen and (max-width: 767px)
#players, #chats
width: 100%
+
#chat > .card
max-width: 100%
margin: 0;
border: none;
+
#players > p
margin-left: 5px
+
.anonymous
font-style: italic
+
button.player-action
margin-left: 32px
main
.row
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
- p(:class="{warn:!!this.errmsg}")
- | {{ errmsg || st.tr["Logout successful!"] }}
+ p {{ st.tr["Logout successful!"] }}
</template>
<script>
name: "my-logout",
data: function() {
return {
- st: store.state,
- errmsg: ""
+ st: store.state
};
},
created: function() {
- // NOTE: this local cleaning would logically happen when we're sure
- // that token is erased. But in the case a user clear the cookies,
- // it would lead to situations where he cannot ("locally") log out.
- // At worst, if token deletion fails the user can erase cookie manually.
- this.st.user.id = 0;
- this.st.user.name = "";
- this.st.user.email = "";
- this.st.user.notify = false;
- localStorage.removeItem("myid");
- localStorage.removeItem("myname");
- ajax("/logout", "GET"); //TODO: listen for errors?
+ ajax(
+ "/logout",
+ "GET",
+ () => {
+ this.st.user.id = 0;
+ this.st.user.name = "";
+ this.st.user.email = "";
+ this.st.user.notify = false;
+ localStorage.removeItem("myid");
+ localStorage.removeItem("myname");
+ }
+ );
}
};
</script>
-
-<style lang="sass" scoped>
-.warn
- padding: 3px
- color: red
- background-color: lightgrey
- font-weight: bold
-</style>
.row
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
.button-group
- button.tabbtn#liveGames(@click="setDisplay('live',$event)") {{ st.tr["Live games"] }}
- button.tabbtn#corrGames(@click="setDisplay('corr',$event)") {{ st.tr["Correspondance games"] }}
- GameList(v-show="display=='live'" :games="liveGames"
- @show-game="showGame")
- GameList(v-show="display=='corr'" :games="corrGames"
- @show-game="showGame")
+ button.tabbtn#liveGames(@click="setDisplay('live',$event)")
+ | {{ st.tr["Live games"] }}
+ button.tabbtn#corrGames(@click="setDisplay('corr',$event)")
+ | {{ st.tr["Correspondance games"] }}
+ GameList(
+ v-show="display=='live'"
+ :games="liveGames"
+ @show-game="showGame"
+ )
+ GameList(
+ v-show="display=='corr'"
+ :games="corrGames"
+ @show-game="showGame"
+ )
</template>
<script>
<template lang="pug">
main
input#modalNews.modal(type="checkbox")
- div#newnewsDiv(role="dialog" data-checkbox="modalNews")
+ div#newnewsDiv(
+ role="dialog"
+ data-checkbox="modalNews"
+ )
.card
label.modal-close(for="modalNews")
textarea#newsContent(
@click="showModalNews"
)
| {{ st.tr["Write news"] }}
- .news(v-for="n,idx in newsList" :class="{margintop:idx>0}")
+ .news(
+ v-for="n,idx in newsList"
+ :class="{margintop:idx>0}"
+ )
span.ndt {{ formatDatetime(n.added) }}
div(v-if="devs.includes(st.user.id)")
button(@click="editNews(n)") {{ st.tr["Edit"] }}
button(@click="deleteNews(n)") {{ st.tr["Delete"] }}
p(v-html="parseHtml(n.content)")
- button(v-if="hasMore" @click="loadMore()")
+ button(
+ v-if="hasMore"
+ @click="loadMore()"
+ )
| {{ st.tr["Load more"] }}
</template>
[type="checkbox"].modal+div .card
max-width: 767px
max-height: 100%
+
textarea#newsContent
margin: 0
width: 100%
min-height: 200px
max-height: 100%
+
#dialog
padding: 5px
color: blue
+
button#writeNews
margin-top: 0
margin-bottom: 0
+
span.ndt
color: darkblue
padding: 0 5px 0 var(--universal-margin)
-.margintop
- margin-top: 25px
- border-top: 1px solid grey
+
.news
padding-top: 10px
& > div
display: inline-block
+
+.margintop
+ margin-top: 25px
+ border-top: 1px solid grey
@media screen and (max-width: 767px)
.margintop
margin-top: 10px
<template lang="pug">
main
- input#modalNewprob.modal(type="checkbox" @change="infoMsg=''")
- div#newprobDiv(role="dialog" data-checkbox="modalNewprob")
+ input#modalNewprob.modal(
+ type="checkbox"
+ @change="infoMsg=''"
+ )
+ div#newprobDiv(
+ role="dialog"
+ data-checkbox="modalNewprob"
+ )
.card(@keyup.enter="sendProblem()")
label#closeNewprob.modal-close(for="modalNewprob")
fieldset
td {{ p.vname }}
td {{ firstChars(p.instruction) }}
td {{ p.id }}
- BaseGame(v-if="showOne" :game="game" :vr="vr")
+ BaseGame(
+ v-if="showOne"
+ :game="game"
+ :vr="vr"
+ )
</template>
<script>
);
},
editProblem: function(prob) {
- if (!prob.diag) this.setDiagram(prob); //possible because V is loaded at this stage
+ if (!prob.diag) this.setDiagram(prob); //V is loaded at this stage
this.copyProblem(prob, this.curproblem);
window.doClick("modalNewprob");
},
[type="checkbox"].modal+div .card
max-width: 767px
max-height: 100%
+
#inputFen
width: 100%
+
textarea
width: 100%
+
#diagram
margin: 0 auto
max-width: 400px
+
#controls
margin: 0
width: 100%
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
.button-group
button(@click="clickReadRules()") {{ st.tr["Rules"] }}
- button(v-show="!gameInProgress" @click="startGame('auto')")
+ button(
+ v-show="!gameInProgress"
+ @click="startGame('auto')"
+ )
| {{ st.tr["Example game"] }}
- button(v-show="!gameInProgress" @click="startGame('versus')")
+ button(
+ v-show="!gameInProgress"
+ @click="startGame('versus')"
+ )
| {{ st.tr["Practice"] }}
- button(v-show="gameInProgress" @click="stopGame()")
+ button(
+ v-show="gameInProgress"
+ @click="stopGame()"
+ )
| {{ st.tr["Stop game"] }}
- button(v-if="display=='rules' && gameInfo.vname!='Dark'"
- @click="gotoAnalyze()")
+ button(
+ v-if="display=='rules' && gameInfo.vname!='Dark'"
+ @click="gotoAnalyze()"
+ )
| {{ st.tr["Analyse"] }}
- div(v-show="display=='rules'" v-html="content")
- ComputerGame(v-show="display=='computer'" :game-info="gameInfo"
- @game-over="stopGame" @game-stopped="gameStopped")
+ div(
+ v-show="display=='rules'"
+ v-html="content"
+ )
+ ComputerGame(
+ v-show="display=='computer'"
+ :game-info="gameInfo"
+ @game-over="stopGame"
+ @game-stopped="gameStopped"
+ )
</template>
<script>
main
.row
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
- input#prefixFilter(v-model="curPrefix" :placeholder="st.tr['Prefix?']")
+ input#prefixFilter(
+ v-model="curPrefix"
+ :placeholder="st.tr['Prefix?']"
+ )
.variant.col-sm-12.col-md-5.col-lg-4(
v-for="(v,idx) in filteredVariants"
:class="{'col-md-offset-1': idx%2==0, 'col-lg-offset-2': idx%2==0}"
</script>
<style lang="sass" scoped>
-// TODO: box-shadow or box-sizing ? https://stackoverflow.com/a/13517809
input#prefixFilter
display: block
margin: 0 auto
+
.variant
box-sizing: border-box
border: 1px solid brown
case "askfullgame":
{
const pg = obj.page || page; //required for askidentity and askgame
- const tmpIds = Object.keys(clients[pg][obj.target]);
- if (obj.target == sid) //targetting myself
+ // In cas askfullgame to wrong SID for example, would crash:
+ if (!!clients[pg][obj.target])
{
- const idx_myTmpid = tmpIds.findIndex(x => x == tmpId);
- if (idx_myTmpid >= 0)
- tmpIds.splice(idx_myTmpid, 1);
+ const tmpIds = Object.keys(clients[pg][obj.target]);
+ if (obj.target == sid) //targetting myself
+ {
+ const idx_myTmpid = tmpIds.findIndex(x => x == tmpId);
+ if (idx_myTmpid >= 0)
+ tmpIds.splice(idx_myTmpid, 1);
+ }
+ const tmpId_idx = Math.floor(Math.random() * tmpIds.length);
+ send(
+ clients[pg][obj.target][tmpIds[tmpId_idx]],
+ {code:obj.code, from:[sid,tmpId,page]}
+ );
}
- const tmpId_idx = Math.floor(Math.random() * tmpIds.length);
- send(clients[pg][obj.target][tmpIds[tmpId_idx]], {code:obj.code, from:[sid,tmpId,page]});
break;
}