From 5b3dc10e34bf5bf970494be6ee1fa0b67e2ca88c Mon Sep 17 00:00:00 2001 From: Benjamin Auder <benjamin.auder@somewhere> Date: Fri, 28 Feb 2020 14:57:02 +0100 Subject: [PATCH] Better site presentation (especially for languages settings) --- client/public/images/settings.svg | 7 +++ client/src/App.vue | 43 ++++++----------- client/src/components/BaseGame.vue | 66 ++------------------------ client/src/components/Language.vue | 46 ------------------ client/src/components/MoveList.vue | 76 +++++++++++++++++++++++++++++- client/src/components/Settings.vue | 45 +++++++++++++++++- 6 files changed, 141 insertions(+), 142 deletions(-) create mode 100644 client/public/images/settings.svg delete mode 100644 client/src/components/Language.vue diff --git a/client/public/images/settings.svg b/client/public/images/settings.svg new file mode 100644 index 00000000..d7839216 --- /dev/null +++ b/client/public/images/settings.svg @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve"> +<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata> +<g><path d="M987.5,633c1.4,8.4,1.1,18.6-1.1,30.5c-2.1,11.9-5.6,24-10.5,36.3C971,712,965,723,958,732.8c-7,9.8-14.7,16.8-23.1,21c-8.4,4.2-15.8,6.3-22.1,6.3c-6.3,0-13.3-1.4-21-4.2c-7-2.1-15.8-4-26.3-5.8c-10.5-1.8-21.2-2.1-32.1-1.1c-10.9,1.1-21.7,3.3-32.6,6.8c-10.9,3.5-20.1,9.5-27.9,17.9c-16.8,17.5-26.6,37.5-29.4,59.9c-2.8,22.4,0.4,43.8,9.5,64.1c7,14,6,28-3.2,42c-4.2,5.6-10.9,11.4-20,17.3c-9.1,6-19.1,11.4-30,16.3c-10.9,4.9-22.2,8.8-34.2,11.6c-11.9,2.8-22.4,4.2-31.5,4.2c-6.3,0-12.3-2.5-17.9-7.4c-5.6-4.9-9.5-10.2-11.6-15.8h-1.1c-7.7-21.7-20.8-40.5-39.4-56.2c-18.6-15.8-40.1-23.6-64.6-23.6c-23.8,0-45.4,7.9-64.6,23.6c-19.3,15.8-32.8,34.2-40.5,55.2c-3.5,8.4-8.8,14.5-15.8,18.4c-7,3.9-14.7,5.8-23.1,5.8c-9.8,0-20.8-1.8-33.1-5.3c-12.3-3.5-24.5-7.9-36.8-13.1c-12.3-5.3-23.3-11.4-33.1-18.4c-9.8-7-17.2-14-22.1-21c-3.5-4.9-5.4-10.7-5.8-17.3c-0.4-6.7,2.3-15.9,7.9-27.9c7.7-16.1,10.7-34.5,8.9-55.2c-1.8-20.7-10.7-39.8-26.8-57.3c-9.8-10.5-21.7-17.3-35.7-20.5c-14-3.1-27.3-4.4-39.9-3.7c-14.7,0.7-29.8,3.5-45.2,8.4c-9.8,2.8-19.6,2.1-29.4-2.1c-7.7-2.8-14.9-9.3-21.6-19.4c-6.7-10.2-12.6-21.4-17.9-33.6C20,690.6,16,678,13.2,665c-2.8-13-3.5-23.6-2.1-32.1c2.1-15.4,9.1-25.2,21-29.4c21-8.4,39.9-22.2,56.8-41.5c16.8-19.3,25.2-40.8,25.2-64.6c0-24.5-8.4-45.9-25.2-64.1C72,415,53.1,401.7,32.1,393.3c-6.3-2.1-11.6-7.2-15.8-15.2c-4.2-8.1-6.3-16.3-6.3-24.7c0-9.1,1.4-19.3,4.2-30.5c2.8-11.2,6.5-22.1,11-32.6c4.6-10.5,9.8-20.1,15.8-28.9c6-8.8,12.4-15.2,19.4-19.4c5.6-3.5,11-4.9,16.3-4.2c5.3,0.7,11,2.1,17.3,4.2c21,8.4,42.9,11,65.7,7.9c22.8-3.2,42.9-13.1,60.4-30c8.4-8.4,14.5-18.7,18.4-31c3.9-12.3,6.3-24.4,7.4-36.3c1-11.9,1-22.8,0-32.6c-1.1-9.8-1.9-16.8-2.6-21c-1.4-4.2-2.6-9.1-3.7-14.7c-1.1-5.6-0.5-10.5,1.6-14.7c4.2-9.8,11.7-18.4,22.6-25.8c10.9-7.4,22.6-13.5,35.2-18.4c12.6-4.9,24.9-8.6,36.8-11c11.9-2.5,21.4-3.7,28.4-3.7c9.1,0,16.3,3,21.5,8.9c5.3,6,8.9,12.1,11,18.4c7.7,18.9,20.3,35.6,37.8,49.9c17.5,14.4,38.2,21.5,62,21.5c24.5,0,46.2-6.8,65.2-20.5c18.9-13.7,32.2-31,39.9-52c2.8-5.6,7.2-11.4,13.1-17.3c6-6,12.1-8.9,18.4-8.9c9.8,0,20.5,1.4,32.1,4.2c11.6,2.8,22.9,6.7,34.2,11.6c11.2,4.9,21.5,11.2,31,18.9c9.5,7.7,17,16.1,22.6,25.2c3.5,5.6,4.6,11.7,3.2,18.4s-2.8,11.4-4.2,14.2c-9.1,20.3-11.9,41.7-8.4,64.1c3.5,22.4,13.7,42,30.5,58.9c16.8,16.8,37.5,26.1,62,27.8c24.5,1.8,47.3-2.3,68.3-12.1c5.6-3.5,12.4-4.9,20.5-4.2c8.1,0.7,14.9,3.9,20.5,9.5c10.5,9.8,19.8,24.7,27.9,44.7c8.1,20,13.5,40.1,16.3,60.4c1.4,11.9-0.5,21.2-5.8,27.9c-5.3,6.7-10.7,11-16.3,13.1c-21.7,7.7-40.3,21.2-55.7,40.5c-15.4,19.3-23.1,41.2-23.1,65.7c0,23.8,6.5,44.7,19.4,62.5c13,17.9,29.9,30.7,51,38.4c4.9,2.8,9.1,5.6,12.6,8.4C979.4,615.1,984.7,623.1,987.5,633L987.5,633z M498.7,727.6c31.5,0,61.3-6,89.3-17.9c28-11.9,52.4-28.4,73-49.4c20.7-21,37-45.4,48.9-73c11.9-27.7,17.9-57.3,17.9-88.8c0-31.5-6-61.1-17.9-88.8c-11.9-27.7-28.2-51.9-48.9-72.5c-20.7-20.7-45-37-73-48.9c-28-11.9-57.8-17.9-89.3-17.9c-31.5,0-61.1,6-88.8,17.9c-27.7,11.9-51.8,28.2-72.5,48.9c-20.7,20.7-37,44.9-48.9,72.5c-11.9,27.7-17.9,57.3-17.9,88.8c0,31.5,6,61.1,17.9,88.8c11.9,27.7,28.2,52,48.9,73c20.7,21,44.8,37.5,72.5,49.4C437.6,721.6,467.2,727.6,498.7,727.6L498.7,727.6z"/></g> +</svg> \ No newline at end of file diff --git a/client/src/App.vue b/client/src/App.vue index 9c724e76..b98618bf 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -1,6 +1,5 @@ <template lang="pug"> #app - Language Settings ContactForm UpsertUser @@ -9,7 +8,7 @@ .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 // Menu (top of page): // Left: hall, variants, problems, mygames - // Right: usermenu, settings, flag + // Right: usermenu, settings nav label.drawer-toggle(for="drawerControl") input#drawerControl.drawer(type="checkbox") @@ -27,13 +26,9 @@ #rightMenu .clickable(onClick="window.doClick('modalUser')") | {{ st.user.id > 0 ? (st.user.name || "@nonymous") : "Login" }} - .clickable(onClick="window.doClick('modalSettings')") - | {{ st.tr["Settings"] }} - .clickable#flagContainer(onClick="window.doClick('modalLang')") - img( - v-if="!!st.lang" - :src="flagImage" - ) + #divSettings.clickable(onClick="window.doClick('modalSettings')") + span {{ st.tr["Settings"] }} + img(src="/images/settings.svg") router-view .row .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 @@ -46,7 +41,6 @@ <script> import ContactForm from "@/components/ContactForm.vue"; -import Language from "@/components/Language.vue"; import Settings from "@/components/Settings.vue"; import UpsertUser from "@/components/UpsertUser.vue"; import { store } from "./store.js"; @@ -54,7 +48,6 @@ import { processModalClick } from "./utils/modalClick.js"; export default { components: { ContactForm, - Language, Settings, UpsertUser }, @@ -63,11 +56,6 @@ export default { st: store.state }; }, - computed: { - flagImage: function() { - return `/images/flags/${this.st.lang}.svg`; - } - }, mounted: function() { let dialogs = document.querySelectorAll("div[role='dialog']"); dialogs.forEach(d => { @@ -145,6 +133,16 @@ table th, td padding: 5px +#divSettings + padding: 0 10px 0 0 + height: 100% + & > span + vertical-align: middle + & > img + padding: 0 + height: 24px + vertical-align: middle + @media screen and (max-width: 767px) table tr > th, td @@ -177,12 +175,6 @@ nav justify-content: flex-end & > div display: inline-block - &#flagContainer - display: inline-flex - & > img - padding: 0 - width: 36px - height: 27px @media screen and (max-width: 767px) & > #leftMenu margin-top: 42px @@ -194,13 +186,6 @@ nav & > #rightMenu padding-top: 5px border-top: 1px solid darkgrey - & > div - &#flagContainer - display: inline-flex - & > img - padding: 0 - width: 36px - height: 27px @media screen and (max-width: 767px) nav diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index 1253c063..3820dc1b 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -8,21 +8,6 @@ div#baseGame .card.text-center label.modal-close(for="modalEog") h3.section {{ endgameMessage }} - input#modalAdjust.modal(type="checkbox") - div#adjuster( - role="dialog" - data-checkbox="modalAdjust" - ) - .card.text-center - label.modal-close(for="modalAdjust") - label(for="boardSize") {{ st.tr["Board size"] }} - input#boardSize.slider( - type="range" - min="0" - max="100" - value="50" - @input="adjustBoard()" - ) #gameContainer #boardContainer Board( @@ -47,7 +32,6 @@ div#baseGame #downloadDiv(v-if="allowDownloadPGN") a#download(href="#") button(@click="download()") {{ st.tr["Download"] }} PGN - button(onClick="window.doClick('modalAdjust')") ⤢ button( v-if="canAnalyze" @click="analyzePosition()" @@ -158,55 +142,14 @@ export default { baseGameDiv.addEventListener("keydown", this.handleKeys); baseGameDiv.addEventListener("wheel", this.handleScroll); } - [ - document.getElementById("eogDiv"), - document.getElementById("adjuster") - ].forEach(elt => elt.addEventListener("click", processModalClick)); - // Take full width on small screens: - let boardSize = parseInt(localStorage.getItem("boardSize")); - if (!boardSize) { - boardSize = - window.innerWidth >= 768 - ? 0.75 * Math.min(window.innerWidth, window.innerHeight) - : window.innerWidth; - } - const movesWidth = window.innerWidth >= 768 ? 280 : 0; - document.getElementById("boardContainer").style.width = boardSize + "px"; - let gameContainer = document.getElementById("gameContainer"); - gameContainer.style.width = boardSize + movesWidth + "px"; - document.getElementById("boardSize").value = - (boardSize * 100) / (window.innerWidth - movesWidth); - // timeout to avoid calling too many time the adjust method - let timeoutLaunched = false; - window.addEventListener("resize", () => { - if (!timeoutLaunched) { - timeoutLaunched = true; - setTimeout(() => { - this.adjustBoard(); - timeoutLaunched = false; - }, 500); - } - }); + document.getElementById("eogDiv").addEventListener( + "click", + processModalClick); }, methods: { focusBg: function() { document.getElementById("baseGame").focus(); }, - adjustBoard: function() { - const boardContainer = document.getElementById("boardContainer"); - if (!boardContainer) return; //no board on page - const k = document.getElementById("boardSize").value; - const movesWidth = window.innerWidth >= 768 ? 280 : 0; - const minBoardWidth = 240; //TODO: these 240 and 280 are arbitrary... - // Value of 0 is board min size; 100 is window.width [- movesWidth] - const boardSize = - minBoardWidth + - (k * (window.innerWidth - (movesWidth + minBoardWidth))) / 100; - localStorage.setItem("boardSize", boardSize); - boardContainer.style.width = boardSize + "px"; - document.getElementById("gameContainer").style.width = - boardSize + movesWidth + "px"; - }, handleKeys: function(e) { if ([32, 37, 38, 39, 40].includes(e.keyCode)) e.preventDefault(); switch (e.keyCode) { @@ -530,9 +473,6 @@ export default { [type="checkbox"]#modalEog+div .card min-height: 45px -[type="checkbox"]#modalAdjust+div .card - padding: 5px - #baseGame width: 100% &:focus diff --git a/client/src/components/Language.vue b/client/src/components/Language.vue deleted file mode 100644 index f49a592e..00000000 --- a/client/src/components/Language.vue +++ /dev/null @@ -1,46 +0,0 @@ -<template lang="pug"> -div - - - var langName = { - "en": "English", - "es": "Español", - "fr": "Français", - }; - input#modalLang.modal(type="checkbox") - div( - role="dialog" - data-checkbox="modalLang" - ) - .card - label.modal-close(for="modalLang") - fieldset(@change="setLanguage($event)") - label(for="langSelect") {{ st.tr["Language"] }} - select#langSelect - each language,langCode in langName - option(value=langCode) - =language -</template> - -<script> -import { store } from "@/store"; -export default { - name: "my-language", - data: function() { - return { - st: store.state - }; - }, - mounted: function() { - // NOTE: better style would be in pug directly, but how? - document.querySelectorAll("#langSelect > option").forEach(opt => { - if (opt.value == this.st.lang) opt.selected = true; - }); - }, - methods: { - setLanguage: function(e) { - localStorage["lang"] = e.target.value; - store.setLanguage(e.target.value); - } - } -}; -</script> diff --git a/client/src/components/MoveList.vue b/client/src/components/MoveList.vue index 920d5240..6ff93d8d 100644 --- a/client/src/components/MoveList.vue +++ b/client/src/components/MoveList.vue @@ -1,5 +1,23 @@ <template lang="pug"> div + input#modalAdjust.modal(type="checkbox") + div#adjuster( + role="dialog" + data-checkbox="modalAdjust" + ) + .card.text-center + label.modal-close(for="modalAdjust") + label(for="boardSize") {{ st.tr["Board size"] }} + input#boardSize.slider( + type="range" + min="0" + max="100" + value="50" + @input="adjustBoard()" + ) + div#boardSizeBtnContainer + button#boardSizeBtn(onClick="window.doClick('modalAdjust')") + | {{ st.tr["Board size"] }} #scoreInfo(v-if="score!='*'") p {{ score }} p {{ st.tr[message] }} @@ -17,13 +35,12 @@ div @click="() => gotoMove(moveIdx+1)" ) | {{ notation(moves[moveIdx+1]) }} - // Else: just add an empty cell - //.td(v-else) </template> <script> import { store } from "@/store"; import { getFullNotation } from "@/utils/notation"; +import { processModalClick } from "@/utils/modalClick"; export default { name: "my-move-list", props: ["moves", "show", "cursor", "score", "message", "firstNum"], @@ -32,6 +49,36 @@ export default { st: store.state }; }, + mounted: function() { + document.getElementById("adjuster").addEventListener( + "click", + processModalClick); + // Take full width on small screens: + let boardSize = parseInt(localStorage.getItem("boardSize")); + if (!boardSize) { + boardSize = + window.innerWidth >= 768 + ? 0.75 * Math.min(window.innerWidth, window.innerHeight) + : window.innerWidth; + } + const movesWidth = window.innerWidth >= 768 ? 280 : 0; + document.getElementById("boardContainer").style.width = boardSize + "px"; + let gameContainer = document.getElementById("gameContainer"); + gameContainer.style.width = boardSize + movesWidth + "px"; + document.getElementById("boardSize").value = + (boardSize * 100) / (window.innerWidth - movesWidth); + // timeout to avoid calling too many time the adjust method + let timeoutLaunched = false; + window.addEventListener("resize", () => { + if (!timeoutLaunched) { + timeoutLaunched = true; + setTimeout(() => { + this.adjustBoard(); + timeoutLaunched = false; + }, 500); + } + }); + }, watch: { cursor: function(newCursor) { if (window.innerWidth <= 767) return; //scrolling would hide chessboard @@ -58,6 +105,21 @@ export default { }, gotoMove: function(index) { this.$emit("goto-move", index); + }, + adjustBoard: function() { + const boardContainer = document.getElementById("boardContainer"); + if (!boardContainer) return; //no board on page + const k = document.getElementById("boardSize").value; + const movesWidth = window.innerWidth >= 768 ? 280 : 0; + const minBoardWidth = 240; //TODO: these 240 and 280 are arbitrary... + // Value of 0 is board min size; 100 is window.width [- movesWidth] + const boardSize = + minBoardWidth + + (k * (window.innerWidth - (movesWidth + minBoardWidth))) / 100; + localStorage.setItem("boardSize", boardSize); + boardContainer.style.width = boardSize + "px"; + document.getElementById("gameContainer").style.width = + boardSize + movesWidth + "px"; } } }; @@ -89,4 +151,14 @@ export default { .td.highlight-lm background-color: plum + +#boardSizeBtnContainer + width: 100% + text-align: center + +button#boardSizeBtn + margin: 0 + +[type="checkbox"]#modalAdjust+div .card + padding: 5px </style> diff --git a/client/src/components/Settings.vue b/client/src/components/Settings.vue index 117133d1..a6c3e658 100644 --- a/client/src/components/Settings.vue +++ b/client/src/components/Settings.vue @@ -5,9 +5,27 @@ div role="dialog" data-checkbox="modalSettings" ) - .card(@change="updateSettings($event)") + .card label.modal-close(for="modalSettings") - form + - + var langName = { + "en": "English", + "es": "Español", + "fr": "Français", + }; + fieldset(@change="setLanguage($event)") + label(for="langSelect") + | {{ st.tr["Language"] }} + select#langSelect + each language,langCode in langName + option(value=langCode) + =language + #flagContainer + img( + v-if="!!st.lang" + :src="flagImage" + ) + div(@change="updateSettings($event)") fieldset label(for="setHints") {{ st.tr["Show possible moves?"] }} input#setHints( @@ -44,7 +62,22 @@ export default { st: store.state }; }, + mounted: function() { + // NOTE: better style would be in pug directly, but how? + document.querySelectorAll("#langSelect > option").forEach(opt => { + if (opt.value == this.st.lang) opt.selected = true; + }); + }, + computed: { + flagImage: function() { + return `/images/flags/${this.st.lang}.svg`; + } + }, methods: { + setLanguage: function(e) { + localStorage["lang"] = e.target.value; + store.setLanguage(e.target.value); + }, updateSettings: function(event) { const propName = event.target.id .substr(3) @@ -63,4 +96,12 @@ export default { [type="checkbox"].modal+div .card max-width: 767px max-height: 100% +#flagContainer + display: inline-block + height: 100% + & > img + vertical-align: middle + padding: 0 0 0 10px + width: 36px + height: 27px </style> -- 2.44.0