From: Benjamin Auder Date: Sat, 7 Mar 2020 00:31:56 +0000 (+0100) Subject: Better style for corr moves confirmation (see board) X-Git-Url: https://git.auder.net/game/current/%7B%7B%20asset%28%27mixstore/js/summernote.min.js%27%29%20%7D%7D?a=commitdiff_plain;h=5b4de147a4e2f737c660f3e82f46664a9635477f;p=vchess.git Better style for corr moves confirmation (see board) --- diff --git a/client/src/components/MoveList.vue b/client/src/components/MoveList.vue index da70e349..6e3a90d5 100644 --- a/client/src/components/MoveList.vue +++ b/client/src/components/MoveList.vue @@ -77,6 +77,12 @@ export default { document.getElementById("adjuster").addEventListener( "click", processModalClick); + if ("ontouchstart" in window) { + // Disable tooltips on smartphones: + document.getElementsByClassName("tooltip").forEach(elt => { + elt.classList.remove("tooltip"); + }); + } // Take full width on small screens: let boardSize = parseInt(localStorage.getItem("boardSize")); if (!boardSize) { @@ -218,4 +224,7 @@ span#rulesBtn button margin: 0 + +button.tooltip + padding-bottom: 5px diff --git a/client/src/main.js b/client/src/main.js index 70b7d78a..7e9ce9cc 100644 --- a/client/src/main.js +++ b/client/src/main.js @@ -18,7 +18,12 @@ new Vue({ if (e.code === "Escape") { let modalBoxes = document.querySelectorAll("[id^='modal']"); modalBoxes.forEach(m => { - if (m.checked && m.id != "modalAccept") m.checked = false; + if ( + m.checked && + !["modalAccept","modalConfirm"].includes(m.id) + ) { + m.checked = false; + } }); } }); diff --git a/client/src/translations/en.js b/client/src/translations/en.js index 6676ad89..ca7a0965 100644 --- a/client/src/translations/en.js +++ b/client/src/translations/en.js @@ -21,6 +21,7 @@ export const translations = { blue: "blue", brown: "brown", Cadence: "Cadence", + Cancel: "Cancel", Challenge: "Challenge", "Challenge declined": "Challenge declined", "Chat here": "Chat here", @@ -130,6 +131,7 @@ export const translations = { "User creation failed. Try again": "User creation failed. Try again", "User name": "User name", "User name or email already in use": "User name or email already in use", + Validate: "Validate", Variant: "Variant", Variants: "Variants", Versus: "Versus", diff --git a/client/src/translations/es.js b/client/src/translations/es.js index c5ee0935..e72a36db 100644 --- a/client/src/translations/es.js +++ b/client/src/translations/es.js @@ -21,6 +21,7 @@ export const translations = { blue: "azul", brown: "marrón", Cadence: "Cadencia", + Cancel: "Anular", Challenge: "Desafiar", "Challenge declined": "Desafío rechazado", "Chat here": "Chat aquí", @@ -130,6 +131,7 @@ export const translations = { "User creation failed. Try again": "Error al crear cuenta. inténtelo de nuevo", "User name": "Nombre de usuario", "User name or email already in use": "Nombre de usuario o correo electrónico ya en uso", + Validate: "Validar", Variant: "Variante", Variants: "Variantes", Versus: "Contra", diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js index 270f604c..f777c3e8 100644 --- a/client/src/translations/fr.js +++ b/client/src/translations/fr.js @@ -21,6 +21,7 @@ export const translations = { blue: "bleu", brown: "marron", Cadence: "Cadence", + Cancel: "Annuler", Challenge: "Défier", "Challenge declined": "Défi refusé", "Chat here": "Chattez ici", @@ -130,6 +131,7 @@ export const translations = { "User creation failed. Try again": "Échec de la création du compte. Réessayez", "User name": "Nom d'utilisateur", "User name or email already in use": "Nom d'utilisateur ou email déjà utilisés", + Validate: "Valider", Variant: "Variante", Variants: "Variantes", Versus: "Contre", diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue index df6930cb..086becb8 100644 --- a/client/src/views/Game.vue +++ b/client/src/views/Game.vue @@ -8,7 +8,7 @@ main role="dialog" data-checkbox="modalChat" ) - #chat.card + .card label.modal-close(for="modalChat") #participants span {{ Object.keys(people).length + " " + st.tr["participant(s):"] }} @@ -26,6 +26,16 @@ main @mychat="processChat" @chatcleared="clearChat" ) + input#modalConfirm.modal(type="checkbox") + div#confirmDiv(role="dialog") + .card + .diagram(v-html="curDiag") + .button-group#buttonsConfirm + // onClick for acceptBtn: set dynamically + button.acceptBtn + span {{ st.tr["Validate"] }} + button.refuseBtn(@click="cancelMove()") + span {{ st.tr["Cancel"] }} .row #aboveBoard.col-sm-12.col-md-9.col-md-offset-3.col-lg-10.col-lg-offset-2 span.variant-cadence {{ game.cadence }} @@ -103,8 +113,8 @@ import { ppt } from "@/utils/datetime"; import { ajax } from "@/utils/ajax"; import { extractTime } from "@/utils/timeControl"; import { getRandString } from "@/utils/alea"; +import { getDiagram } from "@/utils/printDiagram"; import { processModalClick } from "@/utils/modalClick"; -import { getFullNotation } from "@/utils/notation"; import { playMove, getFilteredMove } from "@/utils/playUndo"; import { getScoreMessage } from "@/utils/scoring"; import { ArrayFun } from "@/utils/array"; @@ -138,6 +148,7 @@ export default { onMygames: [], //opponents (or me) on "MyGames" page lastate: undefined, //used if opponent send lastate before game is ready repeat: {}, //detect position repetition + curDiag: "", //for corr moves confirmation newChat: "", conn: null, roomInitialized: false, @@ -181,7 +192,8 @@ export default { "&tmpId=" + getRandString() + "&page=" + - encodeURIComponent(this.$route.path); + // Discard potential "/?next=[...]" for page indication: + encodeURIComponent(this.$route.path.match(/\/game\/[a-zA-Z0-9]+/)[0]); this.conn = new WebSocket(this.connexionString); this.conn.onmessage = this.socketMessageListener; this.conn.onclose = this.socketCloseListener; @@ -209,6 +221,12 @@ export default { document .getElementById("chatWrap") .addEventListener("click", processModalClick); + if ("ontouchstart" in window) { + // Disable tooltips on smartphones: + document.getElementsByClassName("tooltip").forEach(elt => { + elt.classList.remove("tooltip"); + }); + } }, beforeDestroy: function() { this.send("disconnect"); @@ -935,27 +953,32 @@ export default { moveCol == this.game.mycolor && !data.receiveMyMove ) { - setTimeout(() => { - // TODO: remplacer cette confirm box par qqch de plus discret - // (et de même pour challenge accepté / refusé) - if ( - !confirm( - this.st.tr["Move played:"] + - " " + - getFullNotation(move) + - "\n" + - this.st.tr["Are you sure?"] - ) - ) { - this.$refs["basegame"].cancelLastMove(); - return; + let el = document.querySelector("#buttonsConfirm > .acceptBtn"); + // We may play several moves in a row: in case of, remove listener: + let elClone = el.cloneNode(true); + el.parentNode.replaceChild(elClone, el); + elClone.addEventListener( + "click", + () => { + document.getElementById("modalConfirm").checked = false; + doProcessMove(); } - doProcessMove(); - // Let small time to finish drawing current move attempt: - }, 500); + ); + this.vr.play(move); + const parsedFen = V.ParseFen(this.vr.getFen()); + this.vr.undo(move); + this.curDiag = getDiagram({ + position: parsedFen.position, + orientation: this.game.mycolor + }); + document.getElementById("modalConfirm").checked = true; } else doProcessMove(); }, + cancelMove: function() { + document.getElementById("modalConfirm").checked = false; + this.$refs["basegame"].cancelLastMove(); + }, gameOver: function(score, scoreMsg) { this.game.score = score; this.$set(this.game, "scoreMsg", scoreMsg || getScoreMessage(score)); @@ -1059,10 +1082,14 @@ span.yourturn display: inline-block margin: 0 15px -#chat +#chatWrap > .card padding-top: 20px max-width: 767px - border: none; + border: none + +#confirmDiv > .card + max-width: 767px + max-height: 100% .draw-sent, .draw-sent:hover background-color: lightyellow @@ -1075,4 +1102,21 @@ span.yourturn .somethingnew background-color: #c5fefe + +.diagram + margin: 0 auto + max-width: 400px + // width: 100% required for Firefox + width: 100% + +#buttonsConfirm + margin: 0 + & > button > span + width: 100% + text-align: center + +button.acceptBtn + background-color: lightgreen +button.refuseBtn + background-color: red diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index 6ecc5527..009a1abe 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -10,15 +10,17 @@ main p(v-html="infoMessage") input#modalAccept.modal(type="checkbox") div#acceptDiv(role="dialog") - .card.text-center - p + .card + p.text-center span.variantName {{ curChallToAccept.vname }} span {{ curChallToAccept.cadence }} span {{ st.tr["with"] + " " + curChallToAccept.from.name }} .diagram(v-html="tchallDiag") .button-group#buttonsTchall - button.acceptBtn(@click="decisionChallenge(true)") {{ st.tr["Accept challenge?"] }} - button.refuseBtn(@click="decisionChallenge(false)") {{ st.tr["Refuse"] }} + button.acceptBtn(@click="decisionChallenge(true)") + span {{ st.tr["Accept challenge?"] }} + button.refuseBtn(@click="decisionChallenge(false)") + span {{ st.tr["Refuse"] }} input#modalNewgame.modal( type="checkbox" @change="cadenceFocusIfOpened($event)" @@ -303,6 +305,7 @@ export default { "&tmpId=" + getRandString() + "&page=" + + // Hall: path is "/" (could be hard-coded as well) encodeURIComponent(this.$route.path); this.conn = new WebSocket(this.connexionString); this.conn.onopen = connectAndPoll; @@ -699,7 +702,7 @@ export default { const parsedFen = V.ParseFen(this.newchallenge.fen); this.newchallenge.diag = getDiagram({ position: parsedFen.position, - orientation: V.GetOppCol(parsedFen.turn) + orientation: parsedFen.turn }); } }, @@ -989,6 +992,9 @@ button.refuseBtn #buttonsTchall margin-top: 10px + & > button > span + width: 100% + text-align: center .variantName font-weight: bold @@ -996,6 +1002,8 @@ button.refuseBtn .diagram margin: 0 auto max-width: 400px + // width: 100% required for Firefox + width: 100% #inputFen width: 100%