diff --git a/.changeset/cold-hairs-sit.md b/.changeset/cold-hairs-sit.md new file mode 100644 index 00000000..60a7ac1c --- /dev/null +++ b/.changeset/cold-hairs-sit.md @@ -0,0 +1,5 @@ +--- +'@theoplayer/web-ui': patch +--- + +Fixed an issue where buttons inside the default UI could accidentally be clicked even when they were hidden because of user inactivity. diff --git a/src/DefaultUI.ts b/src/DefaultUI.ts index c1be2235..e01e7bc5 100644 --- a/src/DefaultUI.ts +++ b/src/DefaultUI.ts @@ -12,6 +12,7 @@ import type { TimeRange } from './components/TimeRange'; import { STREAM_TYPE_CHANGE_EVENT } from './events/StreamTypeChangeEvent'; import { USER_IDLE_CHANGE_EVENT } from './events/UserIdleChangeEvent'; import { READY_EVENT } from './events/ReadyEvent'; +import { ACCIDENTAL_CLICK_DELAY } from './util/Constants'; import { toggleAttribute } from './util/CommonUtils'; import { createCustomEvent } from './util/EventUtils'; import { createTemplate } from './util/TemplateUtils'; @@ -343,7 +344,7 @@ export class DefaultUI extends HTMLElement { // but wait a little bit to prevent accidentally clicking the seekbar. this._timeRangeInertTimeout = setTimeout(() => { this._timeRange!.inert = false; - }, 50); + }, ACCIDENTAL_CLICK_DELAY); } } this.dispatchEvent(createCustomEvent(USER_IDLE_CHANGE_EVENT)); diff --git a/src/UIContainer.ts b/src/UIContainer.ts index 4ac4c6f7..9d7f5f27 100644 --- a/src/UIContainer.ts +++ b/src/UIContainer.ts @@ -38,6 +38,7 @@ import { isArrowKey, isBackKey, KeyCode } from './util/KeyCode'; import { READY_EVENT } from './events/ReadyEvent'; import { createTemplate } from './util/TemplateUtils'; import { addGlobalStyles } from './Global'; +import { ACCIDENTAL_CLICK_DELAY } from './util/Constants'; // Load components used in template import './components/GestureReceiver'; @@ -1092,7 +1093,7 @@ export class UIContainer extends HTMLElement { private readonly _onClickAfterPointerUp = (event: MouseEvent): void => { this.removeEventListener('click', this._onClickAfterPointerUp, true); - if (performance.now() - this._lastPointerUpTime < 10) { + if (performance.now() - this._lastPointerUpTime < ACCIDENTAL_CLICK_DELAY) { event.preventDefault(); event.stopPropagation(); } diff --git a/src/util/Constants.ts b/src/util/Constants.ts new file mode 100644 index 00000000..a19839ff --- /dev/null +++ b/src/util/Constants.ts @@ -0,0 +1,10 @@ +/** + * The delay before we should start handling clicks + * after the user becomes active again (in milliseconds). + * + * When the user is idle and then touches the player, that first touch + * should not trigger any accidental clicks on UI controls. Therefore, + * we will keep all UI controls inactive for a little bit longer + * after that first touch, until this delay has passed. + */ +export const ACCIDENTAL_CLICK_DELAY = 50;