MoveList(v-if="showMoves" :score="game.score" :message="game.scoreMsg"
:firstNum="firstMoveNumber" :moves="moves" :cursor="cursor"
@goto-move="gotoMove")
- // TODO: clearer required ?!
- .clearer
+ .clearer
</template>
<script>
},
methods: {
focusBg: function() {
- // TODO: small blue border appears...
+ // NOTE: small blue border appears...
document.getElementById("baseGame").focus();
},
handleKeys: function(e) {
}
},
handleScroll: function(e) {
- if (e.deltaY < 0)
- this.undo();
- else if (e.deltaY > 0)
- this.play();
+ if (this.game.mode == "analyze" || this.game.score != "*")
+ {
+ e.preventDefault();
+ if (e.deltaY < 0)
+ this.undo();
+ else if (e.deltaY > 0)
+ this.play();
+ }
},
re_setVariables: function() {
this.endgameMessage = "";
};
</script>
-<style lang="sass">
+<style lang="sass" scoped>
#baseGame
width: 100%
#modal-eog+div .card
overflow: hidden
-@media screen and (min-width: 768px)
- #controls
- width: 400px
- margin-left: auto
- margin-right: auto
#controls
margin-top: 10px
margin-left: auto
display: inline-block
width: 20%
margin: 0
+@media screen and (min-width: 768px)
+ #controls
+ max-width: 400px
#pgnDiv
text-align: center
margin-left: auto
margin-right: auto
#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
width: 100%
float: none
clear: both
- table
- tr
- display: flex
- margin: 0
- padding: 0
- td
- text-align: left
</style>
};
</script>
-<style lang="sass">
+<style lang="sass" scoped>
.game.reserve-div
margin-bottom: 18px
color: grey
.opp-chatmsg
color: black
-#chat
- max-width: 100%
</style>
priority++;
}
}
- return Object.assign({}, g, {priority: priority, myTurn: priority==2});
+ return Object.assign({}, g, {priority: priority, myTurn: priority==3});
});
return augmentedGames.sort((g1,g2) => { return g2.priority - g1.priority; });
},
};
</script>
-<style scoped lang="sass">
-.my-turn
- // TODO: the style doesn't work... why?
- background-color: orange
+<style lang="sass" scoped>
+// TODO: understand why the style applied to <tr> element doesn't work
+tr.my-turn > td
+ background-color: #fcd785
</style>
};
},
mounted: function() {
- // TODO: better style would be in pug directly, but how?
+ // NOTE: better style would be in pug directly, but how?
document.querySelectorAll("#langSelect > option").forEach(opt => {
if (opt.value == this.st.lang)
opt.selected = true;
<style lang="sass" scoped>
.moves-list
min-width: 250px
+@media screen and (max-width: 767px)
+ .moves-list
+ tr
+ display: flex
+ margin: 0
+ padding: 0
+ td
+ text-align: left
td.highlight-lm
background-color: plum
</style>
return; //no board on page
const k = document.getElementById("myRange").value;
const movesWidth = (window.innerWidth >= 768 ? 280 : 0);
- const minBoardWidth = 240; //TODO: same
+ const minBoardWidth = 240; //TODO: these 240 and 280 are arbitrary...
// Value of 0 is board min size; 100 is window.width [- movesWidth]
const boardSize = minBoardWidth +
k * (window.innerWidth - (movesWidth+minBoardWidth)) / 100;
methods: {
// O.1] Ask server for room composition:
roomInit: function() {
+ // Notify the room only now that I connected, because
+ // messages might be lost otherwise (if game loading is slow)
+ this.st.conn.send(JSON.stringify({code:"connect"}));
this.st.conn.send(JSON.stringify({code:"pollclients"}));
},
isConnected: function(index) {
}
case "identity":
{
- let player = this.people[data.user.sid];
// NOTE: sometimes player.id fails because player is undefined...
// Probably because the event was meant for Hall?
- if (!player)
+ if (!this.people[data.user.sid])
return;
- player.id = data.user.id;
- player.name = data.user.name;
+ this.$set(this.people, data.user.sid,
+ {id: data.user.id, name: data.user.name});
// Sending last state only for live games: corr games are complete
if (this.game.type == "live" && this.game.oppsid == data.user.sid)
{
game:myGame, target:data.from}));
break;
case "newmove":
- this.$set(this.game, "moveToPlay", data.move); //TODO: Vue3...
+ this.$set(this.game, "moveToPlay", data.move);
break;
case "lastate": //got opponent infos about last move
{
this.gameOver("1/2", data.message);
break;
case "drawoffer":
- this.drawOffer = "received"; //TODO: observers don't know who offered draw
+ // NOTE: observers don't know who offered draw
+ this.drawOffer = "received";
break;
case "askfullgame":
- this.st.conn.send(JSON.stringify({code:"fullgame", game:this.game, target:data.from}));
+ this.st.conn.send(JSON.stringify({code:"fullgame",
+ game:this.game, target:data.from}));
break;
case "fullgame":
// Callback "roomInit" to poll clients only after game is loaded
});
this.gameOver("1/2", message);
}
- else if (this.drawOffer == "sent")
- {
- this.drawOffer = "";
- if (this.game.type == "corr")
- GameStorage.update(this.gameRef.id, {drawOffer: false});
- }
- else
+ else if (this.drawOffer == "") //no effect if drawOffer == "sent"
{
if (!confirm("Offer draw?"))
return;
if (sid != this.st.user.sid)
this.st.conn.send(JSON.stringify({code:"drawoffer", target:sid}));
});
- if (this.game.type == "corr")
- GameStorage.update(this.gameRef.id, {drawOffer: true});
+ GameStorage.update(this.gameRef.id, {drawOffer: true});
}
},
abortGame: function() {
};
</script>
-<style lang="sass">
+<style lang="sass" scoped>
.connected
background-color: lightgreen
button(@click="pdisplay='players'") Players
button(@click="pdisplay='chat'") Chat
#players(v-show="pdisplay=='players'")
- p.text-center(v-for="p in uniquePlayers")
+ p(v-for="p in uniquePlayers")
span(:class="{anonymous: !!p.count}")
| {{ (p.name || '@nonymous') + (!!p.count ? " ("+p.count+")" : "") }}
- button.player-action(v-if="!p.count" @click="challOrWatch(p,$event)")
+ button.player-action(v-if="!p.count && p.name != st.user.name"
+ @click="challOrWatch(p,$event)")
| {{ whatPlayerDoes(p) }}
#chat(v-show="pdisplay=='chat'")
Chat(:players="[]")
return (!!variant ? variant.name : "");
},
whatPlayerDoes: function(p) {
- if (this.games.some(g => g.players.some(pl => pl.sid == p.sid)))
+ if (this.games.some(g => g.type == "live"
+ && g.players.some(pl => pl.sid == p.sid)))
+ {
return "Playing";
+ }
return "Challenge"; //player is available
},
sendSomethingTo: function(to, code, obj, warnDisconnected) {
case "Playing":
// NOTE: this search for game was already done for rendering
this.showGame(this.games.find(
- g => g.players.some(pl => pl.sid == p.sid)));
+ g => g.type=="live" && g.players.some(pl => pl.sid == p.sid)));
break;
};
},
};
</script>
-<style lang="sass">
+<style lang="sass" scoped>
#newGame
display: block
margin: 10px auto 5px auto
max-width: 100%
margin: 0;
border: none;
+#players > p
+ margin-left: 40%
+@media screen and (max-width: 767px)
+ #players > p
+ margin-left: 5px
.anonymous
font-style: italic
button.player-action
- margin-left: 20px
+ margin-left: 32px
</style>
},
};
</script>
-
-<style scoped lang="sass">
-/* TODO */
-</style>
};
</script>
-<style lang="sass">
+<style lang="sass" scoped>
//.section-content
// *
// margin-left: auto
.dark-square-diag
background-color: #6f8f57
-// TODO: following is duplicated
+// TODO: following is duplicated (Board.vue)
div.board
float: left
height: 0
};
</script>
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="sass">
+<style lang="sass" scoped>
// TODO: box-shadow or box-sizing ? https://stackoverflow.com/a/13517809
.variant
box-sizing: border-box
const GameModel =
{
checkGameInfo: function(g) {
- if (!g.id.toString().match(/^[0-9]+$/))
- return "Wrong game ID";
if (!g.vid.toString().match(/^[0-9]+$/))
return "Wrong variant ID";
if (!g.vname.match(/^[a-zA-Z0-9]+$/))
{
query =
"INSERT INTO Chats (gid, msg, name, added) VALUES ("
- + id + ",?,'" + obj.chat.name + "'," + "," + Date.now() + ")";
+ + id + ",?,'" + obj.chat.name + "'," + Date.now() + ")";
db.run(query, obj.chat.msg);
}
});
}
});
};
- notifyRoom(query["page"], "connect"); //Hall or Game
- if (query["page"].indexOf("/game/") >= 0)
- notifyRoom("/", "connect"); //notify main hall
+ // Wait for "connect" message to notify connection to the room,
+ // because if game loading is slow the message listener might
+ // not be ready too early.
socket.on("message", objtxt => {
let obj = JSON.parse(objtxt);
if (!!obj.target && !clients[obj.target])
return; //receiver not connected, nothing we can do
switch (obj.code)
{
+ case "connect":
+ notifyRoom(query["page"], "connect"); //Hall or Game
+ if (query["page"].indexOf("/game/") >= 0)
+ notifyRoom("/", "connect"); //notify main hall
+ break;
case "pollclients":
const curPage = clients[sid].page;
socket.send(JSON.stringify({code:"pollclients",