mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-08 18:06:36 +00:00
Convert <home-assistant> to Lit/TS (#2586)
* Convert home-assistant element to Lit/TS * Fix disconnect toast * Lint
This commit is contained in:
parent
9299d548ba
commit
d6887758a9
@ -1,5 +1,8 @@
|
|||||||
import { HomeAssistant } from "../../src/layouts/app/home-assistant";
|
import { HomeAssistantAppEl } from "../../src/layouts/app/home-assistant";
|
||||||
import { provideHass } from "../../src/fake_data/provide_hass";
|
import {
|
||||||
|
provideHass,
|
||||||
|
MockHomeAssistant,
|
||||||
|
} from "../../src/fake_data/provide_hass";
|
||||||
import { navigate } from "../../src/common/navigate";
|
import { navigate } from "../../src/common/navigate";
|
||||||
import { mockLovelace } from "./stubs/lovelace";
|
import { mockLovelace } from "./stubs/lovelace";
|
||||||
import { mockAuth } from "./stubs/auth";
|
import { mockAuth } from "./stubs/auth";
|
||||||
@ -11,14 +14,14 @@ import { mockSystemLog } from "./stubs/system_log";
|
|||||||
import { mockTemplate } from "./stubs/template";
|
import { mockTemplate } from "./stubs/template";
|
||||||
import { mockEvents } from "./stubs/events";
|
import { mockEvents } from "./stubs/events";
|
||||||
import { mockMediaPlayer } from "./stubs/media_player";
|
import { mockMediaPlayer } from "./stubs/media_player";
|
||||||
|
import { HomeAssistant } from "../../src/types";
|
||||||
|
|
||||||
class HaDemo extends HomeAssistant {
|
class HaDemo extends HomeAssistantAppEl {
|
||||||
protected async _handleConnProm() {
|
protected async _handleConnProm() {
|
||||||
const initial: Partial<HomeAssistant> = {
|
const initial: Partial<MockHomeAssistant> = {
|
||||||
panelUrl: (this as any).panelUrl,
|
panelUrl: (this as any).panelUrl,
|
||||||
// Override updateHass so that the correct hass lifecycle methods are called
|
// Override updateHass so that the correct hass lifecycle methods are called
|
||||||
updateHass: (hassUpdate) =>
|
updateHass: (hassUpdate: Partial<HomeAssistant>) =>
|
||||||
// @ts-ignore
|
|
||||||
this._updateHass(hassUpdate),
|
this._updateHass(hassUpdate),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ export interface HASSDomEvent<T> extends Event {
|
|||||||
* @return {Event} The new event that was fired.
|
* @return {Event} The new event that was fired.
|
||||||
*/
|
*/
|
||||||
export const fireEvent = <HassEvent extends ValidHassDomEvent>(
|
export const fireEvent = <HassEvent extends ValidHassDomEvent>(
|
||||||
node: HTMLElement,
|
node: HTMLElement | Window,
|
||||||
type: HassEvent,
|
type: HassEvent,
|
||||||
detail?: HASSDomEvents[HassEvent],
|
detail?: HASSDomEvents[HassEvent],
|
||||||
options?: {
|
options?: {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { fireEvent } from "./dom/fire_event";
|
import { fireEvent } from "./dom/fire_event";
|
||||||
|
|
||||||
export const navigate = (
|
export const navigate = (
|
||||||
node: HTMLElement,
|
_node: any,
|
||||||
path: string,
|
path: string,
|
||||||
replace: boolean = false
|
replace: boolean = false
|
||||||
) => {
|
) => {
|
||||||
@ -18,5 +18,5 @@ export const navigate = (
|
|||||||
history.pushState(null, "", path);
|
history.pushState(null, "", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fireEvent(node, "location-changed");
|
fireEvent(window, "location-changed");
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import "@polymer/paper-toast/paper-toast";
|
import "@polymer/paper-toast/paper-toast";
|
||||||
|
|
||||||
|
// tslint:disable-next-line
|
||||||
const PaperToast = customElements.get("paper-toast");
|
const PaperToast = customElements.get("paper-toast");
|
||||||
|
|
||||||
class HaToast extends PaperToast {
|
export class HaToast extends PaperToast {
|
||||||
connectedCallback() {
|
public connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
if (!this._resizeListener) {
|
if (!this._resizeListener) {
|
||||||
@ -15,10 +16,16 @@ class HaToast extends PaperToast {
|
|||||||
this._resizeListener(this._mediaq);
|
this._resizeListener(this._mediaq);
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
public disconnectedCallback() {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
this._mediaq.removeListener(this._resizeListener);
|
this._mediaq.removeListener(this._resizeListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-toast": HaToast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
customElements.define("ha-toast", HaToast);
|
customElements.define("ha-toast", HaToast);
|
@ -6,8 +6,8 @@ import { subscribeUser } from "../../data/ws-user";
|
|||||||
|
|
||||||
export default (superClass) =>
|
export default (superClass) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
ready() {
|
firstUpdated(changedProps) {
|
||||||
super.ready();
|
super.firstUpdated(changedProps);
|
||||||
this.addEventListener("hass-logout", () => this._handleLogout());
|
this.addEventListener("hass-logout", () => this._handleLogout());
|
||||||
// HACK :( We don't have a way yet to trigger an update of `subscribeUser`
|
// HACK :( We don't have a way yet to trigger an update of `subscribeUser`
|
||||||
this.addEventListener("hass-refresh-current-user", () =>
|
this.addEventListener("hass-refresh-current-user", () =>
|
||||||
|
@ -20,8 +20,8 @@ import { subscribePanels } from "../../data/ws-panels";
|
|||||||
|
|
||||||
export default (superClass) =>
|
export default (superClass) =>
|
||||||
class extends EventsMixin(LocalizeMixin(superClass)) {
|
class extends EventsMixin(LocalizeMixin(superClass)) {
|
||||||
ready() {
|
firstUpdated(changedProps) {
|
||||||
super.ready();
|
super.firstUpdated(changedProps);
|
||||||
this._handleConnProm();
|
this._handleConnProm();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ export default (superClass) =>
|
|||||||
panels: null,
|
panels: null,
|
||||||
services: null,
|
services: null,
|
||||||
user: null,
|
user: null,
|
||||||
panelUrl: this.panelUrl,
|
panelUrl: this._panelUrl,
|
||||||
|
|
||||||
language: getActiveTranslation(),
|
language: getActiveTranslation(),
|
||||||
// If resources are already loaded, don't discard them
|
// If resources are already loaded, don't discard them
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { PolymerElement } from "@polymer/polymer";
|
import { Constructor, LitElement } from "lit-element";
|
||||||
import { Constructor } from "lit-element";
|
|
||||||
import { HASSDomEvent, ValidHassDomEvent } from "../../common/dom/fire_event";
|
import { HASSDomEvent, ValidHassDomEvent } from "../../common/dom/fire_event";
|
||||||
|
|
||||||
interface RegisterDialogParams {
|
interface RegisterDialogParams {
|
||||||
@ -23,10 +22,10 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dialogManagerMixin = (superClass: Constructor<PolymerElement>) =>
|
export const dialogManagerMixin = (superClass: Constructor<LitElement>) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
public ready() {
|
protected firstUpdated(changedProps) {
|
||||||
super.ready();
|
super.firstUpdated(changedProps);
|
||||||
this.addEventListener("register-dialog", (e) =>
|
this.addEventListener("register-dialog", (e) =>
|
||||||
this.registerDialog(e.detail)
|
this.registerDialog(e.detail)
|
||||||
);
|
);
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
import LocalizeMixin from "../../mixins/localize-mixin";
|
|
||||||
|
|
||||||
export default (superClass) =>
|
|
||||||
class extends LocalizeMixin(superClass) {
|
|
||||||
hassConnected() {
|
|
||||||
super.hassConnected();
|
|
||||||
// Need to load in advance because when disconnected, can't dynamically load code.
|
|
||||||
import(/* webpackChunkName: "ha-toast" */ "../../components/ha-toast");
|
|
||||||
}
|
|
||||||
|
|
||||||
hassReconnected() {
|
|
||||||
super.hassReconnected();
|
|
||||||
this.__discToast.opened = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hassDisconnected() {
|
|
||||||
super.hassDisconnected();
|
|
||||||
if (!this.__discToast) {
|
|
||||||
const el = document.createElement("ha-toast");
|
|
||||||
el.duration = 0;
|
|
||||||
el.text = this.localize("ui.notification_toast.connection_lost");
|
|
||||||
this.__discToast = el;
|
|
||||||
this.shadowRoot.appendChild(el);
|
|
||||||
}
|
|
||||||
this.__discToast.opened = true;
|
|
||||||
}
|
|
||||||
};
|
|
40
src/layouts/app/disconnect-toast-mixin.ts
Normal file
40
src/layouts/app/disconnect-toast-mixin.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { Constructor, LitElement } from "lit-element";
|
||||||
|
import { HassBaseEl } from "./hass-base-mixin";
|
||||||
|
import { hassLocalizeLitMixin } from "../../mixins/lit-localize-mixin";
|
||||||
|
import { HaToast } from "../../components/ha-toast";
|
||||||
|
|
||||||
|
export default (superClass: Constructor<LitElement & HassBaseEl>) =>
|
||||||
|
class extends hassLocalizeLitMixin(superClass) {
|
||||||
|
private _discToast?: HaToast;
|
||||||
|
|
||||||
|
protected hassConnected() {
|
||||||
|
super.hassConnected();
|
||||||
|
// Need to load in advance because when disconnected, can't dynamically load code.
|
||||||
|
import(/* webpackChunkName: "ha-toast" */ "../../components/ha-toast");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected hassReconnected() {
|
||||||
|
super.hassReconnected();
|
||||||
|
if (this._discToast) {
|
||||||
|
this._discToast.opened = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected hassDisconnected() {
|
||||||
|
super.hassDisconnected();
|
||||||
|
if (!this._discToast) {
|
||||||
|
const el = document.createElement("ha-toast");
|
||||||
|
el.duration = 0;
|
||||||
|
// Temp. Somehow the localize func is not getting recalculated for
|
||||||
|
// this class. Manually generating one. Will be fixed when we move
|
||||||
|
// the localize function to the hass object.
|
||||||
|
const { language, resources } = this.hass!;
|
||||||
|
el.text = (this as any).__computeLocalize(language, resources)(
|
||||||
|
"ui.notification_toast.connection_lost"
|
||||||
|
);
|
||||||
|
this._discToast = el;
|
||||||
|
this.shadowRoot!.appendChild(el as any);
|
||||||
|
}
|
||||||
|
this._discToast.opened = true;
|
||||||
|
}
|
||||||
|
};
|
@ -1,42 +0,0 @@
|
|||||||
/* eslint-disable no-unused-vars */
|
|
||||||
export default (superClass) =>
|
|
||||||
class extends superClass {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.__pendingHass = false;
|
|
||||||
this.__provideHass = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exists so all methods can safely call super method
|
|
||||||
hassConnected() {}
|
|
||||||
|
|
||||||
hassReconnected() {}
|
|
||||||
|
|
||||||
hassDisconnected() {}
|
|
||||||
|
|
||||||
panelUrlChanged(newPanelUrl) {}
|
|
||||||
|
|
||||||
hassChanged(hass, oldHass) {
|
|
||||||
this.__provideHass.forEach((el) => {
|
|
||||||
el.hass = hass;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
provideHass(el) {
|
|
||||||
this.__provideHass.push(el);
|
|
||||||
el.hass = this.hass;
|
|
||||||
}
|
|
||||||
|
|
||||||
async _updateHass(obj) {
|
|
||||||
const oldHass = this.hass;
|
|
||||||
this.hass = Object.assign({}, this.hass, obj);
|
|
||||||
this.__pendingHass = true;
|
|
||||||
|
|
||||||
await 0;
|
|
||||||
|
|
||||||
if (!this.__pendingHass) return;
|
|
||||||
|
|
||||||
this.__pendingHass = false;
|
|
||||||
this.hassChanged(this.hass, oldHass);
|
|
||||||
}
|
|
||||||
};
|
|
60
src/layouts/app/hass-base-mixin.ts
Normal file
60
src/layouts/app/hass-base-mixin.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { Constructor } from "lit-element";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
|
||||||
|
export class HassBaseEl {
|
||||||
|
protected hass?: HomeAssistant;
|
||||||
|
protected hassConnected() {}
|
||||||
|
protected hassReconnected() {}
|
||||||
|
protected hassDisconnected() {}
|
||||||
|
protected hassChanged(_hass: HomeAssistant, _oldHass?: HomeAssistant) {}
|
||||||
|
protected panelUrlChanged(_newPanelUrl: string) {}
|
||||||
|
protected provideHass(_el: HTMLElement) {}
|
||||||
|
protected _updateHass(_obj: Partial<HomeAssistant>) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default <T>(superClass: Constructor<T>): Constructor<T & HassBaseEl> =>
|
||||||
|
// @ts-ignore
|
||||||
|
class extends superClass {
|
||||||
|
private __provideHass: HTMLElement[];
|
||||||
|
// @ts-ignore
|
||||||
|
protected hass: HomeAssistant;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.__provideHass = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exists so all methods can safely call super method
|
||||||
|
protected hassConnected() {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
}
|
||||||
|
|
||||||
|
protected hassReconnected() {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
}
|
||||||
|
|
||||||
|
protected hassDisconnected() {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
}
|
||||||
|
|
||||||
|
protected panelUrlChanged(_newPanelUrl) {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
}
|
||||||
|
|
||||||
|
protected hassChanged(hass, _oldHass) {
|
||||||
|
this.__provideHass.forEach((el) => {
|
||||||
|
(el as any).hass = hass;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected provideHass(el) {
|
||||||
|
this.__provideHass.push(el);
|
||||||
|
el.hass = this.hass;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async _updateHass(obj) {
|
||||||
|
this.hass = { ...this.hass, ...obj };
|
||||||
|
}
|
||||||
|
};
|
@ -1,120 +0,0 @@
|
|||||||
import "@polymer/app-route/app-location";
|
|
||||||
import "@polymer/app-route/app-route";
|
|
||||||
import "@polymer/iron-flex-layout/iron-flex-layout-classes";
|
|
||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|
||||||
import { afterNextRender } from "@polymer/polymer/lib/utils/render-status";
|
|
||||||
import { html as litHtml, LitElement } from "lit-element";
|
|
||||||
|
|
||||||
import "../home-assistant-main";
|
|
||||||
import "../ha-init-page";
|
|
||||||
import "../../resources/ha-style";
|
|
||||||
import registerServiceWorker from "../../util/register-service-worker";
|
|
||||||
import { DEFAULT_PANEL } from "../../common/const";
|
|
||||||
|
|
||||||
import HassBaseMixin from "./hass-base-mixin";
|
|
||||||
import AuthMixin from "./auth-mixin";
|
|
||||||
import TranslationsMixin from "./translations-mixin";
|
|
||||||
import ThemesMixin from "./themes-mixin";
|
|
||||||
import MoreInfoMixin from "./more-info-mixin";
|
|
||||||
import SidebarMixin from "./sidebar-mixin";
|
|
||||||
import { dialogManagerMixin } from "./dialog-manager-mixin";
|
|
||||||
import ConnectionMixin from "./connection-mixin";
|
|
||||||
import NotificationMixin from "./notification-mixin";
|
|
||||||
import DisconnectToastMixin from "./disconnect-toast-mixin";
|
|
||||||
|
|
||||||
LitElement.prototype.html = litHtml;
|
|
||||||
|
|
||||||
const ext = (baseClass, mixins) =>
|
|
||||||
mixins.reduceRight((base, mixin) => mixin(base), baseClass);
|
|
||||||
|
|
||||||
export class HomeAssistant extends ext(PolymerElement, [
|
|
||||||
AuthMixin,
|
|
||||||
ThemesMixin,
|
|
||||||
TranslationsMixin,
|
|
||||||
MoreInfoMixin,
|
|
||||||
SidebarMixin,
|
|
||||||
DisconnectToastMixin,
|
|
||||||
ConnectionMixin,
|
|
||||||
NotificationMixin,
|
|
||||||
dialogManagerMixin,
|
|
||||||
HassBaseMixin,
|
|
||||||
]) {
|
|
||||||
static get template() {
|
|
||||||
return html`
|
|
||||||
<app-location
|
|
||||||
route="{{route}}"
|
|
||||||
use-hash-as-path="[[_useHashAsPath]]"
|
|
||||||
></app-location>
|
|
||||||
<app-route
|
|
||||||
route="[[route]]"
|
|
||||||
pattern="/:panel"
|
|
||||||
data="{{routeData}}"
|
|
||||||
tail="{{subroute}}"
|
|
||||||
></app-route>
|
|
||||||
<template is="dom-if" if="[[showMain]]" restamp>
|
|
||||||
<home-assistant-main
|
|
||||||
hass="[[hass]]"
|
|
||||||
route="[[route]]"
|
|
||||||
tail="[[subroute]]"
|
|
||||||
></home-assistant-main>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template is="dom-if" if="[[!showMain]]" restamp>
|
|
||||||
<ha-init-page error="[[_error]]"></ha-init-page>
|
|
||||||
</template>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
value: null,
|
|
||||||
},
|
|
||||||
showMain: {
|
|
||||||
type: Boolean,
|
|
||||||
computed: "computeShowMain(hass)",
|
|
||||||
},
|
|
||||||
route: Object,
|
|
||||||
routeData: Object,
|
|
||||||
panelUrl: {
|
|
||||||
type: String,
|
|
||||||
computed: "computePanelUrl(routeData)",
|
|
||||||
observer: "panelUrlChanged",
|
|
||||||
},
|
|
||||||
_error: {
|
|
||||||
type: Boolean,
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ready() {
|
|
||||||
super.ready();
|
|
||||||
afterNextRender(null, registerServiceWorker);
|
|
||||||
}
|
|
||||||
|
|
||||||
computeShowMain(hass) {
|
|
||||||
return hass && hass.states && hass.config && hass.panels && hass.services;
|
|
||||||
}
|
|
||||||
|
|
||||||
computePanelUrl(routeData) {
|
|
||||||
return (
|
|
||||||
(routeData && routeData.panel) ||
|
|
||||||
localStorage.defaultPage ||
|
|
||||||
DEFAULT_PANEL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get _useHashAsPath() {
|
|
||||||
return __DEMO__;
|
|
||||||
}
|
|
||||||
|
|
||||||
panelUrlChanged(newPanelUrl) {
|
|
||||||
super.panelUrlChanged(newPanelUrl);
|
|
||||||
this._updateHass({ panelUrl: newPanelUrl });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("home-assistant", HomeAssistant);
|
|
119
src/layouts/app/home-assistant.ts
Normal file
119
src/layouts/app/home-assistant.ts
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import "@polymer/app-route/app-location";
|
||||||
|
import "@polymer/iron-flex-layout/iron-flex-layout-classes";
|
||||||
|
import {
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
PropertyDeclarations,
|
||||||
|
PropertyValues,
|
||||||
|
} from "lit-element";
|
||||||
|
|
||||||
|
import "../home-assistant-main";
|
||||||
|
import "../ha-init-page";
|
||||||
|
import "../../resources/ha-style";
|
||||||
|
import { registerServiceWorker } from "../../util/register-service-worker";
|
||||||
|
import { DEFAULT_PANEL } from "../../common/const";
|
||||||
|
|
||||||
|
import HassBaseMixin from "./hass-base-mixin";
|
||||||
|
import AuthMixin from "./auth-mixin";
|
||||||
|
import TranslationsMixin from "./translations-mixin";
|
||||||
|
import ThemesMixin from "./themes-mixin";
|
||||||
|
import MoreInfoMixin from "./more-info-mixin";
|
||||||
|
import SidebarMixin from "./sidebar-mixin";
|
||||||
|
import { dialogManagerMixin } from "./dialog-manager-mixin";
|
||||||
|
import ConnectionMixin from "./connection-mixin";
|
||||||
|
import NotificationMixin from "./notification-mixin";
|
||||||
|
import DisconnectToastMixin from "./disconnect-toast-mixin";
|
||||||
|
import { Route, HomeAssistant } from "../../types";
|
||||||
|
import { navigate } from "../../common/navigate";
|
||||||
|
|
||||||
|
(LitElement.prototype as any).html = html;
|
||||||
|
|
||||||
|
const ext = <T>(baseClass: T, mixins): T =>
|
||||||
|
mixins.reduceRight((base, mixin) => mixin(base), baseClass);
|
||||||
|
|
||||||
|
export class HomeAssistantAppEl extends ext(HassBaseMixin(LitElement), [
|
||||||
|
AuthMixin,
|
||||||
|
ThemesMixin,
|
||||||
|
TranslationsMixin,
|
||||||
|
MoreInfoMixin,
|
||||||
|
SidebarMixin,
|
||||||
|
DisconnectToastMixin,
|
||||||
|
ConnectionMixin,
|
||||||
|
NotificationMixin,
|
||||||
|
dialogManagerMixin,
|
||||||
|
]) {
|
||||||
|
private _route?: Route;
|
||||||
|
private _error?: boolean;
|
||||||
|
private _panelUrl?: string;
|
||||||
|
|
||||||
|
static get properties(): PropertyDeclarations {
|
||||||
|
return {
|
||||||
|
hass: {},
|
||||||
|
_route: {},
|
||||||
|
_routeData: {},
|
||||||
|
_panelUrl: {},
|
||||||
|
_error: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const hass = this.hass;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<app-location
|
||||||
|
@route-changed=${this._routeChanged}
|
||||||
|
?use-hash-as-path=${__DEMO__}
|
||||||
|
></app-location>
|
||||||
|
${this._panelUrl === undefined || this._route === undefined
|
||||||
|
? ""
|
||||||
|
: hass && hass.states && hass.config && hass.panels && hass.services
|
||||||
|
? html`
|
||||||
|
<home-assistant-main
|
||||||
|
.hass=${this.hass}
|
||||||
|
.route=${this._route}
|
||||||
|
></home-assistant-main>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<ha-init-page .error=${this._error}></ha-init-page>
|
||||||
|
`}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
setTimeout(registerServiceWorker, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProps: PropertyValues): void {
|
||||||
|
if (changedProps.has("_panelUrl")) {
|
||||||
|
this.panelUrlChanged(this._panelUrl!);
|
||||||
|
this._updateHass({ panelUrl: this._panelUrl });
|
||||||
|
}
|
||||||
|
if (changedProps.has("hass")) {
|
||||||
|
this.hassChanged(this.hass!, changedProps.get("hass") as
|
||||||
|
| HomeAssistant
|
||||||
|
| undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _routeChanged(ev) {
|
||||||
|
const route = ev.detail.value as Route;
|
||||||
|
|
||||||
|
// If it's the first route that we process,
|
||||||
|
// check if we should navigate away from /
|
||||||
|
if (this._route === undefined && route.path === "/") {
|
||||||
|
navigate(window, `/${localStorage.defaultPage || DEFAULT_PANEL}`, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._route = route;
|
||||||
|
|
||||||
|
const dividerPos = route.path.indexOf("/", 1);
|
||||||
|
this._panelUrl =
|
||||||
|
dividerPos === -1
|
||||||
|
? route.path.substr(1)
|
||||||
|
: route.path.substr(1, dividerPos - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("home-assistant", HomeAssistantAppEl);
|
@ -2,8 +2,8 @@ import { afterNextRender } from "@polymer/polymer/lib/utils/render-status";
|
|||||||
|
|
||||||
export default (superClass) =>
|
export default (superClass) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
ready() {
|
firstUpdated(changedProps) {
|
||||||
super.ready();
|
super.firstUpdated(changedProps);
|
||||||
this.addEventListener("hass-more-info", (e) => this._handleMoreInfo(e));
|
this.addEventListener("hass-more-info", (e) => this._handleMoreInfo(e));
|
||||||
|
|
||||||
// Load it once we are having the initial rendering done.
|
// Load it once we are having the initial rendering done.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export default (superClass) =>
|
export default (superClass) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
ready() {
|
firstUpdated(changedProps) {
|
||||||
super.ready();
|
super.firstUpdated(changedProps);
|
||||||
this.registerDialog({
|
this.registerDialog({
|
||||||
dialogShowEvent: "hass-notification",
|
dialogShowEvent: "hass-notification",
|
||||||
dialogTag: "notification-manager",
|
dialogTag: "notification-manager",
|
||||||
|
@ -2,8 +2,8 @@ import { storeState } from "../../util/ha-pref-storage";
|
|||||||
|
|
||||||
export default (superClass) =>
|
export default (superClass) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
ready() {
|
firstUpdated(changedProps) {
|
||||||
super.ready();
|
super.firstUpdated(changedProps);
|
||||||
this.addEventListener("hass-dock-sidebar", (e) =>
|
this.addEventListener("hass-dock-sidebar", (e) =>
|
||||||
this._handleDockSidebar(e)
|
this._handleDockSidebar(e)
|
||||||
);
|
);
|
||||||
|
@ -4,9 +4,8 @@ import { subscribeThemes } from "../../data/ws-themes";
|
|||||||
|
|
||||||
export default (superClass) =>
|
export default (superClass) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
ready() {
|
firstUpdated(changedProps) {
|
||||||
super.ready();
|
super.firstUpdated(changedProps);
|
||||||
|
|
||||||
this.addEventListener("settheme", (ev) => {
|
this.addEventListener("settheme", (ev) => {
|
||||||
this._updateHass({ selectedTheme: ev.detail });
|
this._updateHass({ selectedTheme: ev.detail });
|
||||||
this._applyTheme();
|
this._applyTheme();
|
||||||
|
@ -8,8 +8,8 @@ import { storeState } from "../../util/ha-pref-storage";
|
|||||||
|
|
||||||
export default (superClass) =>
|
export default (superClass) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
ready() {
|
firstUpdated(changedProps) {
|
||||||
super.ready();
|
super.firstUpdated(changedProps);
|
||||||
this.addEventListener("hass-language-select", (e) =>
|
this.addEventListener("hass-language-select", (e) =>
|
||||||
this._selectLanguage(e)
|
this._selectLanguage(e)
|
||||||
);
|
);
|
||||||
@ -81,6 +81,6 @@ export default (superClass) =>
|
|||||||
storeState(this.hass);
|
storeState(this.hass);
|
||||||
this._loadResources();
|
this._loadResources();
|
||||||
this._loadBackendTranslations();
|
this._loadBackendTranslations();
|
||||||
this._loadTranslationFragment(this.panelUrl);
|
this._loadTranslationFragment(this.hass.panelUrl);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -81,9 +81,6 @@ class HomeAssistantMain extends NavigateMixin(EventsMixin(PolymerElement)) {
|
|||||||
return {
|
return {
|
||||||
hass: Object,
|
hass: Object,
|
||||||
narrow: Boolean,
|
narrow: Boolean,
|
||||||
tail: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
route: {
|
route: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: "_routeChanged",
|
observer: "_routeChanged",
|
||||||
@ -136,13 +133,6 @@ class HomeAssistantMain extends NavigateMixin(EventsMixin(PolymerElement)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
if (this.tail.prefix === "") {
|
|
||||||
this.navigate(`/${localStorage.defaultPage || DEFAULT_PANEL}`, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
computeForceNarrow(narrow, dockedSidebar) {
|
computeForceNarrow(narrow, dockedSidebar) {
|
||||||
return narrow || !dockedSidebar;
|
return narrow || !dockedSidebar;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const serviceWorkerUrl =
|
const serviceWorkerUrl =
|
||||||
__BUILD__ === "latest" ? "/service_worker.js" : "/service_worker_es5.js";
|
__BUILD__ === "latest" ? "/service_worker.js" : "/service_worker_es5.js";
|
||||||
|
|
||||||
export default () => {
|
export const registerServiceWorker = () => {
|
||||||
if (!("serviceWorker" in navigator)) return;
|
if (!("serviceWorker" in navigator)) return;
|
||||||
|
|
||||||
navigator.serviceWorker.register(serviceWorkerUrl).then((reg) => {
|
navigator.serviceWorker.register(serviceWorkerUrl).then((reg) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user