diff --git a/src/components/dialogs/hacs-custom-repositories-dialog.ts b/src/components/dialogs/hacs-custom-repositories-dialog.ts index d087ed937..c246ff9b8 100644 --- a/src/components/dialogs/hacs-custom-repositories-dialog.ts +++ b/src/components/dialogs/hacs-custom-repositories-dialog.ts @@ -9,8 +9,13 @@ import "../../../homeassistant-frontend/src/components/ha-form/ha-form"; import type { HaFormSchema } from "../../../homeassistant-frontend/src/components/ha-form/types"; import "../../../homeassistant-frontend/src/components/ha-settings-row"; import "../../../homeassistant-frontend/src/components/ha-svg-icon"; -import { Repository } from "../../data/common"; -import { getRepositories, repositoryAdd, repositoryDelete } from "../../data/websocket"; +import { HacsDispatchEvent, Repository } from "../../data/common"; +import { + getRepositories, + repositoryAdd, + repositoryDelete, + websocketSubscription, +} from "../../data/websocket"; import { scrollBarStyle } from "../../styles/element-styles"; import { HacsStyles } from "../../styles/hacs-common-style"; import "./hacs-dialog"; @@ -121,7 +126,7 @@ export class HacsCustomRepositoriesDialog extends HacsDialogBase { } protected firstUpdated() { - this.hass.connection.subscribeEvents((msg) => (this._error = (msg as any).data), "hacs/error"); + websocketSubscription(this.hass, (data) => (this._error = data), HacsDispatchEvent.ERROR); this._customRepositories = this.hacs.repositories?.filter((repo) => repo.custom); } diff --git a/src/components/dialogs/hacs-download-dialog.ts b/src/components/dialogs/hacs-download-dialog.ts index 3a909f732..99970d5ce 100644 --- a/src/components/dialogs/hacs-download-dialog.ts +++ b/src/components/dialogs/hacs-download-dialog.ts @@ -8,7 +8,7 @@ import "../../../homeassistant-frontend/src/components/ha-circular-progress"; import "../../../homeassistant-frontend/src/components/ha-form/ha-form"; import { HaFormSchema } from "../../../homeassistant-frontend/src/components/ha-form/types"; import { showConfirmationDialog } from "../../../homeassistant-frontend/src/dialogs/generic/show-dialog-box"; -import { Repository } from "../../data/common"; +import { HacsDispatchEvent, Repository } from "../../data/common"; import { getRepositories, repositoryInstall, @@ -16,6 +16,7 @@ import { repositorySetVersion, repositoryToggleBeta, repositoryUpdate, + websocketSubscription, } from "../../data/websocket"; import { HacsStyles } from "../../styles/hacs-common-style"; import { generateLovelaceURL } from "../../tools/added-to-lovelace"; @@ -86,7 +87,7 @@ export class HacsDonwloadDialog extends HacsDialogBase { this._repository = this._getRepository(repositories, this.repository!); } this._toggle = false; - this.hass.connection.subscribeEvents((msg) => (this._error = (msg as any).data), "hacs/error"); + websocketSubscription(this.hass, (data) => (this._error = data), HacsDispatchEvent.ERROR); this._downloadRepositoryData.beta = this._repository!.beta; this._downloadRepositoryData.version = this._repository?.version_or_commit === "version" ? this._repository.releases[0] : ""; diff --git a/src/components/dialogs/hacs-update-dialog.ts b/src/components/dialogs/hacs-update-dialog.ts index b00b88f5a..772c51906 100644 --- a/src/components/dialogs/hacs-update-dialog.ts +++ b/src/components/dialogs/hacs-update-dialog.ts @@ -11,11 +11,12 @@ import "../../../homeassistant-frontend/src/components/ha-circular-progress"; import "../../../homeassistant-frontend/src/components/ha-expansion-panel"; import "../../../homeassistant-frontend/src/components/ha-svg-icon"; import { showConfirmationDialog } from "../../../homeassistant-frontend/src/dialogs/generic/show-dialog-box"; -import { Repository } from "../../data/common"; +import { HacsDispatchEvent, Repository } from "../../data/common"; import { repositoryInstall, repositoryInstallVersion, repositoryReleasenotes, + websocketSubscription, } from "../../data/websocket"; import { scrollBarStyle } from "../../styles/element-styles"; import { HacsStyles } from "../../styles/hacs-common-style"; @@ -56,7 +57,7 @@ export class HacsUpdateDialog extends HacsDialogBase { (release) => release.tag > repository.installed_version ); } - this.hass.connection.subscribeEvents((msg) => (this._error = (msg as any).data), "hacs/error"); + websocketSubscription(this.hass, (data) => (this._error = data), HacsDispatchEvent.ERROR); } protected render(): TemplateResult { diff --git a/src/data/common.ts b/src/data/common.ts index c53e3de7a..9a3961dbf 100644 --- a/src/data/common.ts +++ b/src/data/common.ts @@ -146,3 +146,13 @@ export const sortRepositoriesByName = (repositories: Repository[]): Repository[] repositories?.sort((a: Repository, b: Repository) => a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1 ); + +export enum HacsDispatchEvent { + CONFIG = "hacs_dispatch_config", + ERROR = "hacs_dispatch_error", + RELOAD = "hacs_dispatch_reload", + REPOSITORY = "hacs_dispatch_repository", + STAGE = "hacs_dispatch_stage", + STARTUP = "hacs_dispatch_startup", + STATUS = "hacs_dispatch_status", +} diff --git a/src/data/websocket.ts b/src/data/websocket.ts index cbc25a09a..83845483e 100644 --- a/src/data/websocket.ts +++ b/src/data/websocket.ts @@ -7,6 +7,7 @@ import { LovelaceResource, LovelaceResourcesMutableParams, RemovedRepository, + HacsDispatchEvent, } from "./common"; export const getConfiguration = async (hass: HomeAssistant) => { @@ -189,3 +190,13 @@ export const deleteResource = (hass: HomeAssistant, id: string) => type: "lovelace/resources/delete", resource_id: id, }); + +export const websocketSubscription = ( + hass: HomeAssistant, + onChange: (result: Record | null) => void, + event: HacsDispatchEvent +) => + hass.connection.subscribeMessage(onChange, { + type: "hacs/subscribe", + signal: event, + }); diff --git a/src/hacs-resolver.ts b/src/hacs-resolver.ts index 06b08f288..aaac49c17 100644 --- a/src/hacs-resolver.ts +++ b/src/hacs-resolver.ts @@ -14,6 +14,7 @@ import { LocationChangedEvent, HacsDialogEvent, RemovedRepository, + HacsDispatchEvent, } from "./data/common"; import { @@ -23,6 +24,7 @@ import { getCritical, getLovelaceConfiguration, getRemovedRepositories, + websocketSubscription, } from "./data/websocket"; import "./panels/hacs-entry-panel"; @@ -81,11 +83,11 @@ export class HacsResolver extends LitElement { }; /* Backend event subscription */ - this.hass.connection.subscribeEvents(async () => this._updateProperties(), "hacs/config"); - this.hass.connection.subscribeEvents(async () => this._updateProperties(), "hacs/status"); - - this.hass.connection.subscribeEvents(async () => this._updateProperties(), "hacs/repository"); + websocketSubscription(this.hass, () => this._updateProperties(), HacsDispatchEvent.CONFIG); + websocketSubscription(this.hass, () => this._updateProperties(), HacsDispatchEvent.STATUS); + websocketSubscription(this.hass, () => this._updateProperties(), HacsDispatchEvent.REPOSITORY); this.hass.connection.subscribeEvents(async () => this._updateProperties(), "lovelace_updated"); + await this._updateProperties(); } diff --git a/src/hacs.ts b/src/hacs.ts index b064b1484..0d41755e0 100644 --- a/src/hacs.ts +++ b/src/hacs.ts @@ -1,4 +1,4 @@ -import { LitElement } from "lit"; +import { LitElement, PropertyValues } from "lit"; import { property } from "lit/decorators"; import { Hacs } from "./data/hacs"; import { sectionsEnabled } from "./panels/hacs-sections"; @@ -50,7 +50,8 @@ export class HacsElement extends ProvideHassLitMixin(LitElement) { } } - protected updated() { + protected updated(changedProps: PropertyValues) { + super.updated(changedProps); if (this.hacs.language && this.hacs.configuration) { this.hacs.sections = sectionsEnabled(this.hacs.language, this.hacs.configuration); } diff --git a/src/main.ts b/src/main.ts index a2e585e7b..5b76397c6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,15 @@ -import { html, TemplateResult } from "lit"; +import { html, PropertyValues, TemplateResult } from "lit"; import { customElement, property, query } from "lit/decorators"; import { applyThemesOnElement } from "../homeassistant-frontend/src/common/dom/apply_themes_on_element"; +import { mainWindow } from "../homeassistant-frontend/src/common/dom/get_main_window"; +import { fireEvent } from "../homeassistant-frontend/src/common/dom/fire_event"; +import { isNavigationClick } from "../homeassistant-frontend/src/common/dom/is-navigation-click"; import { navigate } from "../homeassistant-frontend/src/common/navigate"; import { makeDialogManager } from "../homeassistant-frontend/src/dialogs/make-dialog-manager"; import "../homeassistant-frontend/src/resources/ha-style"; import { HomeAssistant, Route } from "../homeassistant-frontend/src/types"; import "./components/dialogs/hacs-event-dialog"; -import { HacsDialogEvent, LocationChangedEvent } from "./data/common"; +import { HacsDialogEvent, HacsDispatchEvent, LocationChangedEvent } from "./data/common"; import { getConfiguration, getCritical, @@ -14,6 +17,7 @@ import { getRemovedRepositories, getRepositories, getStatus, + websocketSubscription, } from "./data/websocket"; import { HacsElement } from "./hacs"; import "./hacs-router"; @@ -34,6 +38,9 @@ class HacsFrontend extends HacsElement { protected firstUpdated(changedProps) { super.firstUpdated(changedProps); + + this._applyTheme(); + this.hacs.language = this.hass.language; this.addEventListener("hacs-location-changed", (e) => this._setRoute(e as LocationChangedEvent) @@ -44,34 +51,72 @@ class HacsFrontend extends HacsElement { this._showDialogSecondary(e as HacsDialogEvent) ); - this.hass.connection.subscribeEvents( - async () => this._updateProperties("configuration"), - "hacs/config" + websocketSubscription( + this.hass, + () => this._updateProperties("configuration"), + HacsDispatchEvent.CONFIG ); - this.hass.connection.subscribeEvents( - async () => this._updateProperties("status"), - "hacs/status" + + websocketSubscription( + this.hass, + () => this._updateProperties("status"), + HacsDispatchEvent.STATUS ); - this.hass.connection.subscribeEvents( - async () => this._updateProperties("status"), - "hacs/stage" + + websocketSubscription( + this.hass, + () => this._updateProperties("status"), + HacsDispatchEvent.STAGE ); - this.hass.connection.subscribeEvents( - async () => this._updateProperties("repositories"), - "hacs/repository" + + websocketSubscription( + this.hass, + () => this._updateProperties("repositories"), + HacsDispatchEvent.REPOSITORY ); + this.hass.connection.subscribeEvents( async () => this._updateProperties("lovelace"), "lovelace_updated" ); - - makeDialogManager(this, this.shadowRoot!); this._updateProperties(); if (this.route.path === "") { navigate("/hacs/entry", { replace: true }); } - this._applyTheme(); + window.addEventListener("haptic", (ev) => { + // @ts-ignore + fireEvent(window.parent, ev.type, ev.detail, { + bubbles: false, + }); + }); + + document.body.addEventListener("click", (ev) => { + const href = isNavigationClick(ev); + if (href) { + navigate(href); + } + }); + + mainWindow.addEventListener("location-changed", (ev) => + // @ts-ignore + fireEvent(this, ev.type, ev.detail, { + bubbles: false, + }) + ); + + makeDialogManager(this, this.shadowRoot!); + } + + protected updated(changedProps: PropertyValues) { + super.updated(changedProps); + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if (!oldHass) { + return; + } + if (oldHass.themes !== this.hass.themes) { + this._applyTheme(); + } } private async _updateProperties(prop = "all") {