From fb54f098a565034c09c111f1141d2c60073b4a61 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Thu, 31 Jan 2019 22:21:10 +0100
Subject: [PATCH] Advance on styling

---
 client/src/App.vue                |  45 +++++-
 client/src/stylesheets/index.sass |  43 ------
 client/src/translations/en.js     |   9 +-
 client/src/views/Home.vue         | 240 +++++++++++++++---------------
 client/src/views/Variants.vue     |  36 ++---
 5 files changed, 186 insertions(+), 187 deletions(-)

diff --git a/client/src/App.vue b/client/src/App.vue
index dd45b343..2699453b 100644
--- a/client/src/App.vue
+++ b/client/src/App.vue
@@ -39,11 +39,10 @@
                 | {{ !st.user.id ? "Login" : "Update" }}
               .clickable(onClick="doClick('modalSettings')")
                 | {{ st.tr["Settings"] }}
-              .clickable(onClick="doClick('modalLang')")
+              .clickable#flagContainer(onClick="doClick('modalLang')")
                 img(v-if="!!st.lang"
                   :src="require(`@/assets/images/flags/${st.lang}.svg`)")
-    .row
-      router-view
+    router-view
     .row
       .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
         footer
@@ -87,6 +86,39 @@ export default {
   @media screen and (max-width: 767px)
     padding: 0
 
+.row > div
+  padding: 0
+
+.nopadding
+  padding: 0
+
+#modalWelcome
+  max-width: 767px
+  @media screen and (max-width: 767px)
+    max-width: 100vw
+  img
+    width: 75%
+    @media screen and (max-width: 767px)
+      width: 100%
+      max-width: 552px
+  ul
+    list-style-type: none
+  // TODO: bad practice, shouldn't use table to align things...
+  table.list-table
+    width: 300px
+    margin: 0 auto
+    border: 0
+    tbody
+      border: 0
+      tr
+        border: 0
+        margin: 0
+        padding: 0
+        td
+          padding: 0
+          text-align: left
+          border: 0
+
 header
   width: 100%
   display: flex
@@ -102,6 +134,7 @@ header
 
 nav
   width: 100%
+  margin: 0
   padding: 0
   & > #menuBar
     width: 100%
@@ -125,10 +158,12 @@ nav
       justify-content: flex-end
       & > div
         display: inline-block
+        &#flagContainer
+          display: inline-flex
         & > img
           padding: 0
-          width: 30px
-          height: 30px
+          width: 36px
+          height: 27px
 
 // TODO: drawer, until 600px wide OK (seemingly)
 // After, zone where left and right just go on top of another
diff --git a/client/src/stylesheets/index.sass b/client/src/stylesheets/index.sass
index 5f76e00b..dcf75b3c 100644
--- a/client/src/stylesheets/index.sass
+++ b/client/src/stylesheets/index.sass
@@ -52,46 +52,3 @@
     @media screen and (max-width: 767px)
       padding-top: 8px
 
-// TODO: box-shadow or box-sizing ? https://stackoverflow.com/a/13517809
-.variant
-  box-sizing: border-box
-  border: 1px solid brown
-  background-color: lightyellow
-  &:hover
-    background-color: yellow
-  a
-    color: #663300
-    text-decoration: none
-  .boxtitle
-    font-weight: bold
-    margin-bottom: 0
-  .description
-    @media screen and (max-width: 767px)
-      margin-top: 0
-
-#welcome
-  max-width: 767px
-  @media screen and (max-width: 767px)
-    max-width: 100vw
-  img
-    width: 75%
-    @media screen and (max-width: 767px)
-      width: 100%
-      max-width: 552px
-  ul
-    list-style-type: none
-  // TODO: bad practice, shouldn't use table to align things...
-  table.list-table
-    width: 300px
-    margin: 0 auto
-    border: 0
-    tbody
-      border: 0
-      tr
-        border: 0
-        margin: 0
-        padding: 0
-        td
-          padding: 0
-          text-align: left
-          border: 0
diff --git a/client/src/translations/en.js b/client/src/translations/en.js
index 6f7cab10..28c83dd3 100644
--- a/client/src/translations/en.js
+++ b/client/src/translations/en.js
@@ -1,7 +1,13 @@
 export const translations =
 {
-  "Language": "Language",
+  "Home": "Home",
+  "Variants": "Variants",
+  "My games": "My games",
+  "Problems": "Problems",
   "Contact form": "Contact form",
+  "Source code": "Source code",
+
+  "Language": "Language",
   "Email": "Email",
   "Subject": "Subject",
   "Content": "Content",
@@ -38,7 +44,6 @@ export const translations =
   "Waiting for opponent...": "Waiting for opponent...",
   "Rules": "Rules",
   "Play": "Play",
-  "Problems": "Problems",
   "White win": "White win",
   "Black win": "Black win",
   "Draw": "Draw",
diff --git a/client/src/views/Home.vue b/client/src/views/Home.vue
index f0f6a5c7..3a7e383f 100644
--- a/client/src/views/Home.vue
+++ b/client/src/views/Home.vue
@@ -74,25 +74,25 @@ export default {
     GameList,
     ChallengeList,
   },
-	data: function () {
-		return {
+  data: function () {
+    return {
       st: store.state,
-			gdisplay: "live",
-			liveGames: [],
-			corrGames: [],
-			players: [], //online players
-			challenges: [], //live challenges
-			willPlay: [], //IDs of challenges in which I decide to play (>= 3 players)
-			newgameInfo: {
-				fen: "",
-				vid: 0,
-				nbPlayers: 0,
-				players: [{id:0,name:""},{id:0,name:""},{id:0,name:""}],
-				mainTime: 0,
-				increment: 0,
-			},
-		};
-	},
+      gdisplay: "live",
+      liveGames: [],
+      corrGames: [],
+      players: [], //online players
+      challenges: [], //live challenges
+      willPlay: [], //IDs of challenges in which I decide to play (>= 3 players)
+      newgameInfo: {
+        fen: "",
+        vid: 0,
+        nbPlayers: 0,
+        players: [{id:0,name:""},{id:0,name:""},{id:0,name:""}],
+        mainTime: 0,
+        increment: 0,
+      },
+    };
+  },
   watch: {
     "st.conn": function() {
       // TODO: ask server for current corr games (all but mines: names, ID, time control)
@@ -135,113 +135,113 @@ export default {
       this.st.conn.onclose = socketCloseListener;
     },
   },
-	methods: {
-		showGame: function(game) {
+  methods: {
+    showGame: function(game) {
       // NOTE: if we are an observer, the game will be found in main games list
       // (sent by connected remote players)
       this.$router.push("/" + game.id)
-		},
-		challenge: function(player) {
-			this.st.conn.send(JSON.stringify({code:"sendchallenge", oppid:p.id,
-				user:{name:this.st.user.name,id:this.st.user.id}}));
-		},
-		clickChallenge: function(challenge) {
-			const index = this.challenges.findIndex(c => c.id == challenge.id);
-			const toIdx = challenge.to.findIndex(p => p.id == user.id);
-			const me = {name:user.name,id:user.id};
-			if (toIdx >= 0)
-			{
-				// It's a multiplayer challenge I accepted: withdraw
-				this.st.conn.send(JSON.stringify({code:"withdrawchallenge",
-					cid:challenge.id, user:me}));
-				this.challenges.to.splice(toIdx, 1);
-			}
-			else if (challenge.from.id == user.id) //it's my challenge: cancel it
-			{
-				this.st.conn.send(JSON.stringify({code:"cancelchallenge", cid:challenge.id}));
-				this.challenges.splice(index, 1);
-			}
-			else //accept a challenge
-			{
-				this.st.conn.send(JSON.stringify({code:"acceptchallenge",
-					cid:challenge.id, user:me}));
-				this.challenges[index].to.push(me);
-			}
-			// TODO: accepter un challenge peut lancer une partie, il
-			// faut alors supprimer challenge + creer partie + la retourner et l'ajouter ici
-			// autres actions:
-			// supprime mon défi
-			// accepte un défi
-			// annule l'acceptation d'un défi (si >= 3 joueurs)
-			//
-			// si pas le mien et FEN speciale :: (charger code variante et)
-			// montrer diagramme + couleur (orienté)
-		},
-		// user: last person to accept the challenge
-		newGameLive: function(chall, user) {
-			const fen = chall.fen || V.GenRandInitFen();
-			const game = {}; //TODO: fen, players, time ...
-			//setStorage(game); //TODO
-			game.players.forEach(p => {
-				this.conn.send(
-					JSON.stringify({code:"newgame", oppid:p.id, game:game}));
-			});
-			if (this.settings.sound >= 1)
-				new Audio("/sounds/newgame.mp3").play().catch(err => {});
-		},
-		newGame: function() {
-			const afterRulesAreLoaded = () => {
-				// NOTE: side-effect = set FEN
-				// TODO: (to avoid any cheating option) separate the GenRandInitFen() functions
-				// in separate files, load on server and generate FEN on server.
-				const error = checkChallenge(this.newgameInfo, vname);
-				if (!!error)
-					return alert(error);
-				// Possible (server) error if filled player does not exist
-				ajax(
-					"/challenges/" + this.newgameInfo.vid,
-					"POST",
-					this.newgameInfo,
-					response => {
-						const chall = Object.assign({},
-							this.newgameInfo,
-							{
-								id: response.cid,
-								uid: user.id,
-								added: Date.now(),
-								vname: vname,
-							});
-						this.challenges.push(chall);
-					}
-				);
+    },
+    challenge: function(player) {
+      this.st.conn.send(JSON.stringify({code:"sendchallenge", oppid:p.id,
+        user:{name:this.st.user.name,id:this.st.user.id}}));
+    },
+    clickChallenge: function(challenge) {
+      const index = this.challenges.findIndex(c => c.id == challenge.id);
+      const toIdx = challenge.to.findIndex(p => p.id == user.id);
+      const me = {name:user.name,id:user.id};
+      if (toIdx >= 0)
+      {
+        // It's a multiplayer challenge I accepted: withdraw
+        this.st.conn.send(JSON.stringify({code:"withdrawchallenge",
+          cid:challenge.id, user:me}));
+        this.challenges.to.splice(toIdx, 1);
+      }
+      else if (challenge.from.id == user.id) //it's my challenge: cancel it
+      {
+        this.st.conn.send(JSON.stringify({code:"cancelchallenge", cid:challenge.id}));
+        this.challenges.splice(index, 1);
+      }
+      else //accept a challenge
+      {
+        this.st.conn.send(JSON.stringify({code:"acceptchallenge",
+          cid:challenge.id, user:me}));
+        this.challenges[index].to.push(me);
+      }
+      // TODO: accepter un challenge peut lancer une partie, il
+      // faut alors supprimer challenge + creer partie + la retourner et l'ajouter ici
+      // autres actions:
+      // supprime mon défi
+      // accepte un défi
+      // annule l'acceptation d'un défi (si >= 3 joueurs)
+      //
+      // si pas le mien et FEN speciale :: (charger code variante et)
+      // montrer diagramme + couleur (orienté)
+    },
+    // user: last person to accept the challenge
+    newGameLive: function(chall, user) {
+      const fen = chall.fen || V.GenRandInitFen();
+      const game = {}; //TODO: fen, players, time ...
+      //setStorage(game); //TODO
+      game.players.forEach(p => {
+        this.conn.send(
+          JSON.stringify({code:"newgame", oppid:p.id, game:game}));
+      });
+      if (this.settings.sound >= 1)
+        new Audio("/sounds/newgame.mp3").play().catch(err => {});
+    },
+    newGame: function() {
+      const afterRulesAreLoaded = () => {
+        // NOTE: side-effect = set FEN
+        // TODO: (to avoid any cheating option) separate the GenRandInitFen() functions
+        // in separate files, load on server and generate FEN on server.
+        const error = checkChallenge(this.newgameInfo, vname);
+        if (!!error)
+          return alert(error);
+        // Possible (server) error if filled player does not exist
+        ajax(
+          "/challenges/" + this.newgameInfo.vid,
+          "POST",
+          this.newgameInfo,
+          response => {
+            const chall = Object.assign({},
+              this.newgameInfo,
+              {
+                id: response.cid,
+                uid: user.id,
+                added: Date.now(),
+                vname: vname,
+              });
+            this.challenges.push(chall);
+          }
+        );
         // TODO: else, if live game: send infos (socket), and...
-			};
-			const idxInVariants =
-				variantArray.findIndex(v => v.id == this.newgameInfo.vid);
-			const vname = variantArray[idxInVariants].name;
-			const scriptId = vname + "RulesScript";
-			if (!document.getElementById(scriptId))
-			{
-				// Load variant rules (only once)
-				var script = document.createElement("script");
-				script.id = scriptId;
-				script.onload = afterRulesAreLoaded;
-				//script.addEventListener ("load", afterRulesAreLoaded, false);
-				script.src = "/javascripts/variants/" + vname + ".js";
-				document.body.appendChild(script);
-			}
-			else
-				afterRulesAreLoaded();
-		},
-		possibleNbplayers: function(nbp) {
-			if (this.newgameInfo.vid == 0)
-				return false;
+      };
+      const idxInVariants =
+        variantArray.findIndex(v => v.id == this.newgameInfo.vid);
+      const vname = variantArray[idxInVariants].name;
+      const scriptId = vname + "RulesScript";
+      if (!document.getElementById(scriptId))
+      {
+        // Load variant rules (only once)
+        var script = document.createElement("script");
+        script.id = scriptId;
+        script.onload = afterRulesAreLoaded;
+        //script.addEventListener ("load", afterRulesAreLoaded, false);
+        script.src = "/javascripts/variants/" + vname + ".js";
+        document.body.appendChild(script);
+      }
+      else
+        afterRulesAreLoaded();
+    },
+    possibleNbplayers: function(nbp) {
+      if (this.newgameInfo.vid == 0)
+        return false;
       const variants = this.st.variants;
-			const idxInVariants =
-				variants.findIndex(v => v.id == this.newgameInfo.vid);
-			return NbPlayers[variants[idxInVariants].name].includes(nbp);
-		},
-	},
+      const idxInVariants =
+        variants.findIndex(v => v.id == this.newgameInfo.vid);
+      return NbPlayers[variants[idxInVariants].name].includes(nbp);
+    },
+  },
 };
 </script>
 
diff --git a/client/src/views/Variants.vue b/client/src/views/Variants.vue
index f5214296..bb345257 100644
--- a/client/src/views/Variants.vue
+++ b/client/src/views/Variants.vue
@@ -1,6 +1,6 @@
 <template lang="pug">
-div
-  .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
+.row
+  .nopadding.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
     label(for="prefixFilter") Type first letters...
     input#prefixFilter(v-model="curPrefix")
   .variant.col-sm-12.col-md-5.col-lg-4(
@@ -50,19 +50,21 @@ export default {
 </script>
 
 <!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="scss">
-h3 {
-  margin: 40px 0 0;
-}
-ul {
-  list-style-type: none;
-  padding: 0;
-}
-li {
-  display: inline-block;
-  margin: 0 10px;
-}
-a {
-  color: #42b983;
-}
+<style scoped lang="sass">
+// TODO: box-shadow or box-sizing ? https://stackoverflow.com/a/13517809
+.variant
+  box-sizing: border-box
+  border: 1px solid brown
+  background-color: lightyellow
+  &:hover
+    background-color: yellow
+  a
+    color: #663300
+    text-decoration: none
+  .boxtitle
+    font-weight: bold
+    margin-bottom: 0
+  .description
+    @media screen and (max-width: 767px)
+      margin-top: 0
 </style>
-- 
2.44.0