From d5bc498373fc9822789b30ae6d54d948eb8d4a06 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 7 Sep 2020 13:41:59 +0200 Subject: [PATCH] Fix action handler bugs (#6811) --- src/components/ha-sidebar.ts | 6 ++++ .../directives/action-handler-directive.ts | 32 +++++++++---------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts index 12b1c17d39..2f6c72bb4b 100644 --- a/src/components/ha-sidebar.ts +++ b/src/components/ha-sidebar.ts @@ -31,6 +31,7 @@ import memoizeOne from "memoize-one"; import { LocalStorage } from "../common/decorators/local-storage"; import { fireEvent } from "../common/dom/fire_event"; import { computeDomain } from "../common/entity/compute_domain"; +import { navigate } from "../common/navigate"; import { compare } from "../common/string/compare"; import { computeRTL } from "../common/util/compute_rtl"; import { ActionHandlerDetail } from "../data/lovelace"; @@ -649,6 +650,10 @@ class HaSidebar extends LitElement { ); } + private _handlePanelTap(ev: Event) { + navigate(this, (ev.currentTarget as HTMLAnchorElement).href); + } + private _renderPanel( urlPath: string, title: string | null, @@ -661,6 +666,7 @@ class HaSidebar extends LitElement { href="${`/${urlPath}`}" data-panel="${urlPath}" tabindex="-1" + @tap=${this._handlePanelTap} @mouseenter=${this._itemMouseEnter} @mouseleave=${this._itemMouseLeave} > diff --git a/src/panels/lovelace/common/directives/action-handler-directive.ts b/src/panels/lovelace/common/directives/action-handler-directive.ts index 09dc3c4351..0c245a4764 100644 --- a/src/panels/lovelace/common/directives/action-handler-directive.ts +++ b/src/panels/lovelace/common/directives/action-handler-directive.ts @@ -44,6 +44,8 @@ class ActionHandler extends HTMLElement implements ActionHandler { protected held = false; + private cancelled = false; + private dblClickTimeout?: number; constructor() { @@ -76,9 +78,12 @@ class ActionHandler extends HTMLElement implements ActionHandler { document.addEventListener( ev, () => { - clearTimeout(this.timer); - this.stopAnimation(); - this.timer = undefined; + this.cancelled = true; + if (this.timer) { + this.stopAnimation(); + clearTimeout(this.timer); + this.timer = undefined; + } }, { passive: true } ); @@ -124,7 +129,7 @@ class ActionHandler extends HTMLElement implements ActionHandler { } element.actionHandler.start = (ev: Event) => { - this.held = false; + this.cancelled = false; let x; let y; if ((ev as TouchEvent).touches) { @@ -136,6 +141,7 @@ class ActionHandler extends HTMLElement implements ActionHandler { } if (options.hasHold) { + this.held = false; this.timer = window.setTimeout(() => { this.startAnimation(x, y); this.held = true; @@ -144,24 +150,20 @@ class ActionHandler extends HTMLElement implements ActionHandler { }; element.actionHandler.end = (ev: Event) => { - // Don't respond on our own generated click - if (!ev.isTrusted) { + // Don't respond when moved or scrolled while touch + if (["touchend", "touchcancel"].includes(ev.type) && this.cancelled) { return; } // Prevent mouse event if touch event - ev.preventDefault(); + if (ev.cancelable) { + ev.preventDefault(); + } if (options.hasHold) { - if ( - ["touchend", "touchcancel"].includes(ev.type) && - this.timer === undefined - ) { - return; - } clearTimeout(this.timer); this.stopAnimation(); this.timer = undefined; } - if (this.held) { + if (options.hasHold && this.held) { fireEvent(element, "action", { action: "hold" }); } else if (options.hasDoubleClick) { if ( @@ -179,8 +181,6 @@ class ActionHandler extends HTMLElement implements ActionHandler { } } else { fireEvent(element, "action", { action: "tap" }); - // Fire the click we prevented the action for - (ev.target as HTMLElement)?.click(); } };