Add popup fullscreen and timeout options

This commit is contained in:
Thomas Lovén 2022-07-16 22:25:35 +00:00
parent 09faf4a286
commit e9f40aba93
5 changed files with 249 additions and 66 deletions

View File

@ -821,12 +821,22 @@ const t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e
class BrowserModPopup extends s { class BrowserModPopup extends s {
closeDialog() { closeDialog() {
this.open = false; this.open = false;
clearInterval(this._timeoutTimer);
} }
openDialog() { openDialog() {
this.open = true; this.open = true;
if (this.timeout) {
this.timeoutStart = new Date().getTime();
this._timeoutTimer = setInterval(() => {
const ellapsed = new Date().getTime() - this.timeoutStart;
const progress = (ellapsed / this.timeout) * 100;
this.style.setProperty("--progress", `${progress}%`);
if (ellapsed >= this.timeout)
this._timeout();
}, 10);
} }
async setupDialog(title, content, { primary_action = undefined, secondary_action = undefined, dismissable = true, }) { }
this.dismissable = dismissable; async setupDialog(title, content, { primary_action = undefined, secondary_action = undefined, dismissable = true, timeout = undefined, callbacks = undefined, } = {}) {
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
@ -841,26 +851,38 @@ class BrowserModPopup extends s {
// Basic HTML content // Basic HTML content
this.content = o(content); this.content = o(content);
} }
if (primary_action) {
this.primary_action = primary_action; this.primary_action = primary_action;
this.secondary_action = secondary_action; this.secondary_action = secondary_action;
this.actions = ""; this.actions = primary_action === undefined ? undefined : "";
this.dismissable = dismissable;
this.timeout = timeout;
this.callbacks = callbacks;
} }
else { _primary() {
this.primary_action = undefined; var _a, _b, _c;
this.secondary_action = undefined; if ((_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.dismiss)
this.actions = undefined; this.callbacks.dismiss = undefined;
this.closeDialog();
(_c = (_b = this.callbacks) === null || _b === void 0 ? void 0 : _b.primary_action) === null || _c === void 0 ? void 0 : _c.call(_b);
} }
_secondary() {
var _a, _b, _c;
if ((_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.dismiss)
this.callbacks.dismiss = undefined;
this.closeDialog();
(_c = (_b = this.callbacks) === null || _b === void 0 ? void 0 : _b.secondary_action) === null || _c === void 0 ? void 0 : _c.call(_b);
} }
_primary_clicked() { _dismiss() {
var _a, _b; var _a, _b;
this.closeDialog(); this.closeDialog();
(_b = (_a = this.primary_action) === null || _a === void 0 ? void 0 : _a.callback) === null || _b === void 0 ? void 0 : _b.call(_a); (_b = (_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.dismiss) === null || _b === void 0 ? void 0 : _b.call(_a);
} }
_secondary_clicked() { _timeout() {
var _a, _b; var _a, _b, _c;
if ((_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.dismiss)
this.callbacks.dismiss = undefined;
this.closeDialog(); this.closeDialog();
(_b = (_a = this.secondary_action) === null || _a === void 0 ? void 0 : _a.callback) === null || _b === void 0 ? void 0 : _b.call(_a); (_c = (_b = this.callbacks) === null || _b === void 0 ? void 0 : _b.timeout) === null || _c === void 0 ? void 0 : _c.call(_b);
} }
render() { render() {
if (!this.open) if (!this.open)
@ -868,12 +890,15 @@ class BrowserModPopup extends s {
return $ ` return $ `
<ha-dialog <ha-dialog
open open
@closed=${this.closeDialog} @closed=${this._dismiss}
.heading=${this.title !== undefined} .heading=${this.title !== undefined}
?hideActions=${this.actions === undefined} ?hideActions=${this.actions === undefined}
.scrimClickAction=${this.dismissable ? undefined : ""} .scrimClickAction=${this.dismissable ? this._dismiss : ""}
.escapeKeyAction=${this.dismissable ? undefined : ""} .escapeKeyAction=${this.dismissable ? this._dismiss : ""}
> >
${this.timeout
? $ ` <div slot="heading" class="progress"></div> `
: ""}
${this.title ${this.title
? $ ` ? $ `
<app-toolbar slot="heading"> <app-toolbar slot="heading">
@ -895,8 +920,8 @@ class BrowserModPopup extends s {
? $ ` ? $ `
<mwc-button <mwc-button
slot="primaryAction" slot="primaryAction"
.label=${this.primary_action.label} .label=${this.primary_action}
@click=${this._primary_clicked} @click=${this._primary}
></mwc-button> ></mwc-button>
` `
: ""} : ""}
@ -904,8 +929,8 @@ class BrowserModPopup extends s {
? $ ` ? $ `
<mwc-button <mwc-button
slot="secondaryAction" slot="secondaryAction"
.label=${this.secondary_action.label} .label=${this.secondary_action}
@click=${this._secondary_clicked} @click=${this._secondary}
></mwc-button> ></mwc-button>
` `
: ""} : ""}
@ -929,6 +954,27 @@ class BrowserModPopup extends s {
var(--card-background-color, white) var(--card-background-color, white)
); );
} }
:host([wide]) ha-dialog {
--mdc-dialog-max-width: 90vw;
}
:host([fullscreen]) ha-dialog {
--mdc-dialog-min-width: 100vw;
--mdc-dialog-max-width: 100vw;
--mdc-dialog-min-height: 100%;
--mdc-dialog-max-height: 100%;
--mdc-shape-medium: 0px;
--vertial-align-dialog: flex-end;
}
.progress::before {
content: "";
position: absolute;
left: 0;
width: calc(100% - var(--progress, 60%));
top: 0;
height: 2px;
background: var(--primary-color);
z-index: 10;
}
app-toolbar { app-toolbar {
flex-shrink: 0; flex-shrink: 0;
@ -946,15 +992,33 @@ class BrowserModPopup extends s {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.content { .content {
--padding-x: 24px;
--padding-y: 20px;
margin: -20px -24px; margin: -20px -24px;
padding: 20px 24px; padding: var(--padding-y) var(--padding-y);
--header-height: 64px;
--footer-height: 0px;
}
.content:first-child {
--header-height: 0px;
} }
:host([card]) .content { :host([card]) .content {
padding: 0; --padding-x: 0px;
--padding-y: 0px;
} }
:host([actions]) .content { :host([actions]) .content {
border-bottom: 1px solid var(--divider-color); border-bottom: 1px solid var(--divider-color);
--footer-height: 54px;
}
:host([wide]) .content {
width: calc(90vw - 2 * var(--padding-x));
}
:host([fullscreen]) .content {
height: calc(
100vh - var(--header-height) - var(--footer-height) - 2 *
var(--padding-y)
);
} }
@media all and (max-width: 450px), all and (max-height: 500px) { @media all and (max-width: 450px), all and (max-height: 500px) {
@ -1086,8 +1150,38 @@ var pjson = {
/* /*
TODO: TODO:
- Popups - Popups
X Basic popups
- Card-mod integration
X Timeout
X Fullscreen
- Information about interaction requirement
- Information about fullykiosk
- Commands - Commands
- Framework
- ll-custom handling
- Commands
- popup
- close_popup
- more-info
- navigate
- lovelace-reload
- window-reload
- screensaver
- toast?
- Redesign services to target devices
- frontend editor for popup cards
- also screensavers
- Tweaks - Tweaks
- Save sidebar
- Save sidebar per user
- Kiosk mode
- Kiosk mode per user
- Favicon templates
- Title templates
- Quickbar tweaks (ctrl+enter)?
- Video player?
- Media_seek
- Screensavers
*/ */
class BrowserMod extends PopupMixin(BrowserStateMixin(CameraMixin(MediaPlayerMixin(ScreenSaverMixin(FullyMixin(RequireInteractMixin(ConnectionMixin(EventTarget)))))))) { class BrowserMod extends PopupMixin(BrowserStateMixin(CameraMixin(MediaPlayerMixin(ScreenSaverMixin(FullyMixin(RequireInteractMixin(ConnectionMixin(EventTarget)))))))) {
constructor() { constructor() {

View File

@ -112,13 +112,10 @@ loadDevTools().then(() => {
} }
}; };
window.browser_mod.showPopup("Unregister device", `Are you sure you want to unregister device ${deviceID}?`, { window.browser_mod.showPopup("Unregister device", `Are you sure you want to unregister device ${deviceID}?`, {
dismissable: false, primary_action: "Yes",
primary_action: { secondary_action: "No",
label: "Yes", callbacks: {
callback: unregisterCallback, primary_action: unregisterCallback,
},
secondary_action: {
label: "No",
}, },
}); });
} }

View File

@ -41,13 +41,10 @@ loadDevTools().then(() => {
"Unregister device", "Unregister device",
`Are you sure you want to unregister device ${deviceID}?`, `Are you sure you want to unregister device ${deviceID}?`,
{ {
dismissable: false, primary_action: "Yes",
primary_action: { secondary_action: "No",
label: "Yes", callbacks: {
callback: unregisterCallback, primary_action: unregisterCallback,
},
secondary_action: {
label: "No",
}, },
} }
); );

View File

@ -15,8 +15,38 @@ import pjson from "../../package.json";
/* /*
TODO: TODO:
- Popups - Popups
X Basic popups
- Card-mod integration
X Timeout
X Fullscreen
- Information about interaction requirement
- Information about fullykiosk
- Commands - Commands
- Framework
- ll-custom handling
- Commands
- popup
- close_popup
- more-info
- navigate
- lovelace-reload
- window-reload
- screensaver
- toast?
- Redesign services to target devices
- frontend editor for popup cards
- also screensavers
- Tweaks - Tweaks
- Save sidebar
- Save sidebar per user
- Kiosk mode
- Kiosk mode per user
- Favicon templates
- Title templates
- Quickbar tweaks (ctrl+enter)?
- Video player?
- Media_seek
- Screensavers
*/ */
export class BrowserMod extends PopupMixin( export class BrowserMod extends PopupMixin(
BrowserStateMixin( BrowserStateMixin(

View File

@ -12,13 +12,27 @@ class BrowserModPopup extends LitElement {
@property() primary_action; @property() primary_action;
@property() secondary_action; @property() secondary_action;
@property() dismissable; @property() dismissable;
callbacks;
timeout;
timeoutStart;
_timeoutTimer;
closeDialog() { closeDialog() {
this.open = false; this.open = false;
clearInterval(this._timeoutTimer);
} }
openDialog() { openDialog() {
this.open = true; this.open = true;
if (this.timeout) {
this.timeoutStart = new Date().getTime();
this._timeoutTimer = setInterval(() => {
const ellapsed = new Date().getTime() - this.timeoutStart;
const progress = (ellapsed / this.timeout) * 100;
this.style.setProperty("--progress", `${progress}%`);
if (ellapsed >= this.timeout) this._timeout();
}, 10);
}
} }
async setupDialog( async setupDialog(
@ -28,9 +42,10 @@ class BrowserModPopup extends LitElement {
primary_action = undefined, primary_action = undefined,
secondary_action = undefined, secondary_action = undefined,
dismissable = true, dismissable = true,
} timeout = undefined,
callbacks = undefined,
} = {}
) { ) {
this.dismissable = dismissable;
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
@ -44,26 +59,34 @@ class BrowserModPopup extends LitElement {
// Basic HTML content // Basic HTML content
this.content = unsafeHTML(content); this.content = unsafeHTML(content);
} }
if (primary_action) {
this.primary_action = primary_action; this.primary_action = primary_action;
this.secondary_action = secondary_action; this.secondary_action = secondary_action;
this.actions = ""; this.actions = primary_action === undefined ? undefined : "";
} else {
this.primary_action = undefined; this.dismissable = dismissable;
this.secondary_action = undefined; this.timeout = timeout;
this.actions = undefined; this.callbacks = callbacks;
}
} }
_primary_clicked() { _primary() {
if (this.callbacks?.dismiss) this.callbacks.dismiss = undefined;
this.closeDialog(); this.closeDialog();
const eval2 = eval; this.callbacks?.primary_action?.();
this.primary_action?.callback?.();
} }
_secondary_clicked() { _secondary() {
if (this.callbacks?.dismiss) this.callbacks.dismiss = undefined;
this.closeDialog(); this.closeDialog();
const eval2 = eval; this.callbacks?.secondary_action?.();
this.secondary_action?.callback?.(); }
_dismiss() {
this.closeDialog();
this.callbacks?.dismiss?.();
}
_timeout() {
if (this.callbacks?.dismiss) this.callbacks.dismiss = undefined;
this.closeDialog();
this.callbacks?.timeout?.();
} }
render() { render() {
@ -72,12 +95,15 @@ class BrowserModPopup extends LitElement {
return html` return html`
<ha-dialog <ha-dialog
open open
@closed=${this.closeDialog} @closed=${this._dismiss}
.heading=${this.title !== undefined} .heading=${this.title !== undefined}
?hideActions=${this.actions === undefined} ?hideActions=${this.actions === undefined}
.scrimClickAction=${this.dismissable ? undefined : ""} .scrimClickAction=${this.dismissable ? this._dismiss : ""}
.escapeKeyAction=${this.dismissable ? undefined : ""} .escapeKeyAction=${this.dismissable ? this._dismiss : ""}
> >
${this.timeout
? html` <div slot="heading" class="progress"></div> `
: ""}
${this.title ${this.title
? html` ? html`
<app-toolbar slot="heading"> <app-toolbar slot="heading">
@ -99,8 +125,8 @@ class BrowserModPopup extends LitElement {
? html` ? html`
<mwc-button <mwc-button
slot="primaryAction" slot="primaryAction"
.label=${this.primary_action.label} .label=${this.primary_action}
@click=${this._primary_clicked} @click=${this._primary}
></mwc-button> ></mwc-button>
` `
: ""} : ""}
@ -108,8 +134,8 @@ class BrowserModPopup extends LitElement {
? html` ? html`
<mwc-button <mwc-button
slot="secondaryAction" slot="secondaryAction"
.label=${this.secondary_action.label} .label=${this.secondary_action}
@click=${this._secondary_clicked} @click=${this._secondary}
></mwc-button> ></mwc-button>
` `
: ""} : ""}
@ -134,6 +160,27 @@ class BrowserModPopup extends LitElement {
var(--card-background-color, white) var(--card-background-color, white)
); );
} }
:host([wide]) ha-dialog {
--mdc-dialog-max-width: 90vw;
}
:host([fullscreen]) ha-dialog {
--mdc-dialog-min-width: 100vw;
--mdc-dialog-max-width: 100vw;
--mdc-dialog-min-height: 100%;
--mdc-dialog-max-height: 100%;
--mdc-shape-medium: 0px;
--vertial-align-dialog: flex-end;
}
.progress::before {
content: "";
position: absolute;
left: 0;
width: calc(100% - var(--progress, 60%));
top: 0;
height: 2px;
background: var(--primary-color);
z-index: 10;
}
app-toolbar { app-toolbar {
flex-shrink: 0; flex-shrink: 0;
@ -151,15 +198,33 @@ class BrowserModPopup extends LitElement {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.content { .content {
--padding-x: 24px;
--padding-y: 20px;
margin: -20px -24px; margin: -20px -24px;
padding: 20px 24px; padding: var(--padding-y) var(--padding-y);
--header-height: 64px;
--footer-height: 0px;
}
.content:first-child {
--header-height: 0px;
} }
:host([card]) .content { :host([card]) .content {
padding: 0; --padding-x: 0px;
--padding-y: 0px;
} }
:host([actions]) .content { :host([actions]) .content {
border-bottom: 1px solid var(--divider-color); border-bottom: 1px solid var(--divider-color);
--footer-height: 54px;
}
:host([wide]) .content {
width: calc(90vw - 2 * var(--padding-x));
}
:host([fullscreen]) .content {
height: calc(
100vh - var(--header-height) - var(--footer-height) - 2 *
var(--padding-y)
);
} }
@media all and (max-width: 450px), all and (max-height: 500px) { @media all and (max-width: 450px), all and (max-height: 500px) {