From 74657ae81516f7ef6df4bc9781cb3f44a1aec8d0 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 5 Mar 2020 13:36:13 -0800 Subject: [PATCH] Make cast backwards compatible (#5081) * Make cast backwards compatible * Update hc-main.ts * Update home-assistant-js-websocket --- cast/src/launcher/layout/hc-cast.ts | 6 +++- cast/src/receiver/layout/hc-main.ts | 23 ++++++++----- .../addon-store/hassio-addon-repository.ts | 13 ++++---- hassio/src/addon-view/hassio-addon-info.ts | 11 +++---- hassio/src/dashboard/hassio-addons.ts | 10 +++--- package.json | 2 +- src/common/config/version.ts | 11 +++++++ src/data/lovelace.ts | 32 +++++++++++++++++++ .../info/developer-tools-info.ts | 2 +- yarn.lock | 8 ++--- 10 files changed, 86 insertions(+), 32 deletions(-) create mode 100644 src/common/config/version.ts diff --git a/cast/src/launcher/layout/hc-cast.ts b/cast/src/launcher/layout/hc-cast.ts index 859b2cb911..b9bb9f76fb 100644 --- a/cast/src/launcher/layout/hc-cast.ts +++ b/cast/src/launcher/layout/hc-cast.ts @@ -26,10 +26,12 @@ import { CastManager } from "../../../../src/cast/cast_manager"; import { LovelaceConfig, getLovelaceCollection, + getLegacyLovelaceCollection, } from "../../../../src/data/lovelace"; import "./hc-layout"; import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config"; import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute"; +import { atLeastVersion } from "../../../../src/common/config/version"; @customElement("hc-cast") class HcCast extends LitElement { @@ -133,7 +135,9 @@ class HcCast extends LitElement { protected firstUpdated(changedProps) { super.firstUpdated(changedProps); - const llColl = getLovelaceCollection(this.connection); + const llColl = atLeastVersion(this.connection.haVersion, 0, 107) + ? getLovelaceCollection(this.connection) + : getLegacyLovelaceCollection(this.connection); // We first do a single refresh because we need to check if there is LL // configuration. llColl.refresh().then( diff --git a/cast/src/receiver/layout/hc-main.ts b/cast/src/receiver/layout/hc-main.ts index 1bb401c36a..fa84d8d2ef 100644 --- a/cast/src/receiver/layout/hc-main.ts +++ b/cast/src/receiver/layout/hc-main.ts @@ -16,6 +16,8 @@ import { LovelaceConfig, getLovelaceCollection, fetchResources, + LegacyLovelaceConfig, + getLegacyLovelaceCollection, } from "../../../../src/data/lovelace"; import "./hc-launch-screen"; import { castContext } from "../cast_context"; @@ -23,6 +25,7 @@ import { CAST_NS } from "../../../../src/cast/const"; import { ReceiverStatusMessage } from "../../../../src/cast/sender_messages"; import { loadLovelaceResources } from "../../../../src/panels/lovelace/common/load-resources"; import { isNavigationClick } from "../../../../src/common/dom/is-navigation-click"; +import { atLeastVersion } from "../../../../src/common/config/version"; let resourcesLoaded = false; @@ -168,19 +171,14 @@ export class HcMain extends HassElement { this._error = "Cannot show Lovelace because we're not connected."; return; } - if (!resourcesLoaded) { - resourcesLoaded = true; - loadLovelaceResources( - await fetchResources(this.hass!.connection), - this.hass!.auth.data.hassUrl - ); - } if (!this._unsubLovelace || this._urlPath !== msg.urlPath) { this._urlPath = msg.urlPath; if (this._unsubLovelace) { this._unsubLovelace(); } - const llColl = getLovelaceCollection(this.hass!.connection, msg.urlPath); + const llColl = atLeastVersion(this.hass.connection.haVersion, 0, 107) + ? getLovelaceCollection(this.hass!.connection, msg.urlPath) + : getLegacyLovelaceCollection(this.hass!.connection); // We first do a single refresh because we need to check if there is LL // configuration. try { @@ -199,6 +197,15 @@ export class HcMain extends HassElement { ); } } + if (!resourcesLoaded) { + resourcesLoaded = true; + const resources = atLeastVersion(this.hass.connection.haVersion, 0, 107) + ? await fetchResources(this.hass!.connection) + : (this._lovelaceConfig as LegacyLovelaceConfig).resources; + if (resources) { + loadLovelaceResources(resources, this.hass!.auth.data.hassUrl); + } + } this._showDemo = false; this._lovelacePath = msg.viewPath; if (castContext.getDeviceCapabilities().touch_input_supported) { diff --git a/hassio/src/addon-store/hassio-addon-repository.ts b/hassio/src/addon-store/hassio-addon-repository.ts index 84d5aa3440..2e789bcace 100644 --- a/hassio/src/addon-store/hassio-addon-repository.ts +++ b/hassio/src/addon-store/hassio-addon-repository.ts @@ -18,6 +18,7 @@ import { } from "../../../src/data/hassio/addon"; import { navigate } from "../../../src/common/navigate"; import { filterAndSort } from "../components/hassio-filter-addons"; +import { atLeastVersion } from "../../../src/common/config/version"; class HassioAddonRepositoryEl extends LitElement { @property() public hass!: HomeAssistant; @@ -39,7 +40,6 @@ class HassioAddonRepositoryEl extends LitElement { protected render(): TemplateResult { const repo = this.repo; const addons = this._getAddons(this.addons, this.filter); - const ha105pluss = this._computeHA105plus; if (this.filter && addons.length < 1) { return html` @@ -92,7 +92,11 @@ class HassioAddonRepositoryEl extends LitElement { : !addon.available ? "not_available" : ""} - .iconImage=${ha105pluss && addon.icon + .iconImage=${atLeastVersion( + this.hass.connection.haVersion, + 0, + 105 + ) && addon.icon ? `/api/hassio/addons/${addon.slug}/icon` : undefined} .showTopbar=${addon.installed || !addon.available} @@ -117,11 +121,6 @@ class HassioAddonRepositoryEl extends LitElement { navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`); } - private get _computeHA105plus(): boolean { - const [major, minor] = this.hass.config.version.split(".", 2); - return Number(major) > 0 || (major === "0" && Number(minor) >= 105); - } - static get styles(): CSSResultArray { return [ hassioStyle, diff --git a/hassio/src/addon-view/hassio-addon-info.ts b/hassio/src/addon-view/hassio-addon-info.ts index b8b8f8c5c4..95503c23fe 100644 --- a/hassio/src/addon-view/hassio-addon-info.ts +++ b/hassio/src/addon-view/hassio-addon-info.ts @@ -36,6 +36,7 @@ import { haStyle } from "../../../src/resources/styles"; import { HomeAssistant } from "../../../src/types"; import { navigate } from "../../../src/common/navigate"; import { showHassioMarkdownDialog } from "../dialogs/markdown/show-dialog-hassio-markdown"; +import { atLeastVersion } from "../../../src/common/config/version"; const PERMIS_DESC = { rating: { @@ -659,7 +660,10 @@ class HassioAddonInfo extends LitElement { } private get _computeCannotIngressSidebar(): boolean { - return !this.addon.ingress || !this._computeHA92plus; + return ( + !this.addon.ingress || + !atLeastVersion(this.hass.connection.haVersion, 0, 92) + ); } private get _computeUsesProtectedOptions(): boolean { @@ -668,11 +672,6 @@ class HassioAddonInfo extends LitElement { ); } - private get _computeHA92plus(): boolean { - const [major, minor] = this.hass.config.version.split(".", 2); - return Number(major) > 0 || (major === "0" && Number(minor) >= 92); - } - private async _startOnBootToggled(): Promise { this._error = undefined; const data: HassioAddonSetOptionParams = { diff --git a/hassio/src/dashboard/hassio-addons.ts b/hassio/src/dashboard/hassio-addons.ts index 801afd1854..908cee988a 100644 --- a/hassio/src/dashboard/hassio-addons.ts +++ b/hassio/src/dashboard/hassio-addons.ts @@ -15,6 +15,7 @@ import { navigate } from "../../../src/common/navigate"; import { hassioStyle } from "../resources/hassio-style"; import { haStyle } from "../../../src/resources/styles"; import "../components/hassio-card-content"; +import { atLeastVersion } from "../../../src/common/config/version"; @customElement("hassio-addons") class HassioAddons extends LitElement { @@ -22,9 +23,6 @@ class HassioAddons extends LitElement { @property() public addons?: HassioAddonInfo[]; protected render(): TemplateResult { - const [major, minor] = this.hass.config.version.split(".", 2); - const ha105pluss = - Number(major) > 0 || (major === "0" && Number(minor) >= 105); return html`

Add-ons

@@ -68,7 +66,11 @@ class HassioAddons extends LitElement { : addon.installed && addon.state === "started" ? "running" : "stopped"} - .iconImage=${ha105pluss && addon.icon + .iconImage=${atLeastVersion( + this.hass.connection.haVersion, + 0, + 105 + ) && addon.icon ? `/api/hassio/addons/${addon.slug}/icon` : undefined} > diff --git a/package.json b/package.json index 9c1c133861..5681e6e51c 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "fuse.js": "^3.4.4", "google-timezones-json": "^1.0.2", "hls.js": "^0.12.4", - "home-assistant-js-websocket": "4.4.1", + "home-assistant-js-websocket": "4.5.0", "intl-messageformat": "^2.2.0", "js-yaml": "^3.13.1", "leaflet": "^1.4.0", diff --git a/src/common/config/version.ts b/src/common/config/version.ts new file mode 100644 index 0000000000..cc6ccf7f7f --- /dev/null +++ b/src/common/config/version.ts @@ -0,0 +1,11 @@ +export const atLeastVersion = ( + version: string, + major: number, + minor: number +): boolean => { + const [haMajor, haMinor] = version.split(".", 2); + return ( + Number(haMajor) > major || + (Number(haMajor) === major && Number(haMinor) >= minor) + ); +}; diff --git a/src/data/lovelace.ts b/src/data/lovelace.ts index a9c11f4cc8..4f62a24224 100644 --- a/src/data/lovelace.ts +++ b/src/data/lovelace.ts @@ -16,6 +16,10 @@ export interface LovelaceConfig { background?: string; } +export interface LegacyLovelaceConfig extends LovelaceConfig { + resources?: LovelaceResource[]; +} + export interface LovelaceResource { id: string; type: "css" | "js" | "module" | "html"; @@ -278,6 +282,34 @@ export const getLovelaceCollection = ( ) ); +// Legacy functions to support cast for Home Assistion < 0.107 +const fetchLegacyConfig = ( + conn: Connection, + force: boolean +): Promise => + conn.sendMessagePromise({ + type: "lovelace/config", + force, + }); + +const subscribeLegacyLovelaceUpdates = ( + conn: Connection, + onChange: () => void +) => conn.subscribeEvents(onChange, "lovelace_updated"); + +export const getLegacyLovelaceCollection = (conn: Connection) => + getCollection( + conn, + "_lovelace", + (conn2) => fetchLegacyConfig(conn2, false), + (_conn, store) => + subscribeLegacyLovelaceUpdates(conn, () => + fetchLegacyConfig(conn, false).then((config) => + store.setState(config, true) + ) + ) + ); + export interface WindowWithLovelaceProm extends Window { llConfProm?: Promise; llResProm?: Promise; diff --git a/src/panels/developer-tools/info/developer-tools-info.ts b/src/panels/developer-tools/info/developer-tools-info.ts index af94401464..2576fda229 100644 --- a/src/panels/developer-tools/info/developer-tools-info.ts +++ b/src/panels/developer-tools/info/developer-tools-info.ts @@ -36,7 +36,7 @@ class HaPanelDevInfo extends LitElement { )}" />
-

Home Assistant ${hass.config.version}

+

Home Assistant ${hass.connection.haVersion}

${this.hass.localize( diff --git a/yarn.lock b/yarn.lock index d2d859218e..36f7e145f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7524,10 +7524,10 @@ hoek@6.x.x: resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.3.tgz#73b7d33952e01fe27a38b0457294b79dd8da242c" integrity sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ== -home-assistant-js-websocket@4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/home-assistant-js-websocket/-/home-assistant-js-websocket-4.4.1.tgz#609943ee5a3e6ec0673b69a6df0c29b86e0d57bf" - integrity sha512-UXVn8rryoL4R9OCdFd04O2J7o1mM1WZIGQpZBVXMIinE9kn6tbkP3JkBGvTPh8mc6JmO3finoxH4ZtZgS+lbHQ== +home-assistant-js-websocket@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/home-assistant-js-websocket/-/home-assistant-js-websocket-4.5.0.tgz#e1cbdd6c279f25839986ffc8368e8c2d533ee0ff" + integrity sha512-ig+zws1MW14XwjMtXRzDBxDZVwvEaluTA9Pq4wqRebKo0Hw7yVix2GFn0wzG75eqC3mc0BlJQiXqBeWhJuJ0pQ== homedir-polyfill@^1.0.1: version "1.0.3"