From fd08ab2c5b8931bb8c95cf7e9f2f95122647f991 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Sat, 12 Jan 2019 15:21:00 +0100
Subject: [PATCH] Some advances. TODO: test board.js, and then game.js, and
 then implement room.js

---
 TODO                                      |  5 ++
 config/parameters.js.dist                 |  8 +--
 db/create.sql                             |  6 +-
 models/Game.js                            |  2 +-
 models/Problem.js                         |  2 +-
 public/javascripts/components/game.js     |  7 ++-
 public/javascripts/components/problems.js |  2 +-
 public/javascripts/index.js               |  4 +-
 public/javascripts/layout.js              |  1 +
 public/stylesheets/index.sass             |  7 ---
 public/stylesheets/layout.sass            |  7 +++
 reflexions                                |  5 ++
 routes/playing.js                         | 18 +-----
 utils/access.js                           | 67 +++++++++++------------
 utils/tokenGenerator.js                   | 25 ++++-----
 views/index.pug                           | 15 +++--
 views/userMenu.pug                        |  2 +-
 17 files changed, 89 insertions(+), 94 deletions(-)
 create mode 100644 reflexions

diff --git a/TODO b/TODO
index a4a9d5b9..7ea4813d 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,8 @@
+Sur index, introduction menu remplacé par "mes parties", montrant parties (corr) en cours toutes variantes confondues
+Dans variant page, "mes parties" peut toujours contenir corr + importées (deux onglets)
+En fin de partie (observée ou non), bouton "import game" en + de "download game" ==> directement dans indexedDB
+--> sursis de 7 jours pour les parties par correspondance, qui sont encore chargées depuis le serveur
+
 mat en 2 échiqueté : brnkr3/pppp1p1p/4ps2/8/2P2P2/P1qP4/2c1s1PP/R1K5
 (Bb3+ Kb1 Ba2#)
 
diff --git a/config/parameters.js.dist b/config/parameters.js.dist
index bb3cbe29..6f274dd3 100644
--- a/config/parameters.js.dist
+++ b/config/parameters.js.dist
@@ -1,4 +1,4 @@
-const Parameters =
+module.exports =
 {
 	// For mail sending. NOTE: *no trailing slash*
 	siteURL: "http://localhost:3000",
@@ -7,12 +7,12 @@ const Parameters =
 	env: process.env.NODE_ENV || 'development',
 
 	// Lifespan of a (login) cookie
-	cookieExpire: 183*24*3600*1000, //6 months in milliseconds
+	cookieExpire: 183*24*60*60*1000, //6 months in milliseconds
 
 	// Characters in a login token, and period of validity (in milliseconds)
 	token: {
 		length: 16,
-		expire: 1000*60*30, //30 minutes in milliseconds
+		expire: 30*60*1000, //30 minutes in milliseconds
 	},
 
 	// Email settings
@@ -26,5 +26,3 @@ const Parameters =
 		contact: "some_contact_email",
 	},
 };
-
-module.exports = Parameters;
diff --git a/db/create.sql b/db/create.sql
index e94b84a3..5f463bfc 100644
--- a/db/create.sql
+++ b/db/create.sql
@@ -59,11 +59,11 @@ create table Games (
 
 -- Store informations about players in a corr game
 create table Players (
+	gid integer,
 	uid integer,
 	color character,
-	gid integer,
-	foreign key (uid) references Users(id),
-	foreign key (gid) references Games(id)
+	foreign key (gid) references Games(id),
+	foreign key (uid) references Users(id)
 );
 
 create table Moves (
diff --git a/models/Game.js b/models/Game.js
index 2e57309f..d279514f 100644
--- a/models/Game.js
+++ b/models/Game.js
@@ -1 +1 @@
-//TODO: at least this model (maybe MoveModel ?!)
+//TODO:
diff --git a/models/Problem.js b/models/Problem.js
index 6184eafc..78586761 100644
--- a/models/Problem.js
+++ b/models/Problem.js
@@ -65,7 +65,7 @@ exports.fetchN = function(vname, uid, type, directionStr, lastDt, MaxNbProblems,
 			"WHERE vid = (SELECT id FROM Variants WHERE name = '" + vname + "') " +
 			"  AND added " + directionStr + " " + lastDt + " " + typeLine + " " +
 			"ORDER BY added " + (directionStr=="<" ? "DESC " : "") +
-			"LIMIT " + MaxNbProblems,
+			"LIMIT " + MaxNbProblems;
 		db.all(query, callback);
 	});
 }
diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js
index 39c12c0e..ca791257 100644
--- a/public/javascripts/components/game.js
+++ b/public/javascripts/components/game.js
@@ -4,7 +4,7 @@
 // Game logic on a variant page: 3 modes, analyze, computer or human
 Vue.component('my-game', {
 	// gameId: to find the game in storage (assumption: it exists)
-	props: ["gameId","mode","allowChat","allowMovelist"],
+	props: ["gameId","fen","mode","allowChat","allowMovelist"],
 	data: function() {
 		return {
 			// if oppid == "computer" then mode = "computer" (otherwise human)
@@ -24,6 +24,11 @@ Vue.component('my-game', {
 			vr: null, //VariantRules object, describing the game state + rules
 		};
 	},
+	watch: {
+		fen: function(newFen) {
+			this.vr = new VariantRules(newFen);
+		},
+	},
 	computed: {
 		showChat: function() {
 			return this.allowChat && this.mode=='human' && this.score != '*';
diff --git a/public/javascripts/components/problems.js b/public/javascripts/components/problems.js
index 9a14c709..53077049 100644
--- a/public/javascripts/components/problems.js
+++ b/public/javascripts/components/problems.js
@@ -38,7 +38,7 @@ Vue.component('my-problems', {
 						{{ curProb.instructions }}
 					</p>
 				</div>
-				<my-board :fen="curProb.fen" :analyze:"true" .................> //TODO: use my-game in analyze mode ?
+				<my-game :fen="curProb.fen" :mode="analyze" :allowMovelist="true">
 				</my-board>
 				<div id="solution-div" class="section-content">
 					<h3 class="clickable" @click="showSolution = !showSolution">
diff --git a/public/javascripts/index.js b/public/javascripts/index.js
index 3d35c456..bc4cd9e1 100644
--- a/public/javascripts/index.js
+++ b/public/javascripts/index.js
@@ -5,10 +5,10 @@ new Vue({
 		counts: {},
 		curPrefix: "",
 		conn: null,
+		display: "variants",
 	},
 	computed: {
 		sortedCounts: function () {
-			// TODO: priorité aux parties corr où c'est à nous de jouer !
 			const capitalizedPrefix = this.curPrefix.replace(/^\w/, c => c.toUpperCase());
 			const variantsCounts = variantArray
 			.filter( v => {
@@ -50,7 +50,7 @@ new Vue({
 		this.conn.onmessage = socketMessageListener;
 		this.conn.onclose = socketCloseListener;
 
-		// TODO:
+		// TODO: AJAX call get corr games (all variants)
 		// si dernier lastMove sur serveur n'est pas le mien et nextColor == moi, alors background orange
 		// ==> background orange si à moi de jouer par corr (sur main index)
 		// (helper: static fonction "GetNextCol()" dans base_rules.js)
diff --git a/public/javascripts/layout.js b/public/javascripts/layout.js
index 6d26b921..8cb79e0d 100644
--- a/public/javascripts/layout.js
+++ b/public/javascripts/layout.js
@@ -2,3 +2,4 @@
 //à l'arrivée sur le site : set peerID (un identifiant unique en tout cas...) si pas trouvé
 //
 //TODO: si une partie en cours dans storage, rediriger vers cette partie
+//(à condition que l'URL n'y corresponde pas déjà !)
diff --git a/public/stylesheets/index.sass b/public/stylesheets/index.sass
index d25ecb49..5f76e00b 100644
--- a/public/stylesheets/index.sass
+++ b/public/stylesheets/index.sass
@@ -40,13 +40,6 @@
       margin-top: 10px
       font-size: 1em
 
-#introductionMenu, #userMenu
-  float: right
-  @media screen and (max-width: 767px)
-    .info-container
-      p
-        margin-right: 5px
-
 #flagMenu
   float: right
   margin-right: 10px
diff --git a/public/stylesheets/layout.sass b/public/stylesheets/layout.sass
index eae4542a..161995db 100644
--- a/public/stylesheets/layout.sass
+++ b/public/stylesheets/layout.sass
@@ -35,6 +35,13 @@ body
       border-left: 1px solid var(--button-group-border-color)
       border-top: 0
 
+.right-menu
+  float: right
+  @media screen and (max-width: 767px)
+    .info-container
+      p
+        margin-right: 5px
+
 #settings, #contactForm
   max-width: 767px
   @media screen and (max-width: 767px)
diff --git a/reflexions b/reflexions
new file mode 100644
index 00000000..61c9932a
--- /dev/null
+++ b/reflexions
@@ -0,0 +1,5 @@
+tell opponent that I got the move, for him to start timer (and lose...)
+board2, board3, board4
+VariantRules2, 3 et 4 aussi
+fetch challenges and corr games from server at startup (room)
+but forbid anonymous to start corr games or accept challenges
diff --git a/routes/playing.js b/routes/playing.js
index 37592c9d..7af0a1bc 100644
--- a/routes/playing.js
+++ b/routes/playing.js
@@ -90,12 +90,8 @@ router.get("/gamesbyplayer", access.logged, access.ajax, (req,res) => {
 	});
 });
 
-// Load a rules page
-router.get("/rules/:variant([a-zA-Z0-9]+)", access.ajax, (req,res) => {
-	res.render("rules/" + req.params["variant"]);
-});
-
 // TODO: if newmove fail, takeback in GUI // TODO: check move structure
+// TODO: for corr games, move should contain an optional "message" field ("corr chat" !)
 router.post("/moves", access.logged, access.ajax, (req,res) => {
 	let gid = ObjectId(req.body.gid);
 	let fen = req.body.fen;
@@ -111,16 +107,4 @@ router.post("/moves", access.logged, access.ajax, (req,res) => {
 	});
 });
 
-//TODO: if new chat fails, do not show chat message locally
-router.post("/chats", access.logged, access.ajax, (req,res) => {
-	let gid = ObjectId(req.body.gid);
-	let uid = ObjectId(req.body.uid);
-	let msg = req.body.msg; //TODO: sanitize HTML (strip all tags...)
-	GameModel.addChat(gid, uid, msg, (err,game) => {
-		access.checkRequest(res, err, game, "Cannot find game", () => {
-			res.json({});
-		});
-	});
-});
-
 module.exports = router;
diff --git a/utils/access.js b/utils/access.js
index 1c82cb67..49d204c3 100644
--- a/utils/access.js
+++ b/utils/access.js
@@ -1,41 +1,36 @@
-var Access = {};
-
-// Prevent access to "users pages"
-Access.logged = function(req, res, next)
+module.exports =
 {
-	if (req.userId == 0)
-		return res.redirect("/");
-	next();
-};
+	// Prevent access to "users pages"
+	logged: function(req, res, next) {
+		if (req.userId == 0)
+			return res.redirect("/");
+		next();
+	},
 
-// Prevent access to "anonymous pages"
-Access.unlogged = function(req, res, next)
-{
-	if (req.userId > 0)
-		return res.redirect("/");
-	next();
-};
+	// Prevent access to "anonymous pages"
+	unlogged: function(req, res, next) {
+		if (req.userId > 0)
+			return res.redirect("/");
+		next();
+	},
 
-// Prevent direct access to AJAX results
-Access.ajax = function(req, res, next)
-{
-	if (!req.xhr)
-		return res.json({errmsg: "Unauthorized access"});
-	next();
-}
+	// Prevent direct access to AJAX results
+	ajax: function(req, res, next) {
+		if (!req.xhr)
+			return res.json({errmsg: "Unauthorized access"});
+		next();
+	},
 
-// Check for errors before callback (continue page loading). TODO: better name.
-Access.checkRequest = function(res, err, out, msg, cb)
-{
-	if (!!err)
-		return res.json({errmsg: err.errmsg || err.toString()});
-	if (!out
-		|| (Array.isArray(out) && out.length == 0)
-		|| (typeof out === "object" && Object.keys(out).length == 0))
-	{
-		return res.json({errmsg: msg});
-	}
-	cb();
+	// Check for errors before callback (continue page loading). TODO: better name.
+	checkRequest: function(res, err, out, msg, cb) {
+		if (!!err)
+			return res.json({errmsg: err.errmsg || err.toString()});
+		if (!out
+			|| (Array.isArray(out) && out.length == 0)
+			|| (typeof out === "object" && Object.keys(out).length == 0))
+		{
+			return res.json({errmsg: msg});
+		}
+		cb();
+	},
 }
-
-module.exports = Access;
diff --git a/utils/tokenGenerator.js b/utils/tokenGenerator.js
index 5578c2ec..1bc172cd 100644
--- a/utils/tokenGenerator.js
+++ b/utils/tokenGenerator.js
@@ -1,17 +1,14 @@
-var TokenGen = {};
-
-TokenGen.rand = function()
+module.exports =
 {
-	return Math.random().toString(36).substr(2); // remove `0.`
-};
+	rand: function() {
+		return Math.random().toString(36).substr(2); // remove `0.`
+	},
 
-TokenGen.generate = function(tlen)
-{
-	var res = "";
-	var nbRands = Math.ceil(tlen/10); //10 = min length of a rand() string
-	for (var i = 0; i < nbRands; i++)
-		res += TokenGen.rand();
-	return res.substr(0, tlen);
+	generate: function(tlen) {
+		var res = "";
+		var nbRands = Math.ceil(tlen/10); //10 = min length of a rand() string
+		for (var i = 0; i < nbRands; i++)
+			res += TokenGen.rand();
+		return res.substr(0, tlen);
+	},
 }
-
-module.exports = TokenGen;
diff --git a/views/index.pug b/views/index.pug
index 6b13a4e9..823b67c5 100644
--- a/views/index.pug
+++ b/views/index.pug
@@ -14,7 +14,7 @@ block content
 				include welcome/fr
 		.row
 			#header.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
-				#mainTitle
+				#mainTitle.clickable(onClick="doClick('modalWelcome')")
 					img(src="/images/index/unicorn.svg")
 					.info-container
 						p vchess.club
@@ -22,16 +22,21 @@ block content
 				#flagMenu.clickable(onClick="doClick('modalLang')")
 					img(src="/images/flags/" + lang + ".svg")
 				include userMenu
-				#introductionMenu.clickable(onClick="doClick('modalWelcome')")
+				#mygamesMenu.clickable.right-menu(v-show="display=='variants'" @click="display='games'")
 					.info-container
-						p Introduction
-		.row
+						p My games
+				#variantsMenu.clickable.right-menu(v-show="display=='games'" @click="display='variants'")
+					.info-container
+						p Variants
+		.row(v-show="display=='variants'")
 			.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")
-		.row
 			my-variant-summary(v-for="(v,idx) in sortedCounts"
 				v-bind:vobj="v" v-bind:index="idx" v-bind:key="v.name")
+		.row(v-show="display=='games'")
+			.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
+				p TODO: load from server, show timeControl + players + link "play"
 
 block javascripts
 	script.
diff --git a/views/userMenu.pug b/views/userMenu.pug
index f590a2ee..5a0b0743 100644
--- a/views/userMenu.pug
+++ b/views/userMenu.pug
@@ -1,4 +1,4 @@
-#userMenu.clickable(onClick="doClick('modalUser')")
+#userMenu.clickable.right-menu(onClick="doClick('modalUser')")
 	.info-container
 		if !user.email
 			p
-- 
2.44.0