From: Benjamin Auder Date: Sat, 19 Jan 2019 19:49:34 +0000 (+0100) Subject: Step toward a one-page application X-Git-Url: https://git.auder.net/?p=vchess.git;a=commitdiff_plain;h=b955c65b942d09d24b5c3bed0d755d4f2f8f71f1 Step toward a one-page application --- diff --git a/public/javascripts/layout.js b/public/javascripts/app.js similarity index 53% rename from public/javascripts/layout.js rename to public/javascripts/app.js index 8cb79e0d..28c086b9 100644 --- a/public/javascripts/layout.js +++ b/public/javascripts/app.js @@ -3,3 +3,15 @@ // //TODO: si une partie en cours dans storage, rediriger vers cette partie //(à condition que l'URL n'y corresponde pas déjà !) + + + created + script. + const variant = !{JSON.stringify(variant)}; + // Just 'V' because this variable is often used: + const V = eval(variant.name + "Rules"); + + +mounted: function() { + feather.replace(); +} diff --git a/routes/index.js b/routes/index.js index d510068e..547ae6d1 100644 --- a/routes/index.js +++ b/routes/index.js @@ -9,7 +9,6 @@ router.get('/', function(req, res, next) { if (!!err) return next(err); res.render('index', { - title: 'club', variantArray: variants, lang: selectLanguage(req, res), }); diff --git a/views/app.pug b/views/app.pug new file mode 100644 index 00000000..fb9853a3 --- /dev/null +++ b/views/app.pug @@ -0,0 +1,157 @@ +doctype html +html + + head + meta(charset="UTF-8") + title vchess - club + meta(name="viewport" content="width=device-width, initial-scale=1") + meta(name="msapplication-config" + content="/images/favicon/browserconfig.xml") + meta(name="theme-color" content="#ffffff") + link(rel="stylesheet" + href="//cdnjs.cloudflare.com/ajax/libs/mini.css/3.0.0/mini-default.min.css") + link(rel="stylesheet" + href="//fonts.googleapis.com/css?family=Open+Sans:400,700") + link(rel="apple-touch-icon" sizes="180x180" + href="/images/favicon/apple-touch-icon.png") + link(rel="icon" type="image/png" sizes="32x32" + href="/images/favicon/favicon-32x32.png") + link(rel="icon" type="image/png" sizes="16x16" + href="/images/favicon/favicon-16x16.png") + link(rel="manifest" href="/images/favicon/manifest.json") + link(rel="mask-icon" href="/images/favicon/safari-pinned-tab.svg" + color="#5bbad5") + link(rel="shortcut icon" href="/images/favicon/favicon.ico") + link(rel="stylesheet" href="/stylesheets/app.css") + + // TODO: on-demand components, do not load all at startup + body + - + var langName = { + "en": "English", + "es": "Español", + "fr": "Français", + }; + case lang + when "en" + include translations/en + include welcome/en + when "es" + include translations/es + include welcome/es + when "fr" + include translations/fr + include welcome/fr + include modals + main#VueElement + my-upsert-user + .container + // Header (on index only) + .row(v-show="display=='index'") + .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 + header + img(src="/images/index/unicorn.svg") + .info-container + p vchess.club + img(src="/images/index/wildebeest.svg") + // Menu (top of page) + .row + .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 + label.drawer-toggle(for="drawerControl") + input#drawerControl.drawer(type="checkbox") + #menuBar + label.drawer-close(for="drawerControl") + a.icon-link(href="/") + i(data-feather="home") + a(href="#room") + =translations["Hall"] + a(href="#tabGames") + =translations["My games"] + a(href="#rules") + =translations["Rules"] + a(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") + #mainTitle.clickable(onClick="doClick('modalWelcome')") + .info-container + p Introduction + .row + .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 + .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" + v-bind:vobj="v" v-bind:index="idx" v-bind:key="v.name") + .row(v-show="display=='correspondance'") + my-correspondance + .row + my-room(v-show="display=='room'" :conn="conn" :settings="settings") + my-tab-games(v-show="display=='tabGames'") + my-rules(v-show="display=='rules'" :settings="settings") + my-problems(v-show="display=='problems'" :prob-id="probId" :settings="settings") + my-game(v-show="display=='game'" :game-ref="gameRef" :conn="conn" + :allow-chat="allowChat" :allow-movelist="allowMovelist" + :mode="mode" :settings="settings" @game-over="archiveGame") + + footer.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2.text-center + div + a(href="https://github.com/yagu0/vchess") Source code + p.clickable(onClick="document.getElementById('modalContact').checked=true") + =translations["Contact form"] + + script. + const translations = !{JSON.stringify(translations)}; + const user = !{JSON.stringify(user)}; + const variantArray = !{JSON.stringify(variantArray)}; + // TODO: get rid of underscore + // (used essentially for _.random(), _.sample() and _.range()) + script(src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js") + // TODO: add only the necessary icons to mini-css custom build + script(src="//unpkg.com/feather-icons") + if development + script(src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js") + else + script(src="https://cdn.jsdelivr.net/npm/vue") + script(src="/javascripts/utils/printDiagram.js") + script(src="/javascripts/utils/datetime.js") + script(src="/javascripts/utils/squareId.js") + script(src="/javascripts/utils/misc.js") + script(src="/javascripts/utils/ajax.js") + script(src="/javascripts/utils/array.js") + script(src="/javascripts/shared/nbPlayers.js") + script(src="/javascripts/shared/challengeCheck.js") + script(src="/javascripts/shared/userCheck.js") + script(src="/javascripts/components/upsertUser.js") + script(src="/javascripts/components/variantSummary.js") + script(src="/javascripts/components/correspondance.js") + script(src="/javascripts/components/board.js") + script(src="/javascripts/components/chat.js") + script(src="/javascripts/components/gameList.js") + script(src="/javascripts/components/challengeList.js") + script(src="/javascripts/components/moveList.js") + script(src="/javascripts/components/game.js") + script(src="/javascripts/components/rules.js") + script(src="/javascripts/components/room.js") + script(src="/javascripts/components/tabGames.js") + script(src="/javascripts/components/problemSummary.js") + script(src="/javascripts/components/problems.js") + script(src="/javascripts/base_rules.js") + script(src="/javascripts/contactForm.js") + script(src="/javascripts/socket_url.js") + script(src="/javascripts/index.js") + script(src="/javascripts/variant.js") + script(src="/javascripts/app.js") diff --git a/views/contactForm.pug b/views/contactForm.pug deleted file mode 100644 index a07369e3..00000000 --- a/views/contactForm.pug +++ /dev/null @@ -1,18 +0,0 @@ -input#modalContact.modal(type="checkbox") -div(role="dialog" aria-labelledby="contactTitle") - form.card.smallpad - label.modal-close(for="modalContact") - h3#contactTitle.section= translations["Contact form"] - fieldset - label(for="userEmail")= translations["Email"] - input#userEmail(type="email") - fieldset - label(for="mailSubject")= translations["Subject"] - input#mailSubject(type="text") - fieldset - label(for="mailContent")= translations["Content"] - br - textarea#mailContent - fieldset - button(type="button" onClick="trySendMessage()") Send - p#emailSent= translations["Email sent!"] diff --git a/views/index.pug b/views/index.pug deleted file mode 100644 index 6ea45166..00000000 --- a/views/index.pug +++ /dev/null @@ -1,48 +0,0 @@ -extends layout - -block css - link(rel="stylesheet", href="/stylesheets/index.css") - -block content - .container - case lang - when "en" - include welcome/en - when "es" - include welcome/es - when "fr" - include welcome/fr - .row - #header.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 - #mainTitle.clickable(onClick="doClick('modalWelcome')") - img(src="/images/index/unicorn.svg") - .info-container - p vchess.club - img(src="/images/index/wildebeest.svg") - #flagMenu.clickable(onClick="doClick('modalLang')") - img(src="/images/flags/" + lang + ".svg") - include userMenu - a.right-menu(v-show="display=='variants'" href="#correspondance") - .info-container - p Correspondance - a.right-menu(v-show="display=='correspondance'" href="#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") - 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=='correspondance'") - my-correspondance - -block javascripts - script. - const variantArray = !{JSON.stringify(variantArray)}; - script(src="/javascripts/socket_url.js") - script(src="/javascripts/components/variantSummary.js") - script(src="/javascripts/components/gameList.js") - script(src="/javascripts/components/challengeList.js") - script(src="/javascripts/components/correspondance.js") - script(src="/javascripts/index.js") diff --git a/views/langNames.pug b/views/langNames.pug deleted file mode 100644 index 997e5830..00000000 --- a/views/langNames.pug +++ /dev/null @@ -1,6 +0,0 @@ -- - var langName = { - "en": "English", - "es": "Español", - "fr": "Français", - }; diff --git a/views/layout.pug b/views/layout.pug deleted file mode 100644 index b2b1d526..00000000 --- a/views/layout.pug +++ /dev/null @@ -1,64 +0,0 @@ -doctype html -html - - head - meta(charset="UTF-8") - title vchess - #{title} - meta(name="viewport" content="width=device-width, initial-scale=1") - meta(name="msapplication-config" content="/images/favicon/browserconfig.xml") - meta(name="theme-color" content="#ffffff") - link(rel="stylesheet" - href="//cdnjs.cloudflare.com/ajax/libs/mini.css/3.0.0/mini-default.min.css") - link(rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:400,700") - link(rel="apple-touch-icon" sizes="180x180" - href="/images/favicon/apple-touch-icon.png") - link(rel="icon" type="image/png" sizes="32x32" - href="/images/favicon/favicon-32x32.png") - link(rel="icon" type="image/png" sizes="16x16" - href="/images/favicon/favicon-16x16.png") - link(rel="manifest" href="/images/favicon/manifest.json") - link(rel="mask-icon" href="/images/favicon/safari-pinned-tab.svg" color="#5bbad5") - link(rel="shortcut icon" href="/images/favicon/favicon.ico") - link(rel="stylesheet" href="/stylesheets/layout.css") - link(rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons") - block css - - body - include langNames - case lang - when "en" - include translations/en - when "es" - include translations/es - when "fr" - include translations/fr - include modalLang - include contactForm - main#VueElement - my-upsert-user() - block content - footer.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2.text-center - div - a(href="https://github.com/yagu0/vchess") Source code - p.clickable(onClick="document.getElementById('modalContact').checked=true") - =translations["Contact form"] - - script(src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js") - script(src="/javascripts/utils/misc.js") - script(src="/javascripts/utils/ajax.js") - script(src="/javascripts/utils/array.js") - script(src="/javascripts/base_rules.js") - script(src="/javascripts/layout.js") - script(src="/javascripts/contactForm.js") - if development - script(src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js") - else - script(src="https://cdn.jsdelivr.net/npm/vue") - script(src="/javascripts/shared/nbPlayers.js") - script(src="/javascripts/shared/challengeCheck.js") - script(src="/javascripts/shared/userCheck.js") - script(src="/javascripts/components/upsertUser.js") - script. - const translations = !{JSON.stringify(translations)}; - const user = !{JSON.stringify(user)}; - block javascripts diff --git a/views/modalLang.pug b/views/modalLang.pug deleted file mode 100644 index b6311829..00000000 --- a/views/modalLang.pug +++ /dev/null @@ -1,11 +0,0 @@ -input#modalLang.modal(type="checkbox") -div(role="dialog") - #language.card - label.modal-close(for="modalLang") - form - fieldset - label(for="langSelect")= translations["Language"] - select#langSelect - each language,langCode in langName - option(value=langCode selected=(lang==langCode)) - =language diff --git a/views/modalSettings.pug b/views/modals.pug similarity index 62% rename from views/modalSettings.pug rename to views/modals.pug index 3c22c359..e24a7389 100644 --- a/views/modalSettings.pug +++ b/views/modals.pug @@ -1,3 +1,15 @@ +input#modalLang.modal(type="checkbox") +div(role="dialog") + #language.card + label.modal-close(for="modalLang") + form + fieldset + label(for="langSelect")= translations["Language"] + select#langSelect + each language,langCode in langName + option(value=langCode selected=(lang==langCode)) + =language + input#modalSettings.modal(type="checkbox") div(role="dialog" aria-labelledby="settingsTitle") .card.smallpad(@change="updateSettings") @@ -33,3 +45,22 @@ div(role="dialog" aria-labelledby="settingsTitle") option(value="0")= translations["None"] option(value="1")= translations["New game"] option(value="2")= translations["All"] + +input#modalContact.modal(type="checkbox") +div(role="dialog" aria-labelledby="contactTitle") + form.card.smallpad + label.modal-close(for="modalContact") + h3#contactTitle.section= translations["Contact form"] + fieldset + label(for="userEmail")= translations["Email"] + input#userEmail(type="email") + fieldset + label(for="mailSubject")= translations["Subject"] + input#mailSubject(type="text") + fieldset + label(for="mailContent")= translations["Content"] + br + textarea#mailContent + fieldset + button(type="button" onClick="trySendMessage()") Send + p#emailSent= translations["Email sent!"] diff --git a/views/userMenu.pug b/views/userMenu.pug deleted file mode 100644 index 5a0b0743..00000000 --- a/views/userMenu.pug +++ /dev/null @@ -1,10 +0,0 @@ -#userMenu.clickable.right-menu(onClick="doClick('modalUser')") - .info-container - if !user.email - p - span Login - i.material-icons person - else - p - span Update - i.material-icons person diff --git a/views/variant.pug b/views/variant.pug deleted file mode 100644 index 7e57bbf5..00000000 --- a/views/variant.pug +++ /dev/null @@ -1,60 +0,0 @@ -extends layout - -block css - link(rel="stylesheet" href="/stylesheets/variant.css") - -block content - include modalSettings - .container - .row - .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 - label.drawer-toggle(for="drawer-control") - input#drawer-control.drawer(type="checkbox") - #menuBar - label.drawer-close(for="drawer-control") - a.icon-link(href="/") - i.material-icons home - a(href="#room") - =translations["Hall"] - a(href="#tabGames") - =translations["My games"] - a(href="#rules") - =translations["Rules"] - a(href="#problems") - =translations["Problems"] - #flagMenu.clickable(onClick="doClick('modalLang')") - img(src="/images/flags/" + lang + ".svg") - #settings.clickable(onClick="doClick('modalSettings')") - i.material-icons settings - include userMenu - .row - my-room(v-show="display=='room'" :conn="conn" :settings="settings") - my-tab-games(v-show="display=='tabGames'") - my-rules(v-show="display=='rules'" :settings="settings") - my-problems(v-show="display=='problems'" :prob-id="probId" :settings="settings") - my-game(v-show="display=='game'" :game-ref="gameRef" :conn="conn" - :allow-chat="allowChat" :allow-movelist="allowMovelist" - :mode="mode" :settings="settings" @game-over="archiveGame") - -block javascripts - script(src="/javascripts/utils/printDiagram.js") - script(src="/javascripts/utils/datetime.js") - script(src="/javascripts/utils/squareId.js") - script(src="/javascripts/socket_url.js") - script(src="/javascripts/variants/" + variant.name + ".js") - script. - const variant = !{JSON.stringify(variant)}; - // Just 'V' because this variable is often used: - const V = eval(variant.name + "Rules"); - script(src="/javascripts/components/board.js") - script(src="/javascripts/components/chat.js") - script(src="/javascripts/components/gameList.js") - script(src="/javascripts/components/challengeList.js") - script(src="/javascripts/components/moveList.js") - script(src="/javascripts/components/game.js") - script(src="/javascripts/components/rules.js") - script(src="/javascripts/components/room.js") - script(src="/javascripts/components/tabGames.js") - script(src="/javascripts/components/problemSummary.js") - script(src="/javascripts/components/problems.js") - script(src="/javascripts/variant.js")