From: Benjamin Auder Date: Wed, 5 Feb 2020 20:12:41 +0000 (+0100) Subject: Left some TODOs, some bugs X-Git-Url: https://git.auder.net/doc/html/%7B%7B%20asset%28%27mixstore/css/base.css%27%29%20%7D%7D?a=commitdiff_plain;h=ac8f441c6441d827b43aabeb812cb4c79e9ee96b;p=vchess.git Left some TODOs, some bugs --- diff --git a/client/src/components/Chat.vue b/client/src/components/Chat.vue index 752dadaf..7eeba5ac 100644 --- a/client/src/components/Chat.vue +++ b/client/src/components/Chat.vue @@ -15,37 +15,24 @@ import { store } from "@/store"; export default { name: "my-chat", // Prop 'pastChats' for corr games where chats are on server - props: ["players","pastChats"], + props: ["players","pastChats","newChat"], data: function() { return { st: store.state, chats: [], //chat messages after human game }; }, - created: function() { - const curMsgListener = this.st.conn.onmessage; //from Game or Hall - const socketMessageListener = msg => { - curMsgListener(msg); - const data = JSON.parse(msg.data); - if (data.code == "newchat") //only event at this level - { - this.chats.unshift({msg:data.msg, name:data.name || "@nonymous"}); - this.$emit("newchat-received"); //data not required here - } - }; - const socketCloseListener = () => { - store.socketCloseListener(); //reinitialize connexion (in store.js) - this.st.conn.addEventListener("message", socketMessageListener); - this.st.conn.addEventListener("close", socketCloseListener); - }; - this.st.conn.onmessage = socketMessageListener; - this.st.conn.onclose = socketCloseListener; + watch: { + newChat: function(chat) { + if (chat.msg != "") + this.chats.unshift({msg:chat.msg, name:chat.name || "@nonymous"}); + }, }, methods: { classObject: function(chat) { return { "my-chatmsg": chat.name == this.st.user.name, - "opp-chatmsg": this.players.some( + "opp-chatmsg": !!this.players && this.players.some( p => p.name == chat.name && p.name != this.st.user.name) }; }, @@ -56,10 +43,8 @@ export default { return; //nothing to send chatInput.value = ""; const chat = {msg:chatTxt, name: this.st.user.name || "@nonymous"}; - this.$emit("newchat-sent", chat); //useful for corr games + this.$emit("mychat", chat); this.chats.unshift(chat); - this.st.conn.send(JSON.stringify({ - code:"newchat", msg:chatTxt, name:chat.name})); }, }, }; diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue index d366bb2d..ddd5e593 100644 --- a/client/src/views/Game.vue +++ b/client/src/views/Game.vue @@ -5,13 +5,13 @@ main #chat.card label.modal-close(for="modalChat") #participants - span {{ Object.keys(people).length }} st.tr["participant(s):"] + span {{ Object.keys(people).length + " " + st.tr["participant(s):"] }} 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-sent="finishSendChat" @newchat-received="processChat") + :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-info @@ -68,6 +68,7 @@ export default { people: {}, //players + observers lastate: undefined, //used if opponent send lastate before game is ready repeat: {}, //detect position repetition + newChat: "", }; }, watch: { @@ -246,6 +247,11 @@ export default { this.drawOffer = ""; this.$set(this.game, "moveToPlay", data.move); break; + case "newchat": + this.newChat = data.chat; + if (!document.getElementById("modalChat").checked) + document.getElementById("chatBtn").style.backgroundColor = "#c5fefe"; + break; case "lastate": //got opponent infos about last move { this.lastate = data; @@ -616,15 +622,12 @@ export default { // TODO: this is called twice, once on opening an once on closing document.getElementById("chatBtn").style.backgroundColor = "#e2e2e2"; }, - finishSendChat: function(chat) { + processChat: function(chat) { + this.st.conn.send(JSON.stringify({code:"newchat", chat:chat})); // NOTE: anonymous chats in corr games are not stored on server (TODO?) if (this.game.type == "corr" && this.st.user.id > 0) GameStorage.update(this.gameRef.id, {chat: chat}); }, - processChat: function() { - if (!document.getElementById("modalChat").checked) - document.getElementById("chatBtn").style.backgroundColor = "#c5fefe"; - }, gameOver: function(score, scoreMsg) { this.game.score = score; this.game.scoreMsg = this.st.tr[(!!scoreMsg @@ -666,7 +669,6 @@ export default { margin-top: 10px button display: inline-block - width: 33% margin: 0 @media screen and (max-width: 767px) diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index 48ad4d3f..8cd330ff 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -29,7 +29,7 @@ main label(for="selectPlayers") {{ st.tr["Play with?"] }} input#selectPlayers(type="text" v-model="newchallenge.to") fieldset(v-if="st.user.id > 0 && newchallenge.to.length > 0") - label(for="inputFen") {{ FEN }} + label(for="inputFen") FEN input#inputFen(type="text" v-model="newchallenge.fen") button(@click="newChallenge") {{ st.tr["Send challenge"] }} .row @@ -59,7 +59,7 @@ main | {{ whatPlayerDoes(p) }} p.anonymous @nonymous ({{ anonymousCount }}) #chat - Chat(:players="[]") + Chat(:newChat="newChat" @mychat="processChat") .clearer div .button-group @@ -108,6 +108,7 @@ export default { to: "", //name of challenged player (if any) timeControl: localStorage.getItem("timeControl") || "", }, + newChat: "", }; }, watch: { @@ -196,6 +197,7 @@ export default { // after we're sure WebSocket is initialized this.st.conn.send(JSON.stringify({code:"connect"})); this.st.conn.send(JSON.stringify({code:"pollclients"})); + this.st.conn.send(JSON.stringify({code:"pollgamers"})); }; if (!!this.st.conn && this.st.conn.readyState == 1) //1 == OPEN state funcPollClients(); @@ -251,6 +253,10 @@ export default { // this.st.variants might be uninitialized (variant == null) return (!!variant ? variant.name : ""); }, + +// TODO: now that we can distinguish people from Hall or Game, +// improve this --> the info is already known + whatPlayerDoes: function(p) { if (this.games.some(g => g.type == "live" && g.players.some(pl => pl.sid == p.sid))) @@ -259,6 +265,14 @@ export default { } return "Challenge"; //player is available }, + +// Also debug: when from game going to Hall, player appears still connected. +// when reloading a finished (observed) game, some ghost moveToPlay errors + + processChat: function(chat) { + // When received on server, this will trigger a "notifyRoom" + this.st.conn.send(JSON.stringify({code:"newchat", chat: chat})); + }, sendSomethingTo: function(to, code, obj, warnDisconnected) { const doSend = (code, obj, sid) => { this.st.conn.send(JSON.stringify(Object.assign( @@ -301,17 +315,23 @@ export default { break; // 0.2] Receive clients list (just socket IDs) case "pollclients": - { data.sockIds.forEach(sid => { this.$set(this.people, sid, {id:0, name:""}); - // Ask identity, challenges and game(s) + // Ask identity and challenges this.st.conn.send(JSON.stringify({code:"askidentity", target:sid})); this.st.conn.send(JSON.stringify({code:"askchallenge", target:sid})); }); + break; + case "pollgamers": + // NOTE: we could make a difference between people in hall + // and gamers, but is it necessary? + data.sockIds.forEach(sid => { + this.$set(this.people, sid, {id:0, name:""}); + this.st.conn.send(JSON.stringify({code:"askidentity", target:sid})); + }); // Also ask current games to all playing peers (TODO: some design issue) this.st.conn.send(JSON.stringify({code:"askgames"})); break; - } case "askidentity": { // Request for identification: reply if I'm not anonymous @@ -413,6 +433,9 @@ export default { } break; } + case "newchat": + this.newChat = data.chat; + break; case "refusechallenge": { ArrayFun.remove(this.challenges, c => c.id == data.cid); @@ -428,24 +451,29 @@ export default { break; } case "connect": - { + case "gconnect": this.$set(this.people, data.from, {name:"", id:0}); this.st.conn.send(JSON.stringify({code:"askidentity", target:data.from})); - this.st.conn.send(JSON.stringify({code:"askchallenge", target:data.from})); - this.st.conn.send(JSON.stringify({code:"askgame", target:data.from})); + if (data.code == "connect") + this.st.conn.send(JSON.stringify({code:"askchallenge", target:data.from})); + else + this.st.conn.send(JSON.stringify({code:"askgame", target:data.from})); break; - } case "disconnect": - { this.$delete(this.people, data.from); - // Also remove all challenges sent by this player: - ArrayFun.remove(this.challenges, c => c.from.sid == data.from); - // And all live games where he plays and no other opponent is online - ArrayFun.remove(this.games, g => - g.type == "live" && (g.players.every(p => p.sid == data.from - || !this.people[p.sid])), "all"); + if (data.code == "disconnect") + { + // Also remove all challenges sent by this player: + ArrayFun.remove(this.challenges, c => c.from.sid == data.from); + } + else + { + // And all live games where he plays and no other opponent is online + ArrayFun.remove(this.games, g => + g.type == "live" && (g.players.every(p => p.sid == data.from + || !this.people[p.sid])), "all"); + } break; - } } }, // Challenge lifecycle: diff --git a/server/sockets.js b/server/sockets.js index ef2f07b4..d296efa1 100644 --- a/server/sockets.js +++ b/server/sockets.js @@ -38,30 +38,43 @@ module.exports = function(wss) { let obj = JSON.parse(objtxt); if (!!obj.target && !clients[obj.target]) return; //receiver not connected, nothing we can do + +// TODO: debug +console.log(obj.code + " " + clients[sid].page); + switch (obj.code) { case "connect": notifyRoom(query["page"], "connect"); //Hall or Game if (query["page"].indexOf("/game/") >= 0) - notifyRoom("/", "connect"); //notify main hall + notifyRoom("/", "gconnect"); //notify main hall break; case "pollclients": + { const curPage = clients[sid].page; socket.send(JSON.stringify({code:"pollclients", - sockIds: Object.keys(clients).filter(k => k != sid && - (clients[k].page == curPage || - // Consider that people playing are in Hall too: - (curPage == "/" && clients[k].page.indexOf("/game/") >= 0)) + sockIds: Object.keys(clients).filter(k => + k != sid && clients[k].page == curPage )})); break; + } + case "pollgamers": + { + const curPage = clients[sid].page; + socket.send(JSON.stringify({code:"pollgamers", + sockIds: Object.keys(clients).filter(k => + k != sid && clients[k].page.indexOf("/game/") >= 0 + )})); + break; + } case "pagechange": notifyRoom(clients[sid].page, "disconnect"); if (clients[sid].page.indexOf("/game/") >= 0) - notifyRoom("/", "disconnect"); + notifyRoom("/", "gdisconnect"); clients[sid].page = obj.page; notifyRoom(obj.page, "connect"); if (obj.page.indexOf("/game/") >= 0) - notifyRoom("/", "connect"); + notifyRoom("/", "gconnect"); break; case "askidentity": clients[obj.target].sock.send(JSON.stringify( @@ -140,11 +153,10 @@ module.exports = function(wss) { } break; case "newchat": - // WARNING: do not use query["page"], because the page may change - notifyRoom(clients[sid].page, "newchat", - {msg: obj.msg, name: obj.name}); + notifyRoom(clients[sid].page, "newchat", {chat:obj.chat}); break; // TODO: WebRTC instead in this case (most demanding?) + // --> At least do a "notifyRoom" case "newmove": clients[obj.target].sock.send(JSON.stringify( {code:"newmove", move:obj.move})); @@ -176,7 +188,7 @@ module.exports = function(wss) { delete clients[sid]; notifyRoom(page, "disconnect"); if (page.indexOf("/game/") >= 0) - notifyRoom("/", "disconnect"); //notify main hall + notifyRoom("/", "gdisconnect"); //notify main hall }); }); }