From 41c80bb63b85b2696d3925c10784c3d7bb5d2aa3 Mon Sep 17 00:00:00 2001 From: Benjamin Auder <benjamin.auder@somewhere> Date: Sat, 1 Feb 2020 23:51:25 +0100 Subject: [PATCH] TODO: fix draw logic --- client/src/components/BaseGame.vue | 36 +++++++++++++----------------- client/src/components/Board.vue | 2 +- client/src/components/Chat.vue | 2 -- client/src/components/GameList.vue | 10 ++++----- client/src/components/Language.vue | 2 +- client/src/components/MoveList.vue | 8 +++++++ client/src/components/Settings.vue | 2 +- client/src/views/Game.vue | 31 ++++++++++++------------- client/src/views/Hall.vue | 21 ++++++++++++----- client/src/views/MyGames.vue | 4 ---- client/src/views/Rules.vue | 4 ++-- client/src/views/Variants.vue | 3 +-- server/models/Game.js | 4 +--- server/sockets.js | 11 ++++++--- 14 files changed, 73 insertions(+), 67 deletions(-) diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index 2bf1fbdb..595f9aa3 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -26,8 +26,7 @@ div#baseGame(tabindex=-1 @click="() => focusBg()" 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> @@ -94,7 +93,7 @@ export default { }, methods: { focusBg: function() { - // TODO: small blue border appears... + // NOTE: small blue border appears... document.getElementById("baseGame").focus(); }, handleKeys: function(e) { @@ -120,10 +119,14 @@ export default { } }, 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 = ""; @@ -350,7 +353,7 @@ export default { }; </script> -<style lang="sass"> +<style lang="sass" scoped> #baseGame width: 100% @@ -360,11 +363,6 @@ export default { #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 @@ -373,12 +371,17 @@ export default { 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 @@ -387,11 +390,4 @@ export default { width: 100% float: none clear: both - table - tr - display: flex - margin: 0 - padding: 0 - td - text-align: left </style> diff --git a/client/src/components/Board.vue b/client/src/components/Board.vue index 25da6f14..1b7fd6bc 100644 --- a/client/src/components/Board.vue +++ b/client/src/components/Board.vue @@ -363,7 +363,7 @@ export default { }; </script> -<style lang="sass"> +<style lang="sass" scoped> .game.reserve-div margin-bottom: 18px diff --git a/client/src/components/Chat.vue b/client/src/components/Chat.vue index cbfb8059..18ce6fa9 100644 --- a/client/src/components/Chat.vue +++ b/client/src/components/Chat.vue @@ -68,6 +68,4 @@ export default { color: grey .opp-chatmsg color: black -#chat - max-width: 100% </style> diff --git a/client/src/components/GameList.vue b/client/src/components/GameList.vue index 4233a01b..5ab61cc3 100644 --- a/client/src/components/GameList.vue +++ b/client/src/components/GameList.vue @@ -50,7 +50,7 @@ export default { 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; }); }, @@ -58,8 +58,8 @@ export default { }; </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> diff --git a/client/src/components/Language.vue b/client/src/components/Language.vue index ac4faa79..c701e590 100644 --- a/client/src/components/Language.vue +++ b/client/src/components/Language.vue @@ -29,7 +29,7 @@ export default { }; }, 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; diff --git a/client/src/components/MoveList.vue b/client/src/components/MoveList.vue index 1209dd99..28d0d009 100644 --- a/client/src/components/MoveList.vue +++ b/client/src/components/MoveList.vue @@ -58,6 +58,14 @@ export default { <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> diff --git a/client/src/components/Settings.vue b/client/src/components/Settings.vue index 6034ab45..92b463ef 100644 --- a/client/src/components/Settings.vue +++ b/client/src/components/Settings.vue @@ -81,7 +81,7 @@ export default { 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; diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue index 30fbc39b..e6cb1e70 100644 --- a/client/src/views/Game.vue +++ b/client/src/views/Game.vue @@ -135,6 +135,9 @@ export default { 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) { @@ -182,13 +185,12 @@ export default { } 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) { @@ -225,7 +227,7 @@ export default { 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 { @@ -245,10 +247,12 @@ export default { 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 @@ -306,13 +310,7 @@ export default { }); 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; @@ -321,8 +319,7 @@ export default { 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() { @@ -578,7 +575,7 @@ export default { }; </script> -<style lang="sass"> +<style lang="sass" scoped> .connected background-color: lightgreen diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index 7b42854d..2df03e6e 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -49,10 +49,11 @@ main 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="[]") @@ -233,8 +234,11 @@ export default { 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) { @@ -428,7 +432,7 @@ export default { 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; }; }, @@ -620,7 +624,7 @@ export default { }; </script> -<style lang="sass"> +<style lang="sass" scoped> #newGame display: block margin: 10px auto 5px auto @@ -628,8 +632,13 @@ export default { 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> diff --git a/client/src/views/MyGames.vue b/client/src/views/MyGames.vue index 60792542..a8d9e127 100644 --- a/client/src/views/MyGames.vue +++ b/client/src/views/MyGames.vue @@ -57,7 +57,3 @@ export default { }, }; </script> - -<style scoped lang="sass"> -/* TODO */ -</style> diff --git a/client/src/views/Rules.vue b/client/src/views/Rules.vue index e1ef8fef..82a4a40f 100644 --- a/client/src/views/Rules.vue +++ b/client/src/views/Rules.vue @@ -111,7 +111,7 @@ export default { }; </script> -<style lang="sass"> +<style lang="sass" scoped> //.section-content // * // margin-left: auto @@ -194,7 +194,7 @@ ul:not(.browser-default) > li .dark-square-diag background-color: #6f8f57 -// TODO: following is duplicated +// TODO: following is duplicated (Board.vue) div.board float: left height: 0 diff --git a/client/src/views/Variants.vue b/client/src/views/Variants.vue index 9d0a42d9..69d4e69c 100644 --- a/client/src/views/Variants.vue +++ b/client/src/views/Variants.vue @@ -50,8 +50,7 @@ export default { }; </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 diff --git a/server/models/Game.js b/server/models/Game.js index 02e3194b..5e1c7990 100644 --- a/server/models/Game.js +++ b/server/models/Game.js @@ -34,8 +34,6 @@ const UserModel = require("./User"); 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]+$/)) @@ -228,7 +226,7 @@ const GameModel = { 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); } }); diff --git a/server/sockets.js b/server/sockets.js index b31334c1..ef2f07b4 100644 --- a/server/sockets.js +++ b/server/sockets.js @@ -31,15 +31,20 @@ module.exports = function(wss) { } }); }; - 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", -- 2.44.0