Update popup design. Add form popups

This commit is contained in:
2022-08-03 21:21:25 +00:00
parent a641617671
commit bb7b7fa6ff
12 changed files with 289 additions and 131 deletions

View File

@@ -1,6 +1,5 @@
import "./browser-player";
// import { BrowserModConnection } from "./connection";
import { ConnectionMixin } from "./connection";
import { ScreenSaverMixin } from "./screensaver";
import { MediaPlayerMixin } from "./mediaPlayer";
@@ -19,7 +18,8 @@ import { BrowserIDMixin } from "./browserID";
/*
TODO:
- Fix nomenclature
- More pictures for documentation
x Fix nomenclature
x Command -> Service
x Device -> Browser
- Popups
@@ -28,6 +28,8 @@ import { BrowserIDMixin } from "./browserID";
X Timeout
X Fullscreen
x Popup-card
x Auto-close
x Forms that are forwarded to service calls
x Motion/occupancy tracker
x Information about interaction requirement
x Information about fullykiosk
@@ -39,29 +41,28 @@ import { BrowserIDMixin } from "./browserID";
x ll-custom handling
- Commands
x popup
x Auto-close
x close_popup
x more-info
x navigate
- lovelace-reload?
- Not needed
o lovelace-reload?
o Not needed
x window-reload
- screensaver ?
- Refer to automations instead
o screensaver ?
o Refer to automations instead
x sequence
x delay
x javascript eval
- toast?
- Replaced with popups with timeout
o toast?
o Replaced with popups with timeout
x Redesign services to target devices
x frontend editor for popup cards
- also screensavers
- Saved frontend settings
o also screensavers
x Saved frontend settings
X Framework
x Save sidebar
x Kiosk mode
x Default dashboard
- Screensaver?
o Screensaver?
x Favicon templates
x Title templates
- Tweaks
@@ -69,9 +70,9 @@ import { BrowserIDMixin } from "./browserID";
x Card-mod preload
x Video player
x Media_seek
- Screensavers
o Screensavers
x IMPORTANT: FIX DEFAULT HIDING OF ENTITIES
- NOFIX. Home Assistant bug
o NOFIX. Home Assistant bug
X Check functionality with CAST - may need to add frontend part as a lovelace resource
*/
export class BrowserMod extends ServicesMixin(

View File

@@ -1,12 +1,11 @@
import { selectTree } from "../helpers";
import { selectTree, throttle } from "../helpers";
export const MediaPlayerMixin = (SuperClass) => {
return class MediaPlayerMixinClass extends SuperClass {
class MediaPlayerMixinClass extends SuperClass {
public player;
private _audio_player;
private _video_player;
private _player_enabled;
private _player_update_cooldown;
constructor() {
super();
@@ -24,10 +23,10 @@ export const MediaPlayerMixin = (SuperClass) => {
}
for (const ev of ["timeupdate"]) {
this._audio_player.addEventListener(ev, () =>
this._player_update_choked()
this._player_update_throttled()
);
this._video_player.addEventListener(ev, () =>
this._player_update_choked()
this._player_update_throttled()
);
}
@@ -99,12 +98,8 @@ export const MediaPlayerMixin = (SuperClass) => {
}
}
private _player_update_choked() {
if (this._player_update_cooldown) return;
this._player_update_cooldown = window.setTimeout(
() => (this._player_update_cooldown = undefined),
3000
);
@throttle(3000)
_player_update_throttled() {
this._player_update();
}
@@ -129,5 +124,7 @@ export const MediaPlayerMixin = (SuperClass) => {
},
});
}
};
}
return MediaPlayerMixinClass;
};

View File

