From 44617f2f862ecdd561e6ad6358c3bb81fb4ae7ed Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Wed, 28 Jan 2026 18:14:51 +0100 Subject: [PATCH] Aggiunge shortcut per cambi e aggiorna README.md --- README.md | 2 ++ src/components/HomePage/HomePage.js | 49 +++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 74f0530..4b48f13 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Applicazione web **Progressive Web App (PWA)** per tracciare i punteggi di parti - Visualizzazione interattiva dei 6 giocatori in campo - Rotazione automatica regolamentare al cambio palla - Configurazione manuale dei numeri di maglia + - Dialog cambi con sostituzione IN/OUT e validazioni - Supporto logica pallavolo ufficiale (25 punti + 2 di vantaggio, tie-break a 15 nel set decisivo) - **Controlli Multimodali** @@ -171,6 +172,7 @@ Serve i file dalla cartella `/dist` per testare la build prima del deploy. | `Ctrl + F` | Attiva/disattiva fullscreen | | `Ctrl + S` | Annuncio vocale punteggio corrente | | `Ctrl + Z` | Switch tra visualizzazione formazioni e punteggio | +| `Ctrl + C` | Apri dialog cambi | --- diff --git a/src/components/HomePage/HomePage.js b/src/components/HomePage/HomePage.js index 96d88ba..d32d011 100644 --- a/src/components/HomePage/HomePage.js +++ b/src/components/HomePage/HomePage.js @@ -301,36 +301,79 @@ export default { window.addEventListener("keydown", this.funzioneTastiSpeciali); }, funzioneTastiSpeciali(e) { - const target = e.target; - if (target && (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable)) { + if (this.diaNomi.show || this.diaCambi.show) { return; } - e.preventDefault(); + + const target = e.target; + const path = typeof e.composedPath === "function" ? e.composedPath() : []; + const elements = [target, ...path].filter(Boolean); + const isTypingField = elements.some((el) => { + if (!el || !el.tagName) { + return false; + } + const tag = String(el.tagName).toLowerCase(); + if (tag === "input" || tag === "textarea") { + return true; + } + if (el.isContentEditable) { + return true; + } + if (el.classList && (el.classList.contains("w-input") || el.classList.contains("w-textarea"))) { + return true; + } + const contentEditable = el.getAttribute && el.getAttribute("contenteditable"); + return contentEditable === "true"; + }); + if (isTypingField) { + return; + } + + let handled = false; if (e.ctrlKey && e.key == "m") { this.diaNomi.show = true + handled = true; } else if (e.ctrlKey && e.key == "b") { this.visuButt = !this.visuButt + handled = true; } else if (e.ctrlKey && e.key == "f") { document.documentElement.requestFullscreen(); + handled = true; } else if (e.ctrlKey && e.key == "s") { this.speak(); + handled = true; } else if (e.ctrlKey && e.key == "z") { this.visuForm = !this.visuForm + handled = true; } else if (e.ctrlKey && e.key == "ArrowUp") { this.incPunt("home") + handled = true; } else if (e.ctrlKey && e.key == "ArrowDown") { this.decPunt("home") + handled = true; } else if (e.ctrlKey && e.key == "ArrowRight") { this.incSet("home") + handled = true; } else if (e.shiftKey && e.key == "ArrowUp") { this.incPunt("guest") + handled = true; } else if (e.shiftKey && e.key == "ArrowDown") { this.decPunt("guest") + handled = true; } else if (e.shiftKey && e.key == "ArrowRight") { this.incSet("guest") + handled = true; } else if (e.ctrlKey && e.key == "ArrowLeft") { this.cambiaPalla() + handled = true; + } else if (e.ctrlKey && (e.key == "c" || e.key == "C")) { + this.apriDialogCambi() + handled = true; } else { return false } + + if (handled) { + e.preventDefault(); + } } } }