Step toward a one-page application
[vchess.git] / public / javascripts / components / game.js
index d370d66..fb4564f 100644 (file)
@@ -1,13 +1,17 @@
 // Game logic on a variant page: 3 modes, analyze, computer or human
 // TODO: envoyer juste "light move", sans FEN ni notation ...etc
 // TODO: if I'm an observer and player(s) disconnect/reconnect, how to find me ?
+//                     onClick :: ask full game to remote player, and register as an observer in game
+//                     (use gameId to communicate)
+//                     on landing on game :: if gameId not found locally, check remotely
+//                     ==> il manque un param dans game : "remoteId"
 Vue.component('my-game', {
        // gameId: to find the game in storage (assumption: it exists)
        // fen: to start from a FEN without identifiers (analyze mode)
        // subMode: "auto" (game comp vs comp) or "corr" (correspondance game),
        // or "examine" (after human game: TODO)
-       props: ["conn","gameId","fen","mode","subMode","allowChat","allowMovelist",
-               "queryHash","settings"],
+       props: ["conn","gameRef","fen","mode","subMode",
+               "allowChat","allowMovelist","settings"],
        data: function() {
                return {
                        // Web worker to play computer moves without freezing interface:
@@ -31,18 +35,13 @@ Vue.component('my-game', {
                };
        },
        watch: {
-               fen: function(newFen) {
+               fen: function() {
                        // (Security) No effect if a computer move is in progress:
                        if (this.mode == "computer" && this.lockCompThink)
                                return this.$emit("computer-think");
-                       this.newGameFromFen(newFen);
+                       this.newGameFromFen();
                },
-               gameId: function() {
-                       this.loadGame();
-               },
-               queryHash: function(newQhash) {
-                       // New query hash = "id=42"; get 42 as gameId
-                       this.gameId = parseInt(newQhash.substr(2));
+               gameRef: function() {
                        this.loadGame();
                },
        },
@@ -105,22 +104,34 @@ Vue.component('my-game', {
                        <div id="pgn-div" class="section-content">
                                <a id="download" href="#">
                                </a>
-                               <button id="downloadBtn" @click="download">
-                                       {{ translate("Download PGN") }}
-                               </button>
+                               <div class="button-group">
+                                       <button id="downloadBtn" @click="download">
+                                               {{ translate("Download PGN") }}
+                                       </button>
+                                       <button>Import game</button>
+                               </div>
                        </div>
                        <my-move-list v-if="showMoves" :moves="moves" :cursor="cursor" @goto-move="gotoMove">
                        </my-move-list>
                </div>
        `,
        created: function() {
-               if (!!this.gameId)
+               if (!!this.gameRef)
                        this.loadGame();
                else if (!!this.fen)
                {
-                       this.vr = new VariantRules(this.fen);
+                       this.vr = new V(this.fen);
                        this.fenStart = this.fen;
                }
+               // TODO: if I'm one of the players in game, then:
+               // Send ping to server (answer pong if opponent is connected)
+               if (true && !!this.conn && !!this.gameRef)
+               {
+                       this.conn.onopen = () => {
+                               this.conn.send(JSON.stringify({
+                                       code:"ping",oppid:this.oppid,gameId:this.gameRef.id}));
+                       };
+               }
                // TODO: also handle "draw accepted" (use opponents array?)
                // --> must give this info also when sending lastState...
                // and, if all players agree then OK draw (end game ...etc)
@@ -133,7 +144,7 @@ Vue.component('my-game', {
                                        this.play(data.move, variant.name!="Dark" ? "animate" : null);
                                        break;
                                case "pong": //received if we sent a ping (game still alive on our side)
-                                       if (this.gameId != data.gameId)
+                                       if (this.gameRef.id != data.gameId)
                                                break; //games IDs don't match: definitely over...
                                        this.oppConnected = true;
                                        // Send our "last state" informations to opponent(s)
@@ -142,7 +153,7 @@ Vue.component('my-game', {
                                                this.conn.send(JSON.stringify({
                                                        code: "lastate",
                                                        oppid: oid,
-                                                       gameId: this.gameId,
+                                                       gameId: this.gameRef.id,
                                                        lastMove: (L>0?this.vr.moves[L-1]:undefined),
                                                        movesCount: L,
                                                }));
@@ -151,7 +162,7 @@ Vue.component('my-game', {
                                // TODO: refactor this, because at 3 or 4 players we may have missed 2 or 3 moves (not just one)
                                case "lastate": //got opponent infos about last move
                                        L = this.vr.moves.length;
-                                       if (this.gameId != data.gameId)
+                                       if (this.gameRef.id != data.gameId)
                                                break; //games IDs don't match: nothing we can do...
                                        // OK, opponent still in game (which might be over)
                                        if (this.score != "*")
@@ -160,7 +171,7 @@ Vue.component('my-game', {
                                                this.conn.send(JSON.stringify({
                                                        code: "lastate",
                                                        oppid: data.oppid,
-                                                       gameId: this.gameId,
+                                                       gameId: this.gameRef.id,
                                                        score: this.score,
                                                }));
                                        }
@@ -172,7 +183,7 @@ Vue.component('my-game', {
                                                this.conn.send(JSON.stringify({
                                                        code: "lastate",
                                                        oppid: this.opponent.id,
-                                                       gameId: this.gameId,
+                                                       gameId: this.gameRef.id,
                                                        lastMove: this.vr.moves[L-1],
                                                        movesCount: L,
                                                }));
@@ -284,28 +295,31 @@ Vue.component('my-game', {
                        this.endGame(this.mycolor=="w"?"0-1":"1-0");
                },
                translate: translate,
-               newGameFromFen: function(fen) {
-                       this.vr = new VariantRules(fen);
+               newGameFromFen: function() {
+                       this.vr = new V(this.fen);
                        this.moves = [];
                        this.cursor = -1;
-                       this.fenStart = newFen;
+                       this.fenStart = this.fen;
                        this.score = "*";
                        if (this.mode == "analyze")
                        {
-                               this.mycolor = V.ParseFen(newFen).turn;
+                               this.mycolor = V.ParseFen(this.fen).turn;
                                this.orientation = this.mycolor;
                        }
                        else if (this.mode == "computer") //only other alternative (HH with gameId)
                        {
                                this.mycolor = (Math.random() < 0.5 ? "w" : "b");
                                this.orientation = this.mycolor;
-                               this.compWorker.postMessage(["init",newFen]);
+                               this.compWorker.postMessage(["init",this.fen]);
                                if (this.mycolor != "w" || this.subMode == "auto")
                                        this.playComputerMove();
                        }
                },
                loadGame: function() {
-                       const game = getGameFromStorage(this.gameId);
+                       // TODO: ask game to remote peer if this.remoteId is set
+                       // (or just if game not found locally)
+                       // NOTE: if it's a corr game, ask it from server
+                       const game = getGameFromStorage(this.gameRef.id, this.gameRef.uid); //uid may be blank
                        this.opponent.id = game.oppid; //opponent ID in case of running HH game
                        this.opponent.name = game.oppname; //maye be blank (if anonymous)
                        this.score = game.score;
@@ -476,7 +490,7 @@ Vue.component('my-game', {
                                if (this.cursor == this.moves.length)
                                        this.moves.push(move);
                                else
-                                       this.moves = this.moves.slice(0,this.cursor-1).concat([move]);
+                                       this.moves = this.moves.slice(0,this.cursor).concat([move]);
                        }
                        // Is opponent in check?
                        this.incheck = this.vr.getCheckSquares(this.vr.turn);
@@ -518,12 +532,12 @@ Vue.component('my-game', {
                                this.moves.pop();
                },
                gotoMove: function(index) {
-                       this.vr = new VariantRules(this.moves[index].fen);
+                       this.vr = new V(this.moves[index].fen);
                        this.cursor = index;
                        this.lastMove = this.moves[index];
                },
                gotoBegin: function() {
-                       this.vr = new VariantRules(this.fenStart);
+                       this.vr = new V(this.fenStart);
                        this.cursor = -1;
                        this.lastMove = null;
                },