Allow smartphone users to drag and drop pieces
[vchess.git] / public / javascripts / components / game.js
index 2897b1c..14d3007 100644 (file)
@@ -240,38 +240,76 @@ Vue.component('my-game', {
                                );
                        }
                        elementArray.push(gameDiv);
-                       if (!!this.vr.reserve) //TODO: table, show counts for reserve pieces
-                               //<tr style="padding:0">
-                               //    <td style="padding:0;font-size:10px">3</td>
+                       if (!!this.vr.reserve)
                        {
-                               let reservePiecesArray = [];
+                               const shiftIdx = (this.mycolor=="w" ? 0 : 1);
+                               let myReservePiecesArray = [];
                                for (let i=0; i<VariantRules.RESERVE_PIECES.length; i++)
                                {
-                                       reservePiecesArray.push(h('img',
+                                       myReservePiecesArray.push(h('div',
+                                       {
+                                               'class': {'board':true, ['board'+sizeY]:true},
+                                               attrs: { id: this.getSquareId({x:sizeX+shiftIdx,y:i}) }
+                                       },
+                                       [
+                                               h('img',
                                                {
                                                        'class': {"piece":true},
                                                        attrs: {
                                                                "src": "/images/pieces/" +
                                                                        this.vr.getReservePpath(this.mycolor,i) + ".svg",
-                                                               id: this.getSquareId({x:sizeX,y:i}),
                                                        }
-                                               })
-                                       );
+                                               }),
+                                               h('sup',
+                                                       {style: { "padding-left":"40%"} },
+                                                       [ this.vr.reserve[this.mycolor][VariantRules.RESERVE_PIECES[i]] ]
+                                               )
+                                       ]));
+                               }
+                               let oppReservePiecesArray = [];
+                               const oppCol = this.vr.getOppCol(this.mycolor);
+                               for (let i=0; i<VariantRules.RESERVE_PIECES.length; i++)
+                               {
+                                       oppReservePiecesArray.push(h('div',
+                                       {
+                                               'class': {'board':true, ['board'+sizeY]:true},
+                                               attrs: { id: this.getSquareId({x:sizeX+(1-shiftIdx),y:i}) }
+                                       },
+                                       [
+                                               h('img',
+                                               {
+                                                       'class': {"piece":true},
+                                                       attrs: {
+                                                               "src": "/images/pieces/" +
+                                                                       this.vr.getReservePpath(oppCol,i) + ".svg",
+                                                       }
+                                               }),
+                                               h('sup',
+                                                       {style: { "padding-left":"40%"} },
+                                                       [ this.vr.reserve[oppCol][VariantRules.RESERVE_PIECES[i]] ]
+                                               )
+                                       ]));
                                }
