From: Benjamin Auder Date: Thu, 31 Jan 2019 18:32:09 +0000 (+0100) Subject: Styled layout. TODO: variants page, and then index X-Git-Url: https://git.auder.net/?p=vchess.git;a=commitdiff_plain;h=85e5b5c1e6192a134fa69182e8c077605fdb969f Styled layout. TODO: variants page, and then index --- diff --git a/client/next_src/components/challengeList.js b/client/next_src/components/challengeList.js deleted file mode 100644 index 2c997b7e..00000000 --- a/client/next_src/components/challengeList.js +++ /dev/null @@ -1,33 +0,0 @@ -Vue.component("my-challenge-list", { - props: ["challenges"], - computed: { - showVariant: function() { - this.challenges.length > 0 && !!this.challenges[0].variant; - }, - showNbPlayers: function() { - this.challenges.length > 0 && !!this.challenges[0].nbPlayers; - }, - }, - template: ` - - - - - - - - - - - - - - - -
VariantFromToCadenceNumber of players
{{ c.variant }}{{ c.from.name }} - {{ p.name }} - {{ c.mainTime }} + {{ c.increment }}{{ c.nbPlayers }}
- `, -}); - -// TODO: challenge format from/to ou uid/players ............ diff --git a/client/next_src/components/gameList.js b/client/next_src/components/gameList.js deleted file mode 100644 index 9b669826..00000000 --- a/client/next_src/components/gameList.js +++ /dev/null @@ -1,29 +0,0 @@ -Vue.component("my-game-list", { - props: ["games"], - computed: { - showVariant: function() { - return this.games.length > 0 && !!this.games[0].vname; - }, - showResult: function() { - return this.games.length > 0 && this.games[0].score != "*"; - }, - }, - template: ` - - - - - - - - - - - - - -
VariantPlayers namesCadenceResult
{{ g.vname }} - {{ p.name }} - {{ g.mainTime }} + {{ g.increment }}{{ g.score }}
- `, -}); diff --git a/client/public/index.html b/client/public/index.html index 6549d7a7..af506cdf 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -10,6 +10,12 @@ href="//cdnjs.cloudflare.com/ajax/libs/mini.css/3.0.0/mini-default.min.css"> +
diff --git a/client/src/App.vue b/client/src/App.vue index 2b131276..dd45b343 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -8,48 +8,46 @@ UpsertUser .container .row(v-show="$route.path == '/'") - // Header (on index only ?!) - header - .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 + .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 + // Header (on index only) + header 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(to="/") - // select options all variants + filter possible (as in problems) - | Home - router-link(to="/myGames") - | {{ st.tr["My games"] }} - router-link(to="/rules") - // Boxes OK for rules/Atomic/ ...etc - | {{ st.tr["Rules"] }} - router-link(to="/problems") - | {{ st.tr["Problems"] }} - #userMenu.clickable.right-menu(onClick="doClick('modalUser')") - .info-container - p - span {{ !st.user.id ? "Login" : "Update" }} - span.icon-user - #flagMenu.clickable.right-menu(onClick="doClick('modalLang')") - img(src="/images/flags/" + lang + ".svg") - #settings.clickable(onClick="doClick('modalSettings')") - | Settings - i(data-feather="settings") + .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 + // Menu (top of page): + // Left: home, variants, mygames, problems + // Right: usermenu, settings, flag + nav + label.drawer-toggle(for="drawerControl") + input#drawerControl.drawer(type="checkbox") + #menuBar + label.drawer-close(for="drawerControl") + #leftMenu + router-link(to="/") + | {{ st.tr["Home"] }} + router-link(to="/variants") + | {{ st.tr["Variants"] }} + router-link(to="/mygames") + | {{ st.tr["My games"] }} + router-link(to="/problems") + | {{ st.tr["Problems"] }} + #rightMenu + .clickable(onClick="doClick('modalUser')") + | {{ !st.user.id ? "Login" : "Update" }} + .clickable(onClick="doClick('modalSettings')") + | {{ st.tr["Settings"] }} + .clickable(onClick="doClick('modalLang')") + img(v-if="!!st.lang" + :src="require(`@/assets/images/flags/${st.lang}.svg`)") .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 + .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 + footer + a(href="https://github.com/yagu0/vchess") {{ st.tr["Source code"] }} p.clickable(onClick="doClick('modalContact')") | {{ st.tr["Contact form"] }} //my-game(:game-ref="gameRef" :mode="mode" :settings="settings" @game-over="archiveGame") @@ -84,14 +82,75 @@ export default { font-family: "Avenir", Helvetica, Arial, sans-serif -webkit-font-smoothing: antialiased -moz-osx-font-smoothing: grayscale - text-align: center - color: #2c3e50 -#nav - padding: 30px - a - font-weight: bold - color: #2c3e50 - &.router-link-exact-active - color: #42b983 +.container + @media screen and (max-width: 767px) + padding: 0 + +header + width: 100% + display: flex + align-items: center + justify-content: center + margin: 0 auto + & > img + width: 30px + height: 30px + +.clickable + cursor: pointer + +nav + width: 100% + padding: 0 + & > #menuBar + width: 100% + padding: 0 + & > #leftMenu + padding: 0 + width: 50% + display: inline-flex + align-items: center + justify-content: flex-start + & > a + display: inline-block + color: #2c3e50 + &.router-link-exact-active + color: #42b983 + & > #rightMenu + padding: 0 + width: 50% + display: inline-flex + align-items: center + justify-content: flex-end + & > div + display: inline-block + & > img + padding: 0 + width: 30px + height: 30px + +// TODO: drawer, until 600px wide OK (seemingly) +// After, zone where left and right just go on top of another +// Then, on narrow screen put everything on one line +[type="checkbox"].drawer+* + right: -767px + +footer + //background-color: #000033 + font-size: 1rem + width: 100% + display: inline-flex + align-items: center + justify-content: center + & > a + display: inline-block + margin: 0 10px 0 0 + &:link + color: #2c3e50 + &:hover + text-decoration: none + & > p + display: inline-block + margin: 0 0 0 10px diff --git a/client/src/components/ChallengeList.vue b/client/src/components/ChallengeList.vue new file mode 100644 index 00000000..a52e0cae --- /dev/null +++ b/client/src/components/ChallengeList.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/client/src/components/GameList.vue b/client/src/components/GameList.vue new file mode 100644 index 00000000..c7f661ca --- /dev/null +++ b/client/src/components/GameList.vue @@ -0,0 +1,29 @@ + + + diff --git a/client/src/data/nbPlayers.js b/client/src/data/nbPlayers.js index 8c0cc864..2f58d168 100644 --- a/client/src/data/nbPlayers.js +++ b/client/src/data/nbPlayers.js @@ -1,4 +1,4 @@ -const NbPlayers = +export const NbPlayers = { "Alice": [2,3,4], "Antiking": [2,3,4], @@ -19,5 +19,3 @@ const NbPlayers = "Wildebeest": [2], "Zen": [2,3,4], }; - -try { module.exports = NbPlayers; } catch (e) { } //for server diff --git a/client/src/main.js b/client/src/main.js index 97bad754..703ff742 100644 --- a/client/src/main.js +++ b/client/src/main.js @@ -38,6 +38,7 @@ new Vue({ // mounted: function() { // feather.replace(); // }, + // "mounted" and not "created", because modalWelcome must be filled mounted: function() { store.initialize(); }, diff --git a/client/src/stylesheets/layout.sass b/client/src/stylesheets/layout.sass index 5639c7b2..b7446750 100644 --- a/client/src/stylesheets/layout.sass +++ b/client/src/stylesheets/layout.sass @@ -55,26 +55,6 @@ a.right-menu color: blue display: none -footer - height: 77px - background-color: #000033 - div - line-height: 77px - a - margin: 0 10px 0 0 - display: inline-block - &:visited, &:link - color: white - p - margin: 0 0 0 10px - display: inline-block - color: white - text-decoration: underline - @media screen and (max-width: 767px) - height: 43px - div - line-height: 43px - a text-decoration: underline diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js index ee65449d..4d242c2c 100644 --- a/client/src/translations/fr.js +++ b/client/src/translations/fr.js @@ -1,5 +1,12 @@ export const translations = { + "Home": "Accueil", + "Variants": "Variantes", + "My games": "Mes parties", + "Problems": "Problèmes", + "Contact form": "Formulaire de contact", + "Source code": "Code source", + "Language": "Langue", // Index page: @@ -31,7 +38,6 @@ export const translations = "Waiting for opponent...": "En attente d'un adversaire...", "Rules": "Règles", "Play": "Jouer", - "Problems": "Problèmes", "White win": "Les blancs gagnent", "Black win": "Les noirs gagnent", "Draw": "Match nul", diff --git a/client/src/views/Home.vue b/client/src/views/Home.vue index c2c5b442..f0f6a5c7 100644 --- a/client/src/views/Home.vue +++ b/client/src/views/Home.vue @@ -7,7 +7,7 @@ div fieldset label(for="selectVariant") {{ st.tr["Variant"] }} select#selectVariant(v-model="newgameInfo.vid") - option(v-for="v in variants" :value="v.id") {{ v.name }} + option(v-for="v in st.variants" :value="v.id") {{ v.name }} fieldset label(for="selectNbPlayers") {{ st.tr["Number of players"] }} select#selectNbPlayers(v-model="newgameInfo.nbPlayers") @@ -31,14 +31,14 @@ div v-model="newgameInfo.players[2].name") fieldset label(for="inputFen") - {{ st.tr["FEN (ignored if players fields are blank)"] }} + | {{ st.tr["FEN (ignored if players fields are blank)"] }} input#inputFen(type="text" v-model="newgameInfo.fen") button(@click="newGame") Launch game p TODO: cadence, adversaire (pre-filled if click on name) p cadence 2m+12s ou 7d+1d (m,s ou d,d) --> main, increment p Note: leave FEN blank for random; FEN only for targeted challenge div - my-challenge-list(:challenges="challenges" @click-challenge="clickChallenge") + ChallengeList(:challenges="challenges" @click-challenge="clickChallenge") div(style="border:1px solid black") h3 Online players div(v-for="p in players" @click="challenge(p)") {{ p.name }} @@ -47,9 +47,9 @@ div .button-group button(@click="gdisplay='live'") Live games button(@click="gdisplay='corr'") Correspondance games - my-game-list(v-show="gdisplay=='live'" :games="liveGames" + GameList(v-show="gdisplay=='live'" :games="liveGames" @show-game="showGame") - my-game-list(v-show="gdisplay=='corr'" :games="corrGames" + GameList(v-show="gdisplay=='corr'" :games="corrGames" @show-game="showGame") @@ -65,6 +65,7 @@ fin de partie corr: supprimer partie du serveur au bout de 7 jours (arbitraire) // TODO: au moins l'échange des coups en P2P ? et game chat ? // TODO: objet game, objet challenge ? et player ? import { store } from "@/store"; +import { NbPlayers } from "@/data/nbPlayers"; import GameList from "@/components/GameList.vue"; import ChallengeList from "@/components/ChallengeList.vue"; export default { @@ -92,46 +93,48 @@ export default { }, }; }, - created: function() { - // TODO: ask server for current corr games (all but mines: names, ID, time control) - const socketMessageListener = msg => { - const data = JSON.parse(msg.data); - switch (data.code) - { - case "newgame": - // TODO: new game just started: data contain all informations - // (id, players, time control, fenStart ...) - break; - // TODO: also receive live games summaries (update) - // (just players names, time control, and ID + player ID) - case "acceptchallenge": - // oppid: opponent socket ID (or DB id if registered) - if (true) //TODO: if challenge is full - this.newGame(data.challenge, data.user); //user.id et user.name - break; - case "withdrawchallenge": - // TODO - break; - case "cancelchallenge": - // TODO - break; - // TODO: distinguish these (dis)connect events from their analogs in game.js - case "connect": - this.players.push({name:data.name, id:data.uid}); - break; - case "disconnect": - const pIdx = this.players.findIndex(p => p.id == data.uid); - this.players.splice(pIdx); - break; - } - }; - const socketCloseListener = () => { - this.st.conn.addEventListener('message', socketMessageListener); - this.st.conn.addEventListener('close', socketCloseListener); - }; - this.st.conn.onmessage = socketMessageListener; - this.st.conn.onclose = socketCloseListener; - }, + watch: { + "st.conn": function() { + // TODO: ask server for current corr games (all but mines: names, ID, time control) + const socketMessageListener = msg => { + const data = JSON.parse(msg.data); + switch (data.code) + { + case "newgame": + // TODO: new game just started: data contain all informations + // (id, players, time control, fenStart ...) + break; + // TODO: also receive live games summaries (update) + // (just players names, time control, and ID + player ID) + case "acceptchallenge": + // oppid: opponent socket ID (or DB id if registered) + if (true) //TODO: if challenge is full + this.newGame(data.challenge, data.user); //user.id et user.name + break; + case "withdrawchallenge": + // TODO + break; + case "cancelchallenge": + // TODO + break; + // TODO: distinguish these (dis)connect events from their analogs in game.js + case "connect": + this.players.push({name:data.name, id:data.uid}); + break; + case "disconnect": + const pIdx = this.players.findIndex(p => p.id == data.uid); + this.players.splice(pIdx); + break; + } + }; + const socketCloseListener = () => { + this.st.conn.addEventListener('message', socketMessageListener); + this.st.conn.addEventListener('close', socketCloseListener); + }; + this.st.conn.onmessage = socketMessageListener; + this.st.conn.onclose = socketCloseListener; + }, + }, methods: { showGame: function(game) { // NOTE: if we are an observer, the game will be found in main games list @@ -207,8 +210,8 @@ export default { uid: user.id, added: Date.now(), vname: vname, - }, - this.challenges.push(response.challenge); + }); + this.challenges.push(chall); } ); // TODO: else, if live game: send infos (socket), and... @@ -233,10 +236,15 @@ export default { possibleNbplayers: function(nbp) { if (this.newgameInfo.vid == 0) return false; + const variants = this.st.variants; const idxInVariants = - variantArray.findIndex(v => v.id == this.newgameInfo.vid); - return NbPlayers[variantArray[idxInVariants].name].includes(nbp); + variants.findIndex(v => v.id == this.newgameInfo.vid); + return NbPlayers[variants[idxInVariants].name].includes(nbp); }, }, -}); +}; + + diff --git a/client/src/views/Variants.vue b/client/src/views/Variants.vue index 03903572..f5214296 100644 --- a/client/src/views/Variants.vue +++ b/client/src/views/Variants.vue @@ -1,15 +1,15 @@