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
This commit is contained in:
Thomas Lovén 2018-12-05 22:05:51 +01:00 committed by Paulus Schoutsen
parent fb180c7b9b
commit 9711068f8b

View File

@ -19,6 +19,8 @@ class LongPress extends HTMLElement implements LongPress {
protected ripple: any; protected ripple: any;
protected timer: number | undefined; protected timer: number | undefined;
protected held: boolean; protected held: boolean;
protected cooldownStart: boolean;
protected cooldownEnd: boolean;
constructor() { constructor() {
super(); super();
@ -26,6 +28,8 @@ class LongPress extends HTMLElement implements LongPress {
this.ripple = document.createElement("mwc-ripple"); this.ripple = document.createElement("mwc-ripple");
this.timer = undefined; this.timer = undefined;
this.held = false; this.held = false;
this.cooldownStart = false;
this.cooldownEnd = false;
} }
public connectedCallback() { public connectedCallback() {
@ -41,7 +45,8 @@ class LongPress extends HTMLElement implements LongPress {
this.ripple.primary = true; this.ripple.primary = true;
[ [
isTouch ? "touchcancel" : "mouseout", "touchcancel",
"mouseout",
"mouseup", "mouseup",
"touchmove", "touchmove",
"mousewheel", "mousewheel",
@ -80,6 +85,9 @@ class LongPress extends HTMLElement implements LongPress {
}); });
const clickStart = (ev: Event) => { const clickStart = (ev: Event) => {
if (this.cooldownStart) {
return;
}
this.held = false; this.held = false;
let x; let x;
let y; let y;
@ -94,30 +102,35 @@ class LongPress extends HTMLElement implements LongPress {
this.startAnimation(x, y); this.startAnimation(x, y);
this.held = true; this.held = true;
}, this.holdTime); }, this.holdTime);
this.cooldownStart = true;
window.setTimeout(() => (this.cooldownStart = false), 100);
}; };
const clickEnd = () => { const clickEnd = (ev: Event) => {
clearTimeout(this.timer); if (
this.stopAnimation(); this.cooldownEnd ||
if (isTouch && this.timer === undefined) { (ev instanceof TouchEvent && this.timer === undefined)
) {
return; return;
} }
clearTimeout(this.timer);
this.stopAnimation();
this.timer = undefined; this.timer = undefined;
if (this.held) { if (this.held) {
element.dispatchEvent(new Event("ha-hold")); element.dispatchEvent(new Event("ha-hold"));
} else { } else {
element.dispatchEvent(new Event("ha-click")); 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("touchstart", clickStart, { passive: true }); element.addEventListener("touchend", clickEnd);
element.addEventListener("touchend", clickEnd); element.addEventListener("touchcancel", clickEnd);
element.addEventListener("touchcancel", clickEnd); element.addEventListener("mousedown", clickStart, { passive: true });
} else { element.addEventListener("click", clickEnd);
element.addEventListener("mousedown", clickStart, { passive: true });
element.addEventListener("click", clickEnd);
}
} }
private startAnimation(x: number, y: number) { private startAnimation(x: number, y: number) {