From ccd4a2b74aecdd6e52960a9ed42acea3e40c9271 Mon Sep 17 00:00:00 2001 From: Benjamin Auder <benjamin.auder@somewhere> Date: Wed, 30 Jan 2019 02:43:47 +0100 Subject: [PATCH] Client now running. Toward fully 1-page (with filters for variants) --- .../{src => next_src}/components/TestComp.vue | 0 client/{src => next_src}/components/board.js | 0 .../components/challengeList.js | 0 client/{src => next_src}/components/chat.js | 0 client/{src => next_src}/components/game.js | 0 .../{src => next_src}/components/gameList.js | 0 .../{src => next_src}/components/moveList.js | 0 .../components/problemSummary.js | 0 .../components/upsertUser.js | 0 client/{src => next_src}/views/Game.vue | 0 client/{src => next_src}/views/Hall.vue | 0 client/{src => next_src}/views/MyGames.vue | 0 client/{src => next_src}/views/Problems.vue | 0 .../views/correspondance_merge_hall.js | 0 client/{src => next_src}/views/rules.js | 0 client/src/App.vue | 78 ++++----- client/src/components/ContactForm.vue | 2 +- client/src/components/Home.vue | 163 ------------------ client/src/main.js | 31 ++-- client/src/router.js | 32 ++-- client/src/utils/misc.js | 2 +- client/src/views/Home.vue | 117 ++++++++----- client/src/welcome/en.pug | 14 +- 23 files changed, 158 insertions(+), 281 deletions(-) rename client/{src => next_src}/components/TestComp.vue (100%) rename client/{src => next_src}/components/board.js (100%) rename client/{src => next_src}/components/challengeList.js (100%) rename client/{src => next_src}/components/chat.js (100%) rename client/{src => next_src}/components/game.js (100%) rename client/{src => next_src}/components/gameList.js (100%) rename client/{src => next_src}/components/moveList.js (100%) rename client/{src => next_src}/components/problemSummary.js (100%) rename client/{src => next_src}/components/upsertUser.js (100%) rename client/{src => next_src}/views/Game.vue (100%) rename client/{src => next_src}/views/Hall.vue (100%) rename client/{src => next_src}/views/MyGames.vue (100%) rename client/{src => next_src}/views/Problems.vue (100%) rename client/{src => next_src}/views/correspondance_merge_hall.js (100%) rename client/{src => next_src}/views/rules.js (100%) delete mode 100644 client/src/components/Home.vue diff --git a/client/src/components/TestComp.vue b/client/next_src/components/TestComp.vue similarity index 100% rename from client/src/components/TestComp.vue rename to client/next_src/components/TestComp.vue diff --git a/client/src/components/board.js b/client/next_src/components/board.js similarity index 100% rename from client/src/components/board.js rename to client/next_src/components/board.js diff --git a/client/src/components/challengeList.js b/client/next_src/components/challengeList.js similarity index 100% rename from client/src/components/challengeList.js rename to client/next_src/components/challengeList.js diff --git a/client/src/components/chat.js b/client/next_src/components/chat.js similarity index 100% rename from client/src/components/chat.js rename to client/next_src/components/chat.js diff --git a/client/src/components/game.js b/client/next_src/components/game.js similarity index 100% rename from client/src/components/game.js rename to client/next_src/components/game.js diff --git a/client/src/components/gameList.js b/client/next_src/components/gameList.js similarity index 100% rename from client/src/components/gameList.js rename to client/next_src/components/gameList.js diff --git a/client/src/components/moveList.js b/client/next_src/components/moveList.js similarity index 100% rename from client/src/components/moveList.js rename to client/next_src/components/moveList.js diff --git a/client/src/components/problemSummary.js b/client/next_src/components/problemSummary.js similarity index 100% rename from client/src/components/problemSummary.js rename to client/next_src/components/problemSummary.js diff --git a/client/src/components/upsertUser.js b/client/next_src/components/upsertUser.js similarity index 100% rename from client/src/components/upsertUser.js rename to client/next_src/components/upsertUser.js diff --git a/client/src/views/Game.vue b/client/next_src/views/Game.vue similarity index 100% rename from client/src/views/Game.vue rename to client/next_src/views/Game.vue diff --git a/client/src/views/Hall.vue b/client/next_src/views/Hall.vue similarity index 100% rename from client/src/views/Hall.vue rename to client/next_src/views/Hall.vue diff --git a/client/src/views/MyGames.vue b/client/next_src/views/MyGames.vue similarity index 100% rename from client/src/views/MyGames.vue rename to client/next_src/views/MyGames.vue diff --git a/client/src/views/Problems.vue b/client/next_src/views/Problems.vue similarity index 100% rename from client/src/views/Problems.vue rename to client/next_src/views/Problems.vue diff --git a/client/src/views/correspondance_merge_hall.js b/client/next_src/views/correspondance_merge_hall.js similarity index 100% rename from client/src/views/correspondance_merge_hall.js rename to client/next_src/views/correspondance_merge_hall.js diff --git a/client/src/views/rules.js b/client/next_src/views/rules.js similarity index 100% rename from client/src/views/rules.js rename to client/next_src/views/rules.js diff --git a/client/src/App.vue b/client/src/App.vue index 745dd799..7b3fb8e5 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -10,52 +10,46 @@ // Header (on index only) header .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 - img(src="./assets/images/index/unicorn.svg") - .info-container - p vchess.club - img(src="./assets/images/index/wildebeest.svg") + img(src="./assets/images/index/unicorn.svg") + .info-container + p vchess.club + img(src="./assets/images/index/wildebeest.svg") .row // Menu (top of page): // shared: Home + flags, userMenu - // variant: hall, problems, rules, my games + settings - nav - label.drawer-toggle(for="drawerControl") - input#drawerControl.drawer(type="checkbox") - #menuBar - label.drawer-close(for="drawerControl") - router-link(v-if="$route.path != '/'" to="/") - | Home - router-link(:href="getLink('/hall')") - | getLink function : suffix ==> /variant + suffix - =translations["Hall"] - router-link(href="#tabGames") - =translations["My games"] - router-link(href="#rules") - =translations["Rules"] - router-link(href="#problems") - =translations["Problems"] - #userMenu.clickable.right-menu(onClick="doClick('modalUser')") - .info-container - if !user.email - p - span Login - span.icon-user - else - p - span Update - span.icon-user - #flagMenu.clickable.right-menu(onClick="doClick('modalLang')") - img(src="/images/flags/" + lang + ".svg") - #settings.clickable(v-show="display!='index'" onClick="doClick('modalSettings')") - i(data-feather="settings") + // variant: hall, problems, rules, my games + settings + nav + label.drawer-toggle(for="drawerControl") + input#drawerControl.drawer(type="checkbox") + #menuBar + label.drawer-close(for="drawerControl") + router-link(to="/") + // select options all variants + filter possible (as in problems) + | Home + router-link(to="/myGames") + | {{ $tr["My games"] }} + router-link(to="/rules") + // Boxes OK for rules/Atomic/ ...etc + | {{ $tr["Rules"] }} + router-link(to="/problems") + | {{ $tr["Problems"] }} + #userMenu.clickable.right-menu(onClick="doClick('modalUser')") + .info-container + p + span {{ !$user.email ? "Login" : "Update" }} + span.icon-user + #flagMenu.clickable.right-menu(onClick="doClick('modalLang')") + img(src="/images/flags/" + lang + ".svg") + #settings.clickable(onClick="doClick('modalSettings')") + i(data-feather="settings") .row - router-view - .row - footer - .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2.text-center - a(href="https://github.com/yagu0/vchess") Source code - p.clickable(onClick="doClick('modalContact')") - = translations["Contact form"] + router-view + .row + footer + .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2.text-center + a(href="https://github.com/yagu0/vchess") Source code + p.clickable(onClick="doClick('modalContact')") + | {{ $tr["Contact form"] }} //my-game(:game-ref="gameRef" :mode="mode" :settings="settings" @game-over="archiveGame") //// TODO: add only the necessary icons to mini-css custom build //script(src="//unpkg.com/feather-icons") diff --git a/client/src/components/ContactForm.vue b/client/src/components/ContactForm.vue index cbfa622c..a521e6aa 100644 --- a/client/src/components/ContactForm.vue +++ b/client/src/components/ContactForm.vue @@ -24,7 +24,7 @@ div import { ajax } from "../utils/ajax"; export default { name: "ContactForm", - methods: { + methods: { // Note: not using Vue here, but would be possible trySendMessage: function() { let email = document.getElementById("userEmail"); diff --git a/client/src/components/Home.vue b/client/src/components/Home.vue deleted file mode 100644 index 8213a86a..00000000 --- a/client/src/components/Home.vue +++ /dev/null @@ -1,163 +0,0 @@ -<template> - <div class="hello"> - - - - -//Index: rename into Home - .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") - my-variant-summary(v-for="(v,idx) in sortedCounts" - - - - - - <h1>{{ msg }}</h1> - <p> - For a guide and recipes on how to configure / customize this project,<br> - check out the - <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>. - </p> - <h3>Installed CLI Plugins</h3> - <ul> - <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li> - </ul> - <h3>Essential Links</h3> - <ul> - <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li> - <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li> - <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li> - <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li> - <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li> - </ul> - <h3>Ecosystem</h3> - <ul> - <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li> - <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li> - <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li> - <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li> - <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li> - </ul> - </div> -</template> - -<script> -export default { - name: "HelloWorld", - props: { - msg: String - }, -// created: function() { -// alert("test"); -// }, - methods: { - - }, -}; -</script> - - - - - - - - -// Javascript for index page: mostly counters updating -new Vue({ - el: "#VueElement", - data: { - counts: {}, - curPrefix: "", - conn: null, - display: "variants", - }, - computed: { - sortedCounts: function () { - const capitalizedPrefix = this.curPrefix.replace(/^\w/, c => c.toUpperCase()); - const variantsCounts = variantArray - .filter( v => { - return v.name.startsWith(capitalizedPrefix); - }) - .map( v => { - return { - name: v.name, - desc: v.description, - count: this.counts[v.name] || 0, - }; - }); - return variantsCounts.sort((a,b) => { - if (a.count != b.count) - return b.count - a.count; - // Else, alphabetic ordering - return a.name.localeCompare(b.name); - }); - }, - }, - created: function() { - this.setDisplay(); - window.onhashchange = this.setDisplay; - - const url = socketUrl; - const sid = getRandString(); - this.conn = new WebSocket(url + "/?sid=" + sid + "&page=index"); - const socketMessageListener = msg => { - const data = JSON.parse(msg.data); - if (data.code == "counts") - this.counts = data.counts; - else if (data.code == "increase") - this.counts[data.vid]++; - else if (data.code == "decrease") - this.counts[data.vid]--; - }; - const socketCloseListener = () => { - this.conn = new WebSocket(url + "/?sid=" + sid + "&page=index"); - this.conn.addEventListener('message', socketMessageListener); - this.conn.addEventListener('close', socketCloseListener); - }; - this.conn.onmessage = socketMessageListener; - this.conn.onclose = socketCloseListener; - - // 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) - - }, - methods: { - setDisplay: function() { - if (!location.hash) - location.hash = "#variants"; //default - this.display = location.hash.substr(1); - }, - - }, -}); - - - - - - - - -<!-- 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> diff --git a/client/src/main.js b/client/src/main.js index c48985dd..66517004 100644 --- a/client/src/main.js +++ b/client/src/main.js @@ -12,28 +12,31 @@ new Vue({ render: function(h) { return h(App); }, - watch: { - $lang: async function(newLang) { - // Fill modalWelcome, and import translations from "./translations/$lang.js" - document.getElementById("modalWelcome").innerHTML = - require("raw-loader!pug-plain-loader!./modals/welcome/" + newLang + ".pug"); - const tModule = await import("./translations/" + newLang + ".js"); - Vue.prototype.$tr = tModule.translations; - //console.log(tModule.translations); - }, - $route: function(newRoute) { - console.log(this.$route.params); - //TODO: conn.send("enter", newRoute) - }, - }, +// watch: { +// $lang: async function(newLang) { +// // Fill modalWelcome, and import translations from "./translations/$lang.js" +// document.getElementById("modalWelcome").innerHTML = +// require("raw-loader!pug-plain-loader!./modals/welcome/" + newLang + ".pug"); +// const tModule = await import("./translations/" + newLang + ".js"); +// Vue.prototype.$tr = tModule.translations; +// //console.log(tModule.translations); +// }, +// $route: function(newRoute) { +// //console.log(this.$route.params); +// console.log("navig to " + newRoute); +// //TODO: conn.send("enter", newRoute) +// }, +// }, created: function() { const supportedLangs = ["en","es","fr"]; Vue.prototype.$lang = localStorage["lang"] || supportedLangs.includes(navigator.language) ? navigator.language : "en"; + Vue.prototype.$variants = []; //avoid runtime error ajax("/variants", "GET", res => { Vue.prototype.$variants = res.variantArray; }); Vue.prototype.$tr = {}; //to avoid a compiler error + Vue.prototype.$user = {}; //TODO: from storage // TODO: if there is a socket ID in localStorage, it means a live game was interrupted (and should resume) const myid = localStorage["myid"] || util.getRandString(); // NOTE: in this version, we don't say on which page we are, yet diff --git a/client/src/router.js b/client/src/router.js index 08bbf88b..7c2e2a68 100644 --- a/client/src/router.js +++ b/client/src/router.js @@ -15,22 +15,22 @@ export default new Router({ name: "home", component: Home, }, - { - path: "/about", - name: "about", - // route level code-splitting - // this generates a separate chunk (about.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: loadView('About'), - //function() { - // return import(/* webpackChunkName: "about" */ "./views/About.vue"); - //} - }, - { - path: "/test", - name: "test", - component: loadView("Test"), - }, +// { +// path: "/about", +// name: "about", +// // route level code-splitting +// // this generates a separate chunk (about.[hash].js) for this route +// // which is lazy-loaded when the route is visited. +// component: loadView('About'), +// //function() { +// // return import(/* webpackChunkName: "about" */ "./views/About.vue"); +// //} +// }, +// { +// path: "/test", +// name: "test", +// component: loadView("Test"), +// }, // TODO: gameRef, problemId: https://router.vuejs.org/guide/essentials/dynamic-matching.html ] }); diff --git a/client/src/utils/misc.js b/client/src/utils/misc.js index 4a2abf71..5a32ff9e 100644 --- a/client/src/utils/misc.js +++ b/client/src/utils/misc.js @@ -56,7 +56,7 @@ export const util = range: function(max) { return [...Array(max).keys()]; - } + }, // TODO: rename into "cookie" et supprimer les deux ci-dessous // Random (enough) string for socket and game IDs diff --git a/client/src/views/Home.vue b/client/src/views/Home.vue index 1eaa6b17..dfd39391 100644 --- a/client/src/views/Home.vue +++ b/client/src/views/Home.vue @@ -1,48 +1,87 @@ -<template> - <div class="home"> - <Home msg="Welcome to Your Vue.js Apppp"/> - </div> +<template lang="pug"> +div + .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( + v-for="(v,idx) in sortedCounts" + :class="{'col-md-offset-1': idx%2==0, 'col-lg-offset-2': idx%2==0}" + ) + a(:href="v.name") + h4.boxtitle.text-center {{ v.name }} + span.count-players / {{ v.count }} + p.description.text-center {{ $tr(v.desc) }} </template> <script> -// @ is an alias to /src -import HelloWorld from "@/components/HelloWorld.vue"; - export default { name: "home", - components: { - HelloWorld, - } -}; -</script> - -// Show a variant summary on index -Vue.component('my-variant-summary', { - props: ['vobj','index'], - template: ` - <div class="variant col-sm-12 col-md-5 col-lg-4" :id="vobj.name" - :class="{'col-md-offset-1': index%2==0, 'col-lg-offset-2': index%2==0}"> - <a :href="url"> - <h4 class="boxtitle text-center"> - {{ vobj.name }} - <span class="count-players"> - / {{ vobj.count }} - </span> - </h4> - <p class="description text-center"> - {{ translate(vobj.desc) }} - </p> - </a> - </div> - `, + data: function() { + return { + counts: {}, + curPrefix: "", + }; + }, computed: { - url: function() { - return "/" + this.vobj.name; + sortedCounts: function () { + const capitalizedPrefix = this.curPrefix.replace(/^\w/, c => c.toUpperCase()); + const variantsCounts = this.$variants + .filter( v => { + return v.name.startsWith(capitalizedPrefix); + }) + .map( v => { + return { + name: v.name, + desc: v.description, + count: this.counts[v.name] || 0, + }; + }); + return variantsCounts.sort((a,b) => { + if (a.count != b.count) + return b.count - a.count; + // Else, alphabetic ordering + return a.name.localeCompare(b.name); + }); }, }, - methods: { - translate: function(text) { - return translations[text]; - }, + created: function() { + const socketMessageListener = msg => { + const data = JSON.parse(msg.data); + if (data.code == "counts") + this.counts = data.counts; + else if (data.code == "increase") + this.counts[data.vid]++; + else if (data.code == "decrease") + this.counts[data.vid]--; + }; + const socketCloseListener = () => { + this.$conn.addEventListener('message', socketMessageListener); + this.$conn.addEventListener('close', socketCloseListener); + }; + this.$conn.onmessage = socketMessageListener; + this.$conn.onclose = socketCloseListener; + // 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) }, -}) +}; +</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> diff --git a/client/src/welcome/en.pug b/client/src/welcome/en.pug index c4ceabc4..27823f36 100644 --- a/client/src/welcome/en.pug +++ b/client/src/welcome/en.pug @@ -42,8 +42,12 @@ div(role="dialog") - var wikipediaUrl = "https://en.wikipedia.org/wiki/" + "List_of_chess_variants#/media/File:Hexagonal_chess.svg"; - p. - For informations about hundreds (if not thousands) of variants, you - can visit the excellent - #[a(href="https://www.chessvariants.com/") chessvariants] website. - p.smallfont Image credit: #[a(href=wikipediaUrl) Wikipedia] + p + | For informations about hundreds (if not thousands) of variants, you + | can visit the excellent + a(href="https://www.chessvariants.com/" _target="blank" rel="noopener") + | chessvariants + | website. + p.smallfont + | Image credit: + a(href=wikipediaUrl _target="blank" rel="noopener") Wikipedia -- 2.44.0