From a5d5668613d9a3d04c9a4f8b69122d02b7322137 Mon Sep 17 00:00:00 2001 From: Benjamin Auder Date: Sat, 22 Dec 2018 15:37:48 +0100 Subject: [PATCH] Almost finished: just translations TODO --- public/javascripts/components/game.js | 99 +++++++------ .../javascripts/components/problemSummary.js | 6 +- public/javascripts/components/problems.js | 31 +++-- public/javascripts/components/rules.js | 6 +- public/javascripts/variant.js | 9 +- public/javascripts/variants/Crazyhouse.js | 9 +- public/stylesheets/index.sass | 4 - public/stylesheets/layout.sass | 6 + public/stylesheets/variant.sass | 131 +++++++++++------- routes/all.js | 62 ++++++--- views/index.pug | 8 +- views/variant.pug | 24 ++-- views/welcome/en.pug | 2 +- views/welcome/fr.pug | 2 +- 14 files changed, 246 insertions(+), 153 deletions(-) diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js index 773bc1f1..e2e908a0 100644 --- a/public/javascripts/components/game.js +++ b/public/javascripts/components/game.js @@ -40,7 +40,6 @@ Vue.component('my-game', { }, render(h) { const [sizeX,sizeY] = [V.size.x,V.size.y]; - const smallScreen = (window.innerWidth <= 420); // Precompute hints squares to facilitate rendering let hintSquares = doubleArray(sizeX, sizeY, false); this.possibleMoves.forEach(m => { hintSquares[m.end.x][m.end.y] = true; }); @@ -56,10 +55,11 @@ Vue.component('my-game', { attrs: { "aria-label": 'New online game' }, 'class': { "tooltip": true, + "play": true, "bottom": true, //display below "seek": this.seek, "playing": this.mode == "human", - "small": smallScreen, + "spaceright": true, }, }, [h('i', { 'class': { "material-icons": true } }, "accessibility")]) @@ -73,9 +73,10 @@ Vue.component('my-game', { attrs: { "aria-label": 'New game VS computer' }, 'class': { "tooltip":true, + "play": true, "bottom": true, "playing": this.mode == "computer", - "small": smallScreen, + "spaceright": true, }, }, [h('i', { 'class': { "material-icons": true } }, "computer")]) @@ -90,9 +91,10 @@ Vue.component('my-game', { attrs: { "aria-label": 'New IRL game' }, 'class': { "tooltip":true, + "play": true, "bottom": true, "playing": this.mode == "friend", - "small": smallScreen, + "spaceright": true, }, }, [h('i', { 'class': { "material-icons": true } }, "people")]) @@ -105,27 +107,33 @@ Vue.component('my-game', { ? parseFloat(window.getComputedStyle(square00).width.slice(0,-2)) : 0; const settingsBtnElt = document.getElementById("settingsBtn"); - const indicWidth = !!settingsBtnElt //-2 for border: - ? parseFloat(window.getComputedStyle(settingsBtnElt).height.slice(0,-2)) - 2 - : (smallScreen ? 31 : 37); + const settingsStyle = !!settingsBtnElt + ? window.getComputedStyle(settingsBtnElt) + : {width:"46px", height:"26px"}; + const [indicWidth,indicHeight] = //[44,24]; + [ + // NOTE: -2 for border + parseFloat(settingsStyle.width.slice(0,-2)) - 2, + parseFloat(settingsStyle.height.slice(0,-2)) - 2 + ]; + let aboveBoardElts = []; if (["chat","human"].includes(this.mode)) { const connectedIndic = h( 'div', { "class": { - "topindicator": true, "indic-left": true, "connected": this.oppConnected, "disconnected": !this.oppConnected, }, style: { "width": indicWidth + "px", - "height": indicWidth + "px", + "height": indicHeight + "px", }, } ); - elementArray.push(connectedIndic); + aboveBoardElts.push(connectedIndic); } if (this.mode == "chat") { @@ -139,15 +147,14 @@ Vue.component('my-game', { }, 'class': { "tooltip": true, - "topindicator": true, + "play": true, + "above-board": true, "indic-left": true, - "settings-btn": !smallScreen, - "settings-btn-small": smallScreen, }, }, [h('i', { 'class': { "material-icons": true } }, "chat")] ); - elementArray.push(chatButton); + aboveBoardElts.push(chatButton); } else if (this.mode == "computer") { @@ -161,32 +168,30 @@ Vue.component('my-game', { }, 'class': { "tooltip": true, - "topindicator": true, + "play": true, + "above-board": true, "indic-left": true, - "settings-btn": !smallScreen, - "settings-btn-small": smallScreen, }, }, [h('i', { 'class': { "material-icons": true } }, "clear")] ); - elementArray.push(clearButton); + aboveBoardElts.push(clearButton); } const turnIndic = h( 'div', { "class": { - "topindicator": true, "indic-right": true, "white-turn": this.vr.turn=="w", "black-turn": this.vr.turn=="b", }, style: { "width": indicWidth + "px", - "height": indicWidth + "px", + "height": indicHeight + "px", }, } ); - elementArray.push(turnIndic); + aboveBoardElts.push(turnIndic); const settingsBtn = h( 'button', { @@ -197,15 +202,20 @@ Vue.component('my-game', { }, 'class': { "tooltip": true, - "topindicator": true, + "play": true, + "above-board": true, "indic-right": true, - "settings-btn": !smallScreen, - "settings-btn-small": smallScreen, }, }, [h('i', { 'class': { "material-icons": true } }, "settings")] ); - elementArray.push(settingsBtn); + aboveBoardElts.push(settingsBtn); + elementArray.push( + h('div', + { "class": { "aboveboard-wrapper": true } }, + aboveBoardElts + ) + ); if (this.mode == "problem") { // Show problem instructions @@ -273,7 +283,10 @@ Vue.component('my-game', { (!["idle","chat"].includes(this.mode) || this.cursor==this.vr.moves.length); const gameDiv = h('div', { - 'class': { 'game': true }, + 'class': { + 'game': true, + 'clearer': true, + }, }, [_.range(sizeX).map(i => { let ci = (this.mycolor=='w' ? i : sizeX-i-1); @@ -354,8 +367,8 @@ Vue.component('my-game', { attrs: { "aria-label": 'Resign' }, 'class': { "tooltip":true, + "play": true, "bottom": true, - "small": smallScreen, }, }, [h('i', { 'class': { "material-icons": true } }, "flag")]) @@ -370,7 +383,7 @@ Vue.component('my-game', { on: { click: e => this.undo() }, attrs: { "aria-label": 'Undo' }, "class": { - "small": smallScreen, + "play": true, "spaceleft": true, }, }, @@ -379,7 +392,10 @@ Vue.component('my-game', { { on: { click: e => this.play() }, attrs: { "aria-label": 'Play' }, - "class": { "small": smallScreen }, + "class": { + "play": true, + "spaceleft": true, + }, }, [h('i', { 'class': { "material-icons": true } }, "fast_forward")]), ] @@ -394,7 +410,7 @@ Vue.component('my-game', { on: { click: this.undoInGame }, attrs: { "aria-label": 'Undo' }, "class": { - "small": smallScreen, + "play": true, "spaceleft": true, }, }, @@ -404,7 +420,10 @@ Vue.component('my-game', { { on: { click: () => { this.mycolor = this.vr.getOppCol(this.mycolor) } }, attrs: { "aria-label": 'Flip' }, - "class": { "small": smallScreen }, + "class": { + "play": true, + "spaceleft": true, + }, }, [h('i', { 'class': { "material-icons": true } }, "cached")] ), @@ -419,13 +438,13 @@ Vue.component('my-game', { { myReservePiecesArray.push(h('div', { - 'class': {'board':true, ['board'+sizeY]:true}, + 'class': {'board':true, ['board'+sizeY+'-reserve']:true}, attrs: { id: this.getSquareId({x:sizeX+shiftIdx,y:i}) } }, [ h('img', { - 'class': {"piece":true}, + 'class': {"piece":true, "reserve":true}, attrs: { "src": "/images/pieces/" + this.vr.getReservePpath(this.mycolor,i) + ".svg", @@ -443,13 +462,13 @@ Vue.component('my-game', { { oppReservePiecesArray.push(h('div', { - 'class': {'board':true, ['board'+sizeY]:true}, + 'class': {'board':true, ['board'+sizeY+'-reserve']:true}, attrs: { id: this.getSquareId({x:sizeX+(1-shiftIdx),y:i}) } }, [ h('img', { - 'class': {"piece":true}, + 'class': {"piece":true, "reserve":true}, attrs: { "src": "/images/pieces/" + this.vr.getReservePpath(oppCol,i) + ".svg", @@ -801,6 +820,7 @@ Vue.component('my-game', { ), h('button', { + attrs: { id: "sendChatBtn"}, on: { click: this.sendChat }, domProps: { innerHTML: "Send" }, } @@ -883,6 +903,7 @@ Vue.component('my-game', { [ h('h3', { + "class": { clickable: true }, domProps: { innerHTML: "Show solution" }, on: { click: this.toggleShowSolution }, } @@ -921,10 +942,10 @@ Vue.component('my-game', { { 'class': { "col-sm-12":true, - "col-md-8":true, - "col-md-offset-2":true, - "col-lg-6":true, - "col-lg-offset-3":true, + "col-md-10":true, + "col-md-offset-1":true, + "col-lg-8":true, + "col-lg-offset-2":true, }, // NOTE: click = mousedown + mouseup on: { diff --git a/public/javascripts/components/problemSummary.js b/public/javascripts/components/problemSummary.js index e7e1db7c..6b006cbb 100644 --- a/public/javascripts/components/problemSummary.js +++ b/public/javascripts/components/problemSummary.js @@ -2,11 +2,11 @@ Vue.component('my-problem-summary', { props: ['prob','preview'], template: ` -
-
+
-
+

{{ timestamp2date(prob.added) }}

diff --git a/public/javascripts/components/problems.js b/public/javascripts/components/problems.js index d9265a36..b67203a3 100644 --- a/public/javascripts/components/problems.js +++ b/public/javascripts/components/problems.js @@ -11,10 +11,21 @@ Vue.component('my-problems', { }; }, template: ` -
- - - +
+
+ + + +
@@ -46,9 +57,9 @@ Vue.component('my-problems', { -
- +
+
@@ -59,9 +70,6 @@ Vue.component('my-problems', { // Newest problem first return this.problems.sort((p1,p2) => { return p2.added - p1.added; }); }, - mailErrProblem: function() { - return "mailto:contact@vchess.club?subject=[" + variant + " problems] error"; - }, }, methods: { // Propagate "show problem" event to parent component (my-variant) @@ -69,7 +77,6 @@ Vue.component('my-problems', { this.$emit('show-problem', JSON.stringify(problem)); }, fetchProblems: function(direction) { - return; //TODO: re-activate after server side is implemented (see routes/all.js) if (this.problems.length == 0) return; //what could we do?! // Search for newest date (or oldest) @@ -96,6 +103,10 @@ Vue.component('my-problems', { previewNewProblem: function() { if (!V.IsGoodFen(this.newProblem.fen)) return alert("Bad FEN string"); + if (this.newProblem.instructions.length == 0) + return alert("Empty instructions"); + if (this.newProblem.solution.length == 0) + return alert("Empty solution"); this.newProblem.stage = "preview"; }, sendNewProblem: function() { diff --git a/public/javascripts/components/rules.js b/public/javascripts/components/rules.js index 829bf3b1..d8aaa0fc 100644 --- a/public/javascripts/components/rules.js +++ b/public/javascripts/components/rules.js @@ -3,7 +3,11 @@ Vue.component('my-rules', { data: function() { return { content: "" }; }, - template: `
`, + template: ` +
+
+
+ `, mounted: function() { // AJAX request to get rules content (plain text, HTML) ajax("/rules/" + variant, "GET", response => { diff --git a/public/javascripts/variant.js b/public/javascripts/variant.js index f77be329..d617c60a 100644 --- a/public/javascripts/variant.js +++ b/public/javascripts/variant.js @@ -1,23 +1,26 @@ new Vue({ el: "#variantPage", data: { - display: "game", //default: play! + display: "play", //default: play! problem: undefined, //current problem in view }, created: function() { const url = window.location.href; const hashPos = url.indexOf("#"); + console.log(hashPos + " " + url); if (hashPos >= 0) this.setDisplay(url.substr(hashPos+1)); }, methods: { showProblem: function(problemTxt) { this.problem = JSON.parse(problemTxt); - this.display = "game"; + this.display = "play"; }, setDisplay: function(elt) { this.display = elt; - document.getElementById("drawer-control").checked = false; + let menuToggle = document.getElementById("drawer-control"); + if (!!menuToggle) + menuToggle.checked = false; }, }, }); diff --git a/public/javascripts/variants/Crazyhouse.js b/public/javascripts/variants/Crazyhouse.js index 1fff1e91..f36bfcc4 100644 --- a/public/javascripts/variants/Crazyhouse.js +++ b/public/javascripts/variants/Crazyhouse.js @@ -11,10 +11,9 @@ class CrazyhouseRules extends ChessRules // 6) Check promoted array if (!fenParsed.promoted) return false; - fenpromoted = fenParsed.promoted; - if (fenpromoted == "-") + if (fenParsed.promoted == "-") return true; //no promoted piece on board - const squares = fenpromoted.split(","); + const squares = fenParsed.promoted.split(","); for (let square of squares) { const c = V.SquareToCoords(square); @@ -48,8 +47,8 @@ class CrazyhouseRules extends ChessRules getReserveFen() { - let counts = _.map(_.range(10), 0); - for (let i=0; i