From 9711068f8bf39837e14046345386307a2291bf3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Wed, 5 Dec 2018 22:05:51 +0100 Subject: [PATCH] Handle mouse events on touchscreens. Fix #2085 (#2170) * Handle mouse events on touchscreens. Fix #2085 * Some more fixes. Makes listeners non-passive! * Only prevent preventable events. * Different approach * Some travis fixes * Try to avoid clicking while scrolling --- .../common/directives/long-press-directive.ts | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/panels/lovelace/common/directives/long-press-directive.ts b/src/panels/lovelace/common/directives/long-press-directive.ts index 2b59a84d63..718ccbafab 100644 --- a/src/panels/lovelace/common/directives/long-press-directive.ts +++ b/src/panels/lovelace/common/directives/long-press-directive.ts @@ -19,6 +19,8 @@ class LongPress extends HTMLElement implements LongPress { protected ripple: any; protected timer: number | undefined; protected held: boolean; + protected cooldownStart: boolean; + protected cooldownEnd: boolean; constructor() { super(); @@ -26,6 +28,8 @@ class LongPress extends HTMLElement implements LongPress { this.ripple = document.createElement("mwc-ripple"); this.timer = undefined; this.held = false; + this.cooldownStart = false; + this.cooldownEnd = false; } public connectedCallback() { @@ -41,7 +45,8 @@ class LongPress extends HTMLElement implements LongPress { this.ripple.primary = true; [ - isTouch ? "touchcancel" : "mouseout", + "touchcancel", + "mouseout", "mouseup", "touchmove", "mousewheel", @@ -80,6 +85,9 @@ class LongPress extends HTMLElement implements LongPress { }); const clickStart = (ev: Event) => { + if (this.cooldownStart) { + return; + } this.held = false; let x; let y; @@ -94,30 +102,35 @@ class LongPress extends HTMLElement implements LongPress { this.startAnimation(x, y); this.held = true; }, this.holdTime); + + this.cooldownStart = true; + window.setTimeout(() => (this.cooldownStart = false), 100); }; - const clickEnd = () => { - clearTimeout(this.timer); - this.stopAnimation(); - if (isTouch && this.timer === undefined) { + const clickEnd = (ev: Event) => { + if ( + this.cooldownEnd || + (ev instanceof TouchEvent && this.timer === undefined) + ) { return; } + clearTimeout(this.timer); + this.stopAnimation(); this.timer = undefined; if (this.held) { element.dispatchEvent(new Event("ha-hold")); } else { element.dispatchEvent(new Event("ha-click")); } + this.cooldownEnd = true; + window.setTimeout(() => (this.cooldownEnd = false), 100); }; - if (isTouch) { - element.addEventListener("touchstart", clickStart, { passive: true }); - element.addEventListener("touchend", clickEnd); - element.addEventListener("touchcancel", clickEnd); - } else { - element.addEventListener("mousedown", clickStart, { passive: true }); - element.addEventListener("click", clickEnd); - } + element.addEventListener("touchstart", clickStart, { passive: true }); + element.addEventListener("touchend", clickEnd); + element.addEventListener("touchcancel", clickEnd); + element.addEventListener("mousedown", clickStart, { passive: true }); + element.addEventListener("click", clickEnd); } private startAnimation(x: number, y: number) {