diff --git a/custom_components/browser_mod/browser_mod.js b/custom_components/browser_mod/browser_mod.js index 894bcda..5edbbb3 100644 --- a/custom_components/browser_mod/browser_mod.js +++ b/custom_components/browser_mod/browser_mod.js @@ -821,12 +821,22 @@ const t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e class BrowserModPopup extends s { closeDialog() { this.open = false; + clearInterval(this._timeoutTimer); } openDialog() { 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; if (content && typeof content === "object") { // Create a card from config in content @@ -841,26 +851,38 @@ class BrowserModPopup extends s { // Basic HTML content this.content = o(content); } - if (primary_action) { - this.primary_action = primary_action; - this.secondary_action = secondary_action; - this.actions = ""; - } - else { - this.primary_action = undefined; - this.secondary_action = undefined; - this.actions = undefined; - } + this.primary_action = primary_action; + this.secondary_action = secondary_action; + this.actions = primary_action === undefined ? undefined : ""; + this.dismissable = dismissable; + this.timeout = timeout; + this.callbacks = callbacks; } - _primary_clicked() { + _primary() { + 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.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); + } + _dismiss() { var _a, _b; 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() { - var _a, _b; + _timeout() { + var _a, _b, _c; + if ((_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.dismiss) + this.callbacks.dismiss = undefined; 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() { if (!this.open) @@ -868,12 +890,15 @@ class BrowserModPopup extends s { return $ ` + ${this.timeout + ? $ `
` + : ""} ${this.title ? $ ` @@ -895,8 +920,8 @@ class BrowserModPopup extends s { ? $ ` ` : ""} @@ -904,8 +929,8 @@ class BrowserModPopup extends s { ? $ ` ` : ""} @@ -929,6 +954,27 @@ class BrowserModPopup extends s { 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 { flex-shrink: 0; @@ -946,15 +992,33 @@ class BrowserModPopup extends s { text-overflow: ellipsis; } .content { + --padding-x: 24px; + --padding-y: 20px; 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 { - padding: 0; + --padding-x: 0px; + --padding-y: 0px; } :host([actions]) .content { 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) { @@ -1086,8 +1150,38 @@ var pjson = { /* TODO: - Popups + X Basic popups + - Card-mod integration + X Timeout + X Fullscreen + - Information about interaction requirement + - Information about fullykiosk - 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 + - 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)))))))) { constructor() { diff --git a/custom_components/browser_mod/browser_mod_panel.js b/custom_components/browser_mod/browser_mod_panel.js index b65993b..417359e 100644 --- a/custom_components/browser_mod/browser_mod_panel.js +++ b/custom_components/browser_mod/browser_mod_panel.js @@ -112,13 +112,10 @@ loadDevTools().then(() => { } }; window.browser_mod.showPopup("Unregister device", `Are you sure you want to unregister device ${deviceID}?`, { - dismissable: false, - primary_action: { - label: "Yes", - callback: unregisterCallback, - }, - secondary_action: { - label: "No", + primary_action: "Yes", + secondary_action: "No", + callbacks: { + primary_action: unregisterCallback, }, }); } diff --git a/js/config_panel/main.ts b/js/config_panel/main.ts index 9c5aa68..640dfd6 100644 --- a/js/config_panel/main.ts +++ b/js/config_panel/main.ts @@ -41,13 +41,10 @@ loadDevTools().then(() => { "Unregister device", `Are you sure you want to unregister device ${deviceID}?`, { - dismissable: false, - primary_action: { - label: "Yes", - callback: unregisterCallback, - }, - secondary_action: { - label: "No", + primary_action: "Yes", + secondary_action: "No", + callbacks: { + primary_action: unregisterCallback, }, } ); diff --git a/js/plugin/main.ts b/js/plugin/main.ts index de1ffff..dc253ed 100644 --- a/js/plugin/main.ts +++ b/js/plugin/main.ts @@ -15,8 +15,38 @@ import pjson from "../../package.json"; /* TODO: - Popups + X Basic popups + - Card-mod integration + X Timeout + X Fullscreen + - Information about interaction requirement + - Information about fullykiosk - 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 + - 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( BrowserStateMixin( diff --git a/js/plugin/popups.ts b/js/plugin/popups.ts index c12553b..436d456 100644 --- a/js/plugin/popups.ts +++ b/js/plugin/popups.ts @@ -12,13 +12,27 @@ class BrowserModPopup extends LitElement { @property() primary_action; @property() secondary_action; @property() dismissable; + callbacks; + timeout; + timeoutStart; + _timeoutTimer; closeDialog() { this.open = false; + clearInterval(this._timeoutTimer); } openDialog() { 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( @@ -28,9 +42,10 @@ class BrowserModPopup extends LitElement { primary_action = undefined, secondary_action = undefined, dismissable = true, - } + timeout = undefined, + callbacks = undefined, + } = {} ) { - this.dismissable = dismissable; this.title = title; if (content && typeof content === "object") { // Create a card from config in content @@ -44,26 +59,34 @@ class BrowserModPopup extends LitElement { // Basic HTML content this.content = unsafeHTML(content); } - if (primary_action) { - this.primary_action = primary_action; - this.secondary_action = secondary_action; - this.actions = ""; - } else { - this.primary_action = undefined; - this.secondary_action = undefined; - this.actions = undefined; - } + + this.primary_action = primary_action; + this.secondary_action = secondary_action; + this.actions = primary_action === undefined ? undefined : ""; + + this.dismissable = dismissable; + this.timeout = timeout; + this.callbacks = callbacks; } - _primary_clicked() { + _primary() { + if (this.callbacks?.dismiss) this.callbacks.dismiss = undefined; this.closeDialog(); - const eval2 = eval; - this.primary_action?.callback?.(); + this.callbacks?.primary_action?.(); } - _secondary_clicked() { + _secondary() { + if (this.callbacks?.dismiss) this.callbacks.dismiss = undefined; this.closeDialog(); - const eval2 = eval; - this.secondary_action?.callback?.(); + this.callbacks?.secondary_action?.(); + } + _dismiss() { + this.closeDialog(); + this.callbacks?.dismiss?.(); + } + _timeout() { + if (this.callbacks?.dismiss) this.callbacks.dismiss = undefined; + this.closeDialog(); + this.callbacks?.timeout?.(); } render() { @@ -72,12 +95,15 @@ class BrowserModPopup extends LitElement { return html` + ${this.timeout + ? html`
` + : ""} ${this.title ? html` @@ -99,8 +125,8 @@ class BrowserModPopup extends LitElement { ? html` ` : ""} @@ -108,8 +134,8 @@ class BrowserModPopup extends LitElement { ? html` ` : ""} @@ -134,6 +160,27 @@ class BrowserModPopup extends LitElement { 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 { flex-shrink: 0; @@ -151,15 +198,33 @@ class BrowserModPopup extends LitElement { text-overflow: ellipsis; } .content { + --padding-x: 24px; + --padding-y: 20px; 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 { - padding: 0; + --padding-x: 0px; + --padding-y: 0px; } :host([actions]) .content { 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) {