@@ -2,6 +2,7 @@ import { LitElement, html, css } from "lit";
import { property, query } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { provideHass, loadLoadCardHelpers, hass_base_el } from "../helpers";
import { loadHaForm } from "../helpers";
class BrowserModPopup extends LitElement {
@property() open;
@@ -23,6 +24,7 @@ class BrowserModPopup extends LitElement {
_timeoutStart;
_timeoutTimer;
_resolveClosed;
_formdata;
async closeDialog() {
this.open = false;
@@ -76,10 +78,30 @@ class BrowserModPopup extends LitElement {
autoclose = false,
} = {}
) {
this._formdata = undefined;
this.title = title;
this.card = undefined;
if (content && content instanceof HTMLElement) {
this.card = undefined;
this.content = content;
} else if (content && Array.isArray(content)) {
loadHaForm();
const form: any = document.createElement("ha-form");
form.schema = content;
form.computeLabel = (s) => s.label ?? s.name;
form.hass = window.browser_mod.hass;
this._formdata = {};
for (const i of content) {
if (i.name && i.default !== undefined) {
this._formdata[i.name] = i.default;
}
}
form.data = this._formdata;
provideHass(form);
form.addEventListener("value-changed", (ev) => {
this._formdata = { ...ev.detail.value };
form.data = this._formdata;
});
this.content = form;
} else if (content && typeof content === "object") {
// Create a card from config in content
this.card = true;
@@ -90,7 +112,6 @@ class BrowserModPopup extends LitElement {
this.content = card;
} else {
// Basic HTML content
this.card = undefined;
this.content = unsafeHTML(content);
}
@@ -115,12 +136,12 @@ class BrowserModPopup extends LitElement {
async _primary() {
if (this._actions?.dismiss_action) this._actions.dismiss_action = undefined;
this.dialog?.close();
this._actions?.right_button_action?.();
this._actions?.right_button_action?.(this._formdata);
}
async _secondary() {
if (this._actions?.dismiss_action) this._actions.dismiss_action = undefined;
this.dialog?.close();
this._actions?.left_button_action?.();
this._actions?.left_button_action?.(this._formdata);
}
async _dismiss(ev?) {
this.dialog?.close();
@@ -150,16 +171,21 @@ class BrowserModPopup extends LitElement {
: ""}
${this.title
? html`
<app-toolbar slot="heading">
${this.dismissable
? html`
<ha-icon-button dialogAction="cancel">
<ha-icon .icon=${"mdi:close"}></ha-icon>
</ha-icon-button>
`
: ""}
<div class="main-title">${this.title}</div>
</app-toolbar>
<div slot="heading">
<ha-header-bar>
${this.dismissable
? html`
<ha-icon-button
dialogAction="cancel"
slot="navigationIcon"
>
<ha-icon .icon=${"mdi:close"}></ha-icon>
</ha-icon-button>
`
: ""}
<div slot="title" class="main-title">${this.title}</div>
</ha-header-bar>
</div>
`
: html``}
@@ -171,6 +197,7 @@ class BrowserModPopup extends LitElement {
slot="primaryAction"
.label=${this.right_button}
@click=${this._primary}
class="action-button"
></mwc-button>
`
: ""}
@@ -180,6 +207,7 @@ class BrowserModPopup extends LitElement {
slot="secondaryAction"
.label=${this.left_button}
@click=${this._secondary}
class="action-button"
></mwc-button>
`
: ""}
@@ -195,6 +223,7 @@ class BrowserModPopup extends LitElement {
static get styles() {
return css`
ha-dialog {
--dialog-backdrop-filter: blur(5px);
z-index: 10;
--mdc-dialog-min-width: var(--popup-min-width, 400px);
--mdc-dialog-max-width: var(--popup-max-width, 600px);
@@ -202,13 +231,12 @@ class BrowserModPopup extends LitElement {
--mdc-dialog-content-ink-color: var(--primary-text-color);
--justify-action-buttons: space-between;
--mdc-dialog-box-shadow: 0px 0px 0px
--dialog-box-shadow: 0px 0px 0px
var(--popup-border-width, var(--ha-card-border-width, 2px))
var(
--popup-border-color,
var(--ha-card-border-color, var(--divider-color, #e0e0e0))
);
--ha-dialog-border-radius: var(--popup-border-radius, 8px);
--mdc-theme-surface: var(
--popup-background-color,
var(--ha-card-background, var(--card-background-color, white))
@@ -224,6 +252,7 @@ class BrowserModPopup extends LitElement {
--mdc-dialog-max-height: 100%;
--mdc-shape-medium: 0px;
--vertial-align-dialog: flex-end;
--ha-dialog-border-radius: 0px;
}
.progress::before {
content: "";
@@ -236,23 +265,20 @@ class BrowserModPopup extends LitElement {
z-index: 10;
}
app-toolbar {
ha-header-bar {
--mdc-theme-on-primary: var(--primary-text-color);
--mdc-theme-primary: var(--mdc-theme-surface);
flex-shrink: 0;
color: var(--primary-text-color);
background-color: var(
--popup-header-background-color,
var(--popup-background-color, var(--sidebar-background-color))
);
display: block;
}
ha-icon-button > * {
display: flex;
}
.main-title {
margin-left: 16px;
line-height: 1.3em;
max-height: 2.6em;
overflow: hidden;
text-overflow: ellipsis;
cursor: default;
}
.content {
--padding-x: 24px;
@@ -269,9 +295,11 @@ class BrowserModPopup extends LitElement {
:host([card]) .content {
--padding-x: 0px;
--padding-y: 0px;
--ha-card-box-shadow: none;
}
:host([actions]) .content {
border-bottom: 1px solid var(--popup-border-color, var(--divider-color));
xborder-bottom: 2px solid
var(--popup-border-color, var(--divider-color));
--footer-height: 54px;
}
:host([wide]) .content {
@@ -280,10 +308,14 @@ class BrowserModPopup extends LitElement {
:host([fullscreen]) .content {
height: calc(
100vh - var(--header-height) - var(--footer-height) - 2 *
var(--padding-y)
var(--padding-y) - 16px
);
}
.action-button {
margin-bottom: -24px;
}
@media all and (max-width: 450px), all and (max-height: 500px) {
ha-dialog {
--mdc-dialog-min-width: 100vw;

View File

@@ -128,7 +128,13 @@ export const ServicesMixin = (SuperClass) => {
const { title, content, ...d } = data;
for (const [k, v] of Object.entries(d)) {
if (k.endsWith("_action")) {
d[k] = () => this._service_action(v as any);
d[k] = (ext_data?) => {
const { service, data } = v as any;
this._service_action({
service,
data: { ...data, ...ext_data },
});
};
}
}
this.showPopup(title, content, d);
@@ -147,18 +153,21 @@ export const ServicesMixin = (SuperClass) => {
break;
case "console":
console.log(data.message);
if (
Object.keys(data).length > 1 ||
(data && data.message === undefined)
)
console.dir(data);
else console.log(data.message);
break;
case "javascript":
const code = `
"use strict";
// Insert global definitions here
const hass = (document.querySelector("home-assistant") || document.querySelector("hc-main")).hass;
${data.code}
`;
const fn = new Function(code);
fn();
const fn = new Function("hass", "data", code);
fn(this.hass, data);
break;
}
}