X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fviews%2FHall.vue;h=079584c02fedc155365842a29206ad31955e3c0e;hb=89021f181ac0689bbc785ce0ebd9a910e66352b0;hp=ae04b7d14046fecd630371b5f1369630846d8b18;hpb=8b152adaed809e759bb2507ade9d2273783c4a39;p=vchess.git diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index ae04b7d1..079584c0 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -7,28 +7,29 @@ main p(v-html="infoMessage") input#modalNewgame.modal(type="checkbox") div#newgameDiv(role="dialog" data-checkbox="modalNewgame") - .card(@keyup.enter="newChallenge()") + .card label#closeNewgame.modal-close(for="modalNewgame") - 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") - | {{ v.name }} - fieldset - label(for="cadence") {{ st.tr["Cadence"] }} * - div#predefinedCadences - button 3+2 - button 5+3 - button 15+5 - 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") - fieldset(v-if="st.user.id > 0 && newchallenge.to.length > 0") - label(for="inputFen") FEN - input#inputFen(type="text" v-model="newchallenge.fen") + 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") + | {{ v.name }} + fieldset + label(for="cadence") {{ st.tr["Cadence"] }} * + div#predefinedCadences + button 3+2 + button 5+3 + button 15+5 + 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") + fieldset(v-if="st.user.id > 0 && newchallenge.to.length > 0") + label(for="inputFen") FEN + input#inputFen(type="text" v-model="newchallenge.fen") button(@click="newChallenge()") {{ st.tr["Send challenge"] }} .row .col-sm-12 @@ -37,9 +38,9 @@ main .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 div .button-group - button(@click="setDisplay('c','live',$event)" class="active") + button#btnClive(@click="setDisplay('c','live',$event)" class="active") | {{ st.tr["Live challenges"] }} - button(@click="setDisplay('c','corr',$event)") + button#btnCcorr(@click="setDisplay('c','corr',$event)") | {{ st.tr["Correspondance challenges"] }} ChallengeList(v-show="cdisplay=='live'" :challenges="filterChallenges('live')" @click-challenge="clickChallenge") @@ -50,11 +51,7 @@ main #players p(v-for="sid in Object.keys(people)" v-if="!!people[sid].name") span {{ people[sid].name }} - // Check: anonymous players cannot send individual challenges or be challenged individually - button.player-action( - v-if="sid != st.user.sid && !!st.user.name && people[sid].id > 0" - @click="challOrWatch(sid)" - ) + button.player-action(v-if="sid!=st.user.sid || isGamer(sid)" @click="challOrWatch(sid)") | {{ getActionLabel(sid) }} p.anonymous @nonymous ({{ anonymousCount }}) #chat @@ -62,9 +59,9 @@ main .clearer div .button-group - button(@click="setDisplay('g','live',$event)" class="active") + button#btnGlive(@click="setDisplay('g','live',$event)" class="active") | {{ st.tr["Live games"] }} - button(@click="setDisplay('g','corr',$event)") + button#btnGcorr(@click="setDisplay('g','corr',$event)") | {{ st.tr["Correspondance games"] }} GameList(v-show="gdisplay=='live'" :games="filterGames('live')" @show-game="showGame") @@ -140,6 +137,17 @@ export default { "GET", {uid: this.st.user.id, excluded: true}, response => { + // Show corr tab with timeout, to let enough time for (socket) polling + setTimeout( + () => { + if (response.games.length > 0 && + this.games.length == response.games.length) + { + this.setDisplay('g', "corr"); + } + }, + 1000 + ); this.games = this.games.concat(response.games.map(g => { const type = this.classifyObject(g); const vname = this.getVname(g.vid); @@ -153,6 +161,16 @@ export default { "GET", {uid: this.st.user.id}, response => { + setTimeout( + () => { + if (response.challenges.length > 0 && + this.challenges.length == response.challenges.length) + { + this.setDisplay('c', "corr"); + } + }, + 1000 + ); // Gather all senders names, and then retrieve full identity: // (TODO [perf]: some might be online...) let names = {}; @@ -250,11 +268,17 @@ export default { }, setDisplay: function(letter, type, e) { this[letter + "display"] = type; - e.target.classList.add("active"); - if (!!e.target.previousElementSibling) - e.target.previousElementSibling.classList.remove("active"); + let elt = !!e + ? e.target + : document.getElementById("btn" + letter.toUpperCase() + type); + elt.classList.add("active"); + if (!!elt.previousElementSibling) + elt.previousElementSibling.classList.remove("active"); else - e.target.nextElementSibling.classList.remove("active"); + elt.nextElementSibling.classList.remove("active"); + }, + isGamer: function(sid) { + return this.people[sid].pages.some(p => p.indexOf("/game/") >= 0); }, getActionLabel: function(sid) { return this.people[sid].pages.some(p => p == "/") @@ -270,8 +294,14 @@ export default { } else { - // In some game, maybe playing maybe not - const gid = this.people[sid].page.match(/[a-zA-Z0-9]+$/)[0]; + // In some game, maybe playing maybe not: show a random one + let gids = []; + this.people[sid].pages.forEach(p => { + const matchGid = p.match(/[a-zA-Z0-9]+$/); + if (!!matchGid) + gids.push(matchGid[0]); + }); + const gid = gids[Math.floor(Math.random() * gids.length)]; this.showGame(this.games.find(g => g.id == gid)); } }, @@ -299,49 +329,58 @@ export default { // need to track "askIdentity" requests: let identityAsked = {}; data.sockIds.forEach(s => { + const page = s.page || "/"; if (s.sid != this.st.user.sid && !identityAsked[s.sid]) { identityAsked[s.sid] = true; - this.send("askidentity", {target:s.sid, page:s.page || "/"}); + this.send("askidentity", {target:s.sid, page:page}); } if (!this.people[s.sid]) - this.$set(this.people, s.sid, {id:0, name:"", pages:[s.page || "/"]}); - else if (!!s.page && this.people[s.sid].pages.indexOf(s.page) < 0) - this.people[s.sid].pages.push(s.page); + this.$set(this.people, s.sid, {id:0, name:"", pages:[page]}); + else if (this.people[s.sid].pages.indexOf(page) < 0) + this.people[s.sid].pages.push(page); if (!s.page) //peer is in Hall this.send("askchallenge", {target:s.sid}); else //peer is in Game - this.send("askgame", {target:s.sid, page:s.page}); + this.send("askgame", {target:s.sid, page:page}); }); break; } case "connect": case "gconnect": + { + const page = data.page || "/"; // NOTE: player could have been polled earlier, but might have logged in then // So it's a good idea to ask identity if he was anonymous. // But only ask game / challenge if currently disconnected. if (!this.people[data.from]) { - this.$set(this.people, data.from, {name:"", id:0, pages:[data.page]}); + this.$set(this.people, data.from, {name:"", id:0, pages:[page]}); if (data.code == "connect") this.send("askchallenge", {target:data.from}); else - this.send("askgame", {target:data.from, page:data.page}); + this.send("askgame", {target:data.from, page:page}); } else { // append page if not already in list - if (this.people[data.from].pages.indexOf(data.page) < 0) - this.people[data.from].pages.push(data.page); + if (this.people[data.from].pages.indexOf(page) < 0) + this.people[data.from].pages.push(page); } if (this.people[data.from].id == 0) { this.newConnect[data.from] = true; //for self multi-connects tests - this.send("askidentity", {target:data.from, page:data.page || "/"}); + this.send("askidentity", {target:data.from, page:page}); } break; + } case "disconnect": case "gdisconnect": + // If the user reloads the page twice very quickly (experienced with Firefox), + // the first reload won't have time to connect but will trigger a "close" event anyway. + // ==> Next check is required. + if (!this.people[data.from]) + return; // Disconnect means no more tmpIds: if (data.code == "disconnect") { @@ -458,6 +497,11 @@ export default { newChall.from = Object.assign({sid:chall.from}, fromValues); newChall.vname = this.getVname(newChall.vid); this.challenges.push(newChall); + // Adjust visual: + if (newChall.type == "live" && this.cdisplay == "corr" && !this.challenges.some(c => c.type == "corr")) + this.setDisplay('c', "live"); + else if (newChall.type == "corr" && this.cdisplay == "live" && !this.challenges.some(c => c.type == "live")) + this.setDisplay('c', "corr"); } break; } @@ -488,7 +532,14 @@ export default { newGame.vname = this.getVname(game.vid); if (!game.score) //if new game from Hall newGame.score = "*"; + newGame.rids = [game.rid]; + delete newGame["rid"]; this.games.push(newGame); + // Adjust visual: + if (newGame.type == "live" && this.gdisplay == "corr" && !this.games.some(g => g.type == "corr")) + this.setDisplay('g', "live"); + else if (newGame.type == "live" && this.gdisplay == "live" && !this.games.some(g => g.type == "live")) + this.setDisplay('g', "corr"); } else { @@ -498,6 +549,13 @@ export default { } break; } + case "result": + { + let g = this.games.find(g => g.id == data.gid); + if (!!g) + g.score = data.score; + break; + } case "startgame": { // New game just started: data contain all information