X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fviews%2FHall.vue;h=0e4d574b0539b61f5666691a2b87f6e69e247040;hb=beda3dd096a455ed337eaaeadc400712bf0f5c6d;hp=0e2c1c60b843cce879ee8a57c44d55af5b1aa0a9;hpb=57078452549f252460d45e91b84c7eea40dd3e9c;p=vchess.git diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index 0e2c1c60..0e4d574b 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -15,6 +15,8 @@ main span.variantName {{ curChallToAccept.vname }} span {{ curChallToAccept.cadence }} span {{ st.tr["with"] + " " + curChallToAccept.from.name }} + p.text-center(v-if="!!curChallToAccept.color") + | {{ st.tr["Your color:"] + " " + invColor(curChallToAccept.color) }} .diagram( v-if="!!curChallToAccept.fen" v-html="tchallDiag" @@ -88,7 +90,13 @@ main type="text" v-model="newchallenge.to" ) - fieldset(v-if="st.user.id > 0 && newchallenge.to.length > 0") + fieldset(v-show="st.user.id > 0 && newchallenge.to.length > 0") + label(for="selectColor") {{ st.tr["Color"] }} + select#selectColor(v-model="newchallenge.color") + option(value='') + option(value='w') {{ st.tr["White"] }} + option(value='b') {{ st.tr["Black"] }} + br input#inputFen( placeholder="FEN" @input="trySetNewchallDiag()" @@ -113,14 +121,15 @@ main v-for="sid in Object.keys(people)" v-if="!!people[sid].name" ) - span {{ people[sid].name }} + UserBio.user-bio(:uid="people[sid].id" :uname="people[sid].name") button.player-action( v-if="isGamer(sid)" @click="watchGame(sid)" ) | {{ st.tr["Observe"] }} button.player-action( - v-else-if="isFocusedOnHall(sid)" + v-else-if="st.user.sid != sid" + :class="{focused: isFocusedOnHall(sid)}" @click="challenge(sid)" ) | {{ st.tr["Challenge"] }} @@ -166,7 +175,7 @@ main button.tabbtn#btnClive(@click="setDisplay('c','live',$event)") | {{ st.tr["Live challenges"] }} button.tabbtn#btnCcorr(@click="setDisplay('c','corr',$event)") - | {{ st.tr["Correspondance challenges"] }} + | {{ st.tr["Correspondence challenges"] }} ChallengeList( v-show="cdisplay=='live'" :challenges="filterChallenges('live')" @@ -182,7 +191,7 @@ main button.tabbtn#btnGlive(@click="setDisplay('g','live',$event)") | {{ st.tr["Live games"] }} button.tabbtn#btnGcorr(@click="setDisplay('g','corr',$event)") - | {{ st.tr["Correspondance games"] }} + | {{ st.tr["Correspondence games"] }} GameList( v-show="gdisplay=='live'" :games="filterGames('live')" @@ -212,6 +221,7 @@ import params from "@/parameters"; import { getRandString, shuffle, randInt } from "@/utils/alea"; import { getDiagram } from "@/utils/printDiagram"; import Chat from "@/components/Chat.vue"; +import UserBio from "@/components/UserBio.vue"; import GameList from "@/components/GameList.vue"; import ChallengeList from "@/components/ChallengeList.vue"; import { GameStorage } from "@/utils/gameStorage"; @@ -220,6 +230,7 @@ export default { name: "my-hall", components: { Chat, + UserBio, GameList, ChallengeList }, @@ -238,12 +249,13 @@ export default { infoMessage: "", newchallenge: { fen: "", - vid: parseInt(localStorage.getItem("vid")) || 0, + vid: parseInt(localStorage.getItem("vid"), 10) || 0, to: "", //name of challenged player (if any) + color: '', cadence: localStorage.getItem("cadence") || "", randomness: // Warning: randomness can be 0, then !!randomness is false - (parseInt(localStorage.getItem("challRandomness"))+1 || 3) - 1, + (parseInt(localStorage.getItem("challRandomness"),10)+1 || 3) - 1, // VariantRules object, stored to not interfere with // diagrams of targetted challenges: V: null, @@ -253,7 +265,7 @@ export default { }, focus: true, tchallDiag: "", - curChallToAccept: {from: {}}, + curChallToAccept: { from: {} }, presetChalls: JSON.parse(localStorage.getItem("presetChalls") || "[]"), conn: null, connexionString: "", @@ -299,6 +311,28 @@ export default { const connectAndPoll = () => { this.send("connect"); this.send("pollclientsandgamers"); + if (!!this.$route.query["challenge"]) { + // Automatic challenge sending, for tournaments + this.loadNewchallVariant( + () => { + this.newchallenge = { + fen: "", + vid: + this.st.variants + .find(v => v.name == this.$route.query["variant"]) + .id, + to: this.$route.query["challenge"], + color: this.$route.query["color"] || '', + cadence: this.$route.query["cadence"], + // Tournament: no randomness (TODO: for now at least) + randomness: 0, + memorize: false + }; + this.issueNewChallenge(); + }, + this.$route.query["variant"] + ); + } }; // Initialize connection this.connexionString = @@ -452,9 +486,14 @@ export default { this.focus = false; this.send("losefocus"); }, + invColor: function(c) { + if (c == 'w') return this.st.tr["Black"]; + return this.tr.tr["White"]; + }, partialResetNewchallenge: function() { // Reset potential target and custom FEN: this.newchallenge.to = ""; + this.newchallenge.color = ''; this.newchallenge.fen = ""; this.newchallenge.diag = ""; this.newchallenge.memorize = false; @@ -497,6 +536,7 @@ export default { if (!this.newchallenge.to) { // Reset potential FEN + diagram this.newchallenge.fen = ""; + this.newchallenge.color = ''; this.newchallenge.diag = ""; } }, @@ -522,9 +562,12 @@ export default { }, // o: challenge or game classifyObject: function(o) { - // Consider imports as live games (TODO) - if (!!o.id && !!o.id.toString().match(/^i/)) return "live"; - return o.cadence.indexOf("d") === -1 ? "live" : "corr"; + // No imported games here + return ( + o.cadence.indexOf("d") >= 0 + ? "corr" + : (o.cadence.indexOf("/") >= 0 ? "simul" : "live") + ); }, setDisplay: function(letter, type, e) { this[letter + "display"] = type; @@ -814,6 +857,10 @@ export default { } break; } + case "entersimul": + // TODO: confirm box accept/refuse. + // If accept, update seat (array in this case) + break; case "game": // Individual request case "newgame": { const game = data.data; @@ -859,7 +906,7 @@ export default { this.startNewGame(gameInfo); else { this.infoMessage = - this.st.tr["New correspondance game:"] + " " + + this.st.tr["New correspondence game:"] + " " + "" + "#/game/" + gameInfo.id + ""; document.getElementById("modalInfo").checked = true; @@ -950,8 +997,8 @@ export default { } } }, - loadNewchallVariant: async function(cb) { - const vname = this.getVname(this.newchallenge.vid); + loadNewchallVariant: async function(cb, vname) { + vname = vname || this.getVname(this.newchallenge.vid); await import("@/variants/" + vname + ".js") .then((vModule) => { window.V = vModule[vname + "Rules"]; @@ -974,8 +1021,8 @@ export default { ) { const parsedFen = V.ParseFen(this.newchallenge.fen); this.newchallenge.diag = getDiagram({ - position: parsedFen.position, - orientation: parsedFen.turn + position: parsedFen.position + //,orientation: parsedFen.turn }); } else this.newchallenge.diag = ""; }, @@ -995,7 +1042,9 @@ export default { if (!this.newchallenge.vid) error = this.st.tr["Please select a variant"]; else if (ctype == "corr" && this.st.user.id <= 0) - error = this.st.tr["Please log in to play correspondance games"]; + error = this.st.tr["Please log in to play correspondence games"]; + else if (!this.newchallenge.to && !!this.newchallenge.color) + error = this.st.tr["Color option only for targeted challenge"]; else if (!!this.newchallenge.to) { if (this.newchallenge.to == this.st.user.name) error = this.st.tr["Self-challenge is forbidden"]; @@ -1005,8 +1054,14 @@ export default { ) { error = this.newchallenge.to + " " + this.st.tr["is not online"]; } + if ( + !!this.newchallenge.color && + !['w', 'b'].includes(this.newchallenge.color) + ) { + error = this.st.tr["Wrong color"]; + } } - if (error) { + if (!!error) { alert(error); return; } @@ -1018,13 +1073,18 @@ export default { } // NOTE: "from" information is not required here let chall = Object.assign({}, this.newchallenge); - // Add only if not already issued (not counting target or FEN): + // Add only if not already issued (not counting FEN): if (this.challenges.some(c => ( c.from.sid == this.st.user.sid || (c.from.id > 0 && c.from.id == this.st.user.id) ) && + ( + (!c.to && !chall.to) || + c.to == chall.to + ) + && c.vid == chall.vid && c.cadence == chall.cadence && c.randomness == chall.randomness @@ -1103,7 +1163,7 @@ export default { // Live challenges have a random ID finishAddChallenge(null); } else { - // Correspondance game: send challenge to server + // Correspondence game: send challenge to server ajax( "/challenges", "POST", @@ -1165,25 +1225,33 @@ export default { alert(this.st.tr["Please log in to accept corr challenges"]); return; } - c.accepted = true; - await import("@/variants/" + c.vname + ".js") - .then((vModule) => { - window.V = vModule[c.vname + "Rules"]; - if (!!c.to) { - // c.to == this.st.user.name (connected) - if (!!c.fen) { - const parsedFen = V.ParseFen(c.fen); - c.mycolor = V.GetOppCol(parsedFen.turn); - this.tchallDiag = getDiagram({ - position: parsedFen.position, - orientation: c.mycolor - }); + if (c.type == "simul") { + // Just notify that I wanna enter the simultaneous game(s) + // TODO: dans défi, indiquer si positions aleatoires, si tjours blancs ou noirs + // --> /w30 ou b1h ou juste 30 (random, sans préfixe). + // => message "entersimul" to c.from + return; + } + else { + c.accepted = true; + await import("@/variants/" + c.vname + ".js") + .then((vModule) => { + window.V = vModule[c.vname + "Rules"]; + if (!!c.to) { + // c.to == this.st.user.name (connected) + if (!!c.fen) { + const parsedFen = V.ParseFen(c.fen); + this.tchallDiag = getDiagram({ + position: parsedFen.position, + orientation: parsedFen.turn + }); + } + this.curChallToAccept = c; + document.getElementById("modalAccept").checked = true; } - this.curChallToAccept = c; - document.getElementById("modalAccept").checked = true; - } - else this.finishProcessingChallenge(c); - }); + else this.finishProcessingChallenge(c); + }); + } } else { // My challenge @@ -1194,17 +1262,24 @@ export default { { data: { id: c.id } } ); } + else if (c.type == "simul" && !!c.seat && Array.isArray(c.seat)) + // TODO: if some players entered, start game + this.launchSimultaneous(c); this.send("deletechallenge_s", { data: { cid: c.id } }); } // In all cases, the challenge is consumed: ArrayFun.remove(this.challenges, ch => ch.id == c.id); }, // NOTE: when launching game, the challenge is already being deleted + // TODO: adapt for simultaneous games, or just write a new function (better) + launchSimultaneous: function(c) { + // TODO + }, launchGame: function(c) { // White player index 0, black player index 1: let players = - !!c.mycolor - ? (c.mycolor == "w" ? [c.seat, c.from] : [c.from, c.seat]) + !!c.color + ? (c.color == "w" ? [c.from, c.seat] : [c.seat, c.from]) : shuffle([c.from, c.seat]); players.forEach(p => { if (!!p["tmpIds"]) delete p["tmpIds"]; @@ -1364,6 +1439,8 @@ div#peopleWrap > .card button.player-action margin-left: 32px + &.focused + background-color: #E6D271 .somethingnew background-color: #90C4EC !important @@ -1400,6 +1477,9 @@ button.refuseBtn #div2, #div3 margin-top: 0 +.user-bio + display: inline + tr > td &.random-0 background-color: #FF5733