Add autoclose option to popups

This commit is contained in:
Thomas Lovén 2022-07-25 22:52:22 +00:00
parent 947735292a
commit b71197d003
5 changed files with 67 additions and 24 deletions

View File

@ -1082,19 +1082,22 @@ const ActivityMixin = (SuperClass) => {
this.activityTriggered = false; this.activityTriggered = false;
this._activityCooldown = 15000; this._activityCooldown = 15000;
for (const ev of ["pointerdown", "pointermove", "keydown"]) { for (const ev of ["pointerdown", "pointermove", "keydown"]) {
window.addEventListener(ev, () => this.activityTrigger()); window.addEventListener(ev, () => this.activityTrigger(true));
} }
this.addEventListener("fully-update", () => { this.addEventListener("fully-update", () => {
this.activityTrigger(); this.activityTrigger();
}); });
} }
activityTrigger() { activityTrigger(touched = false) {
if (!this.activityTriggered) { if (!this.activityTriggered) {
this.sendUpdate({ this.sendUpdate({
activity: true, activity: true,
}); });
} }
this.activityTriggered = true; this.activityTriggered = true;
if (touched) {
this.fireEvent("browser-mod-activity");
}
clearTimeout(this._activityTimeout); clearTimeout(this._activityTimeout);
this._activityTimeout = setTimeout(() => this.activityReset(), this._activityCooldown); this._activityTimeout = setTimeout(() => this.activityReset(), this._activityCooldown);
} }
@ -1124,18 +1127,18 @@ const t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e
*/class e extends i{constructor(i){if(super(i),this.it=w,i.type!==t.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(r){if(r===w||null==r)return this.ft=void 0,this.it=r;if(r===b)return r;if("string"!=typeof r)throw Error(this.constructor.directiveName+"() called with a non-string value");if(r===this.it)return this.ft;this.it=r;const s=[r];return s.raw=s,this.ft={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName="unsafeHTML",e.resultType=1;const o=e$1(e); */class e extends i{constructor(i){if(super(i),this.it=w,i.type!==t.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(r){if(r===w||null==r)return this.ft=void 0,this.it=r;if(r===b)return r;if("string"!=typeof r)throw Error(this.constructor.directiveName+"() called with a non-string value");if(r===this.it)return this.ft;this.it=r;const s=[r];return s.raw=s,this.ft={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName="unsafeHTML",e.resultType=1;const o=e$1(e);
class BrowserModPopup extends s { class BrowserModPopup extends s {
closedCallback() {
var _a;
(_a = this._resolveClosed) === null || _a === void 0 ? void 0 : _a.call(this);
this._resolveClosed = undefined;
}
async closeDialog() { async closeDialog() {
this.open = false; this.open = false;
await new Promise((resolve) => (this._resolveClosed = resolve));
clearInterval(this._timeoutTimer); clearInterval(this._timeoutTimer);
if (this._autocloseListener) {
window.browser_mod.removeEventListener("browser-mod-activity", this._autocloseListener);
this._autocloseListener = undefined;
}
} }
openDialog() { openDialog() {
var _a;
this.open = true; this.open = true;
(_a = this.dialog) === null || _a === void 0 ? void 0 : _a.show();
if (this.timeout) { if (this.timeout) {
this._timeoutStart = new Date().getTime(); this._timeoutStart = new Date().getTime();
this._timeoutTimer = setInterval(() => { this._timeoutTimer = setInterval(() => {
@ -1146,8 +1149,13 @@ class BrowserModPopup extends s {
this._timeout(); this._timeout();
}, 10); }, 10);
} }
this._autocloseListener = undefined;
if (this._autoclose) {
this._autocloseListener = this._dismiss.bind(this);
window.browser_mod.addEventListener("browser-mod-activity", this._autocloseListener);
} }
async setupDialog(title, content, { right_button = undefined, right_button_action = undefined, left_button = undefined, left_button_action = undefined, dismissable = true, dismiss_action = undefined, timeout = undefined, timeout_action = undefined, size = undefined, style = undefined, } = {}) { }
async setupDialog(title, content, { right_button = undefined, right_button_action = undefined, left_button = undefined, left_button_action = undefined, dismissable = true, dismiss_action = undefined, timeout = undefined, timeout_action = undefined, size = undefined, style = undefined, autoclose = false, } = {}) {
this.title = title; this.title = title;
if (content && typeof content === "object") { if (content && typeof content === "object") {
// Create a card from config in content // Create a card from config in content
@ -1177,6 +1185,7 @@ class BrowserModPopup extends s {
this.wide = size === "wide" ? "" : undefined; this.wide = size === "wide" ? "" : undefined;
this.fullscreen = size === "fullscreen" ? "" : undefined; this.fullscreen = size === "fullscreen" ? "" : undefined;
this._style = style; this._style = style;
this._autoclose = autoclose;
} }
async _primary() { async _primary() {
var _a, _b, _c; var _a, _b, _c;
@ -1210,7 +1219,6 @@ class BrowserModPopup extends s {
return $ ` return $ `
<ha-dialog <ha-dialog
open open
@closed=${this.closedCallback}
.heading=${this.title !== undefined} .heading=${this.title !== undefined}
?hideActions=${this.actions === undefined} ?hideActions=${this.actions === undefined}
.scrimClickAction=${this.dismissable ? this._dismiss : ""} .scrimClickAction=${this.dismissable ? this._dismiss : ""}
@ -1399,6 +1407,9 @@ __decorate([
__decorate([ __decorate([
e$2() e$2()
], BrowserModPopup.prototype, "_style", void 0); ], BrowserModPopup.prototype, "_style", void 0);
__decorate([
i$1("ha-dialog")
], BrowserModPopup.prototype, "dialog", void 0);
if (!customElements.get("browser-mod-popup")) if (!customElements.get("browser-mod-popup"))
customElements.define("browser-mod-popup", BrowserModPopup); customElements.define("browser-mod-popup", BrowserModPopup);
const PopupMixin = (SuperClass) => { const PopupMixin = (SuperClass) => {
@ -2125,16 +2136,20 @@ const BrowserIDMixin = (SuperClass) => {
x ll-custom handling x ll-custom handling
- Commands - Commands
x popup x popup
x Auto-close
x close_popup x close_popup
x more-info x more-info
x navigate x navigate
- lovelace-reload? - lovelace-reload?
- Not needed
x window-reload x window-reload
- screensaver ? - screensaver ?
- Refer to automations instead
x sequence x sequence
x delay x delay
x javascript eval x javascript eval
- toast? - toast?
- Replaced with popups with timeout
x Redesign services to target devices x Redesign services to target devices
x frontend editor for popup cards x frontend editor for popup cards
- also screensavers - also screensavers
@ -2152,7 +2167,8 @@ const BrowserIDMixin = (SuperClass) => {
- Video player? - Video player?
- Media_seek - Media_seek
- Screensavers - Screensavers
- IMPORTANT: FIX DEFAULT HIDING OF ENTITIES x IMPORTANT: FIX DEFAULT HIDING OF ENTITIES
- NOFIX. Home Assistant bug
X Check functionality with CAST - may need to add frontend part as a lovelace resource X Check functionality with CAST - may need to add frontend part as a lovelace resource
*/ */
class BrowserMod extends ServicesMixin(PopupMixin(ActivityMixin(BrowserStateMixin(CameraMixin(MediaPlayerMixin(ScreenSaverMixin(AutoSettingsMixin(FullyMixin(RequireInteractMixin(ConnectionMixin(BrowserIDMixin(EventTarget)))))))))))) { class BrowserMod extends ServicesMixin(PopupMixin(ActivityMixin(BrowserStateMixin(CameraMixin(MediaPlayerMixin(ScreenSaverMixin(AutoSettingsMixin(FullyMixin(RequireInteractMixin(ConnectionMixin(BrowserIDMixin(EventTarget)))))))))))) {

View File

@ -101,6 +101,12 @@ popup:
description: Action to perform when popup is dismissed description: Action to perform when popup is dismissed
selector: selector:
object: object:
autoclose:
name: Auto close
description: Close the popup automatically on mouse, pointer or keyboard activity
default: false
selector:
boolean:
timeout: timeout:
name: Auto close timeout name: Auto close timeout
description: Time before closing (ms) description: Time before closing (ms)

View File

@ -6,20 +6,23 @@ export const ActivityMixin = (SuperClass) => {
constructor() { constructor() {
super(); super();
for (const ev of ["pointerdown", "pointermove", "keydown"]) { for (const ev of ["pointerdown", "pointermove", "keydown"]) {
window.addEventListener(ev, () => this.activityTrigger()); window.addEventListener(ev, () => this.activityTrigger(true));
} }
this.addEventListener("fully-update", () => { this.addEventListener("fully-update", () => {
this.activityTrigger(); this.activityTrigger();
}); });
} }
activityTrigger() { activityTrigger(touched = false) {
if (!this.activityTriggered) { if (!this.activityTriggered) {
this.sendUpdate({ this.sendUpdate({
activity: true, activity: true,
}); });
} }
this.activityTriggered = true; this.activityTriggered = true;
if (touched) {
this.fireEvent("browser-mod-activity");
}
clearTimeout(this._activityTimeout); clearTimeout(this._activityTimeout);
this._activityTimeout = setTimeout( this._activityTimeout = setTimeout(
() => this.activityReset(), () => this.activityReset(),

View File

@ -39,16 +39,20 @@ import { BrowserIDMixin } from "./browserID";
x ll-custom handling x ll-custom handling
- Commands - Commands
x popup x popup
x Auto-close
x close_popup x close_popup
x more-info x more-info
x navigate x navigate
- lovelace-reload? - lovelace-reload?
- Not needed
x window-reload x window-reload
- screensaver ? - screensaver ?
- Refer to automations instead
x sequence x sequence
x delay x delay
x javascript eval x javascript eval
- toast? - toast?
- Replaced with popups with timeout
x Redesign services to target devices x Redesign services to target devices
x frontend editor for popup cards x frontend editor for popup cards
- also screensavers - also screensavers
@ -66,7 +70,8 @@ import { BrowserIDMixin } from "./browserID";
- Video player? - Video player?
- Media_seek - Media_seek
- Screensavers - Screensavers
- IMPORTANT: FIX DEFAULT HIDING OF ENTITIES x IMPORTANT: FIX DEFAULT HIDING OF ENTITIES
- NOFIX. Home Assistant bug
X Check functionality with CAST - may need to add frontend part as a lovelace resource X Check functionality with CAST - may need to add frontend part as a lovelace resource
*/ */
export class BrowserMod extends ServicesMixin( export class BrowserMod extends ServicesMixin(

View File

@ -1,5 +1,5 @@
import { LitElement, html, css } from "lit"; import { LitElement, html, css } from "lit";
import { property } from "lit/decorators.js"; import { property, query } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js"; import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { provideHass, loadLoadCardHelpers, hass_base_el } from "../helpers"; import { provideHass, loadLoadCardHelpers, hass_base_el } from "../helpers";
@ -16,27 +16,31 @@ class BrowserModPopup extends LitElement {
@property() dismissable; @property() dismissable;
@property({ reflect: true }) wide; @property({ reflect: true }) wide;
@property({ reflect: true }) fullscreen; @property({ reflect: true }) fullscreen;
@property() _style;
@query("ha-dialog") dialog: any;
_autoclose;
_autocloseListener;
_actions; _actions;
timeout; timeout;
_timeoutStart; _timeoutStart;
_timeoutTimer; _timeoutTimer;
@property() _style;
_resolveClosed; _resolveClosed;
closedCallback() {
this._resolveClosed?.();
this._resolveClosed = undefined;
}
async closeDialog() { async closeDialog() {
this.open = false; this.open = false;
await new Promise((resolve) => (this._resolveClosed = resolve));
clearInterval(this._timeoutTimer); clearInterval(this._timeoutTimer);
if (this._autocloseListener) {
window.browser_mod.removeEventListener(
"browser-mod-activity",
this._autocloseListener
);
this._autocloseListener = undefined;
}
} }
openDialog() { openDialog() {
this.open = true; this.open = true;
this.dialog?.show();
if (this.timeout) { if (this.timeout) {
this._timeoutStart = new Date().getTime(); this._timeoutStart = new Date().getTime();
this._timeoutTimer = setInterval(() => { this._timeoutTimer = setInterval(() => {
@ -46,6 +50,14 @@ class BrowserModPopup extends LitElement {
if (ellapsed >= this.timeout) this._timeout(); if (ellapsed >= this.timeout) this._timeout();
}, 10); }, 10);
} }
this._autocloseListener = undefined;
if (this._autoclose) {
this._autocloseListener = this._dismiss.bind(this);
window.browser_mod.addEventListener(
"browser-mod-activity",
this._autocloseListener
);
}
} }
async setupDialog( async setupDialog(
@ -62,6 +74,7 @@ class BrowserModPopup extends LitElement {
timeout_action = undefined, timeout_action = undefined,
size = undefined, size = undefined,
style = undefined, style = undefined,
autoclose = false,
} = {} } = {}
) { ) {
this.title = title; this.title = title;
@ -94,6 +107,7 @@ class BrowserModPopup extends LitElement {
this.wide = size === "wide" ? "" : undefined; this.wide = size === "wide" ? "" : undefined;
this.fullscreen = size === "fullscreen" ? "" : undefined; this.fullscreen = size === "fullscreen" ? "" : undefined;
this._style = style; this._style = style;
this._autoclose = autoclose;
} }
async _primary() { async _primary() {
@ -122,7 +136,6 @@ class BrowserModPopup extends LitElement {
return html` return html`
<ha-dialog <ha-dialog
open open
@closed=${this.closedCallback}
.heading=${this.title !== undefined} .heading=${this.title !== undefined}
?hideActions=${this.actions === undefined} ?hideActions=${this.actions === undefined}
.scrimClickAction=${this.dismissable ? this._dismiss : ""} .scrimClickAction=${this.dismissable ? this._dismiss : ""}