-                               let reserve = h('div',
-                                       {'class':{'game':true}}, [
+                               let reserves = h('div',
+                                       {
+                                               'class':{'game':true},
+                                               style: {"margin-bottom": "20px"},
+                                       },
+                                       [
+                                               h('div',
+                                                       {
+                                                               'class': { 'row': true },
+                                                               style: {"margin-bottom": "15px"},
+                                                       },
+                                                       myReservePiecesArray
+                                               ),
                                                h('div',
                                                        { 'class': { 'row': true }},
-                                                       [
-                                                               h('div',
-                                                                       {'class':{'board':true, ['board'+sizeY]:true}},
-                                                                       reservePiecesArray
-                                                               )
-                                                       ]
+                                                       oppReservePiecesArray
                                                )
-                                       ],
+                                       ]
                                );
-                               elementArray.push(reserve);
+                               elementArray.push(reserves);
                        }
                        const eogMessage = this.getEndgameMessage(this.score);
                        const modalEog = [
@@ -375,9 +413,24 @@ Vue.component('my-game', {
                                                        {
                                                                attrs: { id: "pgn-game" },
                                                                on: { click: this.download },
-                                                               domProps: {
-                                                                       innerHTML: this.pgnTxt
-                                                               }
+                                                               domProps: { innerHTML: this.pgnTxt }
+                                                       }
+                                               )
+                                       ]
+                               )
+                       );
+               }
+               else if (this.mode != "idle")
+               {
+                       // Show current FEN (at least for debug)
+                       elementArray.push(
+                               h('div',
+                                       { attrs: { id: "fen-div" } },
+                                       [
+                                               h('p',
+                                                       {
+                                                               attrs: { id: "fen-string" },
+                                                               domProps: { innerHTML: this.vr.getBaseFen() }
                                                        }
                                                )
                                        ]
@@ -394,14 +447,14 @@ Vue.component('my-game', {
                                        "col-lg-6":true,
                                        "col-lg-offset-3":true,
                                },
-                               // NOTE: click = mousedown + mouseup --> what about smartphone?!
+                               // NOTE: click = mousedown + mouseup
                                on: {
                                        mousedown: this.mousedown,
                                        mousemove: this.mousemove,
                                        mouseup: this.mouseup,
-                                       touchdown: this.mousedown,
+                                       touchstart: this.mousedown,
                                        touchmove: this.mousemove,
-                                       touchup: this.mouseup,
+                                       touchend: this.mouseup,
                                },
                        },
                        elementArray
@@ -698,6 +751,19 @@ Vue.component('my-game', {
                },
                mousedown: function(e) {
                        e = e || window.event;
+                       let ingame = false;
+                       let elem = e.target;
+                       while (!ingame && elem !== null)
+                       {
+                               if (elem.classList.contains("game"))
+                               {
+                                       ingame = true;
+                                       break;
+                               }
+                               elem = elem.parentElement;
+                       }
+                       if (!ingame) //let default behavior (click on button...)
+                               return;
                        e.preventDefault(); //disable native drag & drop
                        if (!this.selectedPiece && e.target.classList.contains("piece"))
                        {
@@ -717,7 +783,8 @@ Vue.component('my-game', {
                                this.possibleMoves = this.mode!="idle" && this.vr.canIplay(this.mycolor,startSquare)
                                        ? this.vr.getPossibleMovesFrom(startSquare)
                                        : [];
-                               e.target.parentNode.appendChild(this.selectedPiece);
+                               // Next line add moving piece just after current image (required for Crazyhouse reserve)
+                               e.target.parentNode.insertBefore(this.selectedPiece, e.target.nextSibling);
                        }
                },
                mousemove: function(e) {
@@ -727,8 +794,11 @@ Vue.component('my-game', {
                        // If there is an active element, move it around
                        if (!!this.selectedPiece)
                        {
-                               this.selectedPiece.style.left = (e.clientX-this.start.x) + "px";
-                               this.selectedPiece.style.top = (e.clientY-this.start.y) + "px";
+                               const [offsetX,offsetY] = !!e.clientX
+                                       ? [e.clientX,e.clientY] //desktop browser
+                                       : [e.changedTouches[0].pageX, e.changedTouches[0].pageY]; //smartphone
+                               this.selectedPiece.style.left = (offsetX-this.start.x) + "px";
+                               this.selectedPiece.style.top = (offsetY-this.start.y) + "px";
                        }
                },
                mouseup: function(e) {
@@ -737,7 +807,10 @@ Vue.component('my-game', {
                        e = e || window.event;
                        // Read drop target (or parentElement, parentNode... if type == "img")
                        this.selectedPiece.style.zIndex = -3000; //HACK to find square from final coordinates
-                       let landing = document.elementFromPoint(e.clientX, e.clientY);
+                       const [offsetX,offsetY] = !!e.clientX
+                               ? [e.clientX,e.clientY]
+                               : [e.changedTouches[0].pageX, e.changedTouches[0].pageY];
+                       let landing = document.elementFromPoint(offsetX, offsetY);
                        this.selectedPiece.style.zIndex = 3000;
                        while (landing.tagName == "IMG") //classList.contains(piece) fails because of mark/highlight
                                landing = landing.parentNode;