From 372cfdecf459d8e6b083051b2b99d101b17e0f78 Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Fri, 2 Nov 2018 15:59:14 -0400 Subject: [PATCH] Light, Thermostat, and Gauge - Theme Addition (#1947) * Update to have theme options * Make ShouldUpdate into a help function * Adding types to changed function --- src/panels/lovelace/cards/hui-gauge-card.ts | 27 +++++++------ src/panels/lovelace/cards/hui-light-card.ts | 39 ++++++++++-------- .../lovelace/cards/hui-thermostat-card.ts | 40 ++++++++++--------- src/panels/lovelace/common/has-changed.ts | 22 ++++++++++ 4 files changed, 81 insertions(+), 47 deletions(-) create mode 100644 src/panels/lovelace/common/has-changed.ts diff --git a/src/panels/lovelace/cards/hui-gauge-card.ts b/src/panels/lovelace/cards/hui-gauge-card.ts index 92ddcb9d1e..5a6ebddf26 100644 --- a/src/panels/lovelace/cards/hui-gauge-card.ts +++ b/src/panels/lovelace/cards/hui-gauge-card.ts @@ -4,11 +4,15 @@ import { PropertyDeclarations, PropertyValues, } from "@polymer/lit-element"; +import { TemplateResult } from "lit-html"; + import { LovelaceCard, LovelaceConfig } from "../types"; import { HomeAssistant } from "../../../types"; import { fireEvent } from "../../../common/dom/fire_event"; -import { TemplateResult } from "lit-html"; + import isValidEntityId from "../../../common/entity/valid_entity_id"; +import applyThemesOnElement from "../../../common/dom/apply_themes_on_element"; +import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../../../components/ha-card"; @@ -19,6 +23,7 @@ interface Config extends LovelaceConfig { min?: number; max?: number; severity?: object; + theme?: string; } const severityMap = { @@ -50,7 +55,7 @@ class HuiGaugeCard extends LitElement implements LovelaceCard { if (!isValidEntityId(config.entity)) { throw new Error("Invalid Entity"); } - this._config = { min: 0, max: 100, ...config }; + this._config = { min: 0, max: 100, theme: "default", ...config }; } protected render(): TemplateResult { @@ -94,19 +99,10 @@ class HuiGaugeCard extends LitElement implements LovelaceCard { } protected shouldUpdate(changedProps: PropertyValues): boolean { - if (changedProps.get("hass")) { - return ( - (changedProps.get("hass") as any).states[this._config!.entity] !== - this.hass!.states[this._config!.entity] - ); - } - if (changedProps.get("_config")) { - return changedProps.get("_config") !== this._config; - } - return true; + return hasConfigOrEntityChanged(this, changedProps); } - protected updated(): void { + protected updated(changedProps: PropertyValues): void { if ( !this._config || !this.hass || @@ -134,6 +130,11 @@ class HuiGaugeCard extends LitElement implements LovelaceCard { "--base-unit", this._computeBaseUnit() ); + + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if (!oldHass || oldHass.themes !== this.hass.themes) { + applyThemesOnElement(this, this.hass.themes, this._config.theme); + } } private renderStyle(): TemplateResult { diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index d8f97ca029..21de8ab87c 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -4,21 +4,24 @@ import { PropertyValues, PropertyDeclarations, } from "@polymer/lit-element"; +import { TemplateResult } from "lit-html"; + import { fireEvent } from "../../../common/dom/fire_event"; import { styleMap } from "lit-html/directives/styleMap"; -import computeStateName from "../../../common/entity/compute_state_name"; -import stateIcon from "../../../common/entity/state_icon"; import { jQuery } from "../../../resources/jquery"; - -import "../../../components/ha-card"; -import "../../../components/ha-icon"; import { roundSliderStyle } from "../../../resources/jquery.roundslider"; - import { HomeAssistant, LightEntity } from "../../../types"; import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin"; import { LovelaceCard, LovelaceConfig } from "../types"; import { longPress } from "../common/directives/long-press-directive"; -import { TemplateResult } from "lit-html"; + +import stateIcon from "../../../common/entity/state_icon"; +import computeStateName from "../../../common/entity/compute_state_name"; +import applyThemesOnElement from "../../../common/dom/apply_themes_on_element"; +import { hasConfigOrEntityChanged } from "../common/has-changed"; + +import "../../../components/ha-card"; +import "../../../components/ha-icon"; const lightConfig = { radius: 80, @@ -37,6 +40,7 @@ const lightConfig = { interface Config extends LovelaceConfig { entity: string; name?: string; + theme?: string; } export class HuiLightCard extends hassLocalizeLitMixin(LitElement) @@ -61,7 +65,7 @@ export class HuiLightCard extends hassLocalizeLitMixin(LitElement) throw new Error("Specify an entity from within the light domain."); } - this._config = config; + this._config = { theme: "default", ...config }; } protected render(): TemplateResult { @@ -113,13 +117,7 @@ export class HuiLightCard extends hassLocalizeLitMixin(LitElement) } protected shouldUpdate(changedProps: PropertyValues): boolean { - if (changedProps.get("hass")) { - return ( - (changedProps.get("hass") as any).states[this._config!.entity] !== - this.hass!.states[this._config!.entity] - ); - } - return (changedProps as unknown) as boolean; + return hasConfigOrEntityChanged(this, changedProps); } protected firstUpdated(): void { @@ -136,12 +134,21 @@ export class HuiLightCard extends hassLocalizeLitMixin(LitElement) (Math.round((brightness / 254) * 100) || 0) + "%"; } - protected updated(): void { + protected updated(changedProps: PropertyValues): void { + if (!this._config || !this.hass) { + return; + } + const attrs = this.hass!.states[this._config!.entity].attributes; jQuery("#light", this.shadowRoot).roundSlider({ value: Math.round((attrs.brightness / 254) * 100) || 0, }); + + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if (!oldHass || oldHass.themes !== this.hass.themes) { + applyThemesOnElement(this, this.hass.themes, this._config.theme); + } } private renderStyle(): TemplateResult { diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index ef5ca1079f..b072ef5561 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -5,17 +5,20 @@ import { PropertyValues, } from "@polymer/lit-element"; import { classMap } from "lit-html/directives/classMap"; +import { TemplateResult } from "lit-html"; import { jQuery } from "../../../resources/jquery"; -import "../../../components/ha-card"; -import "../../../components/ha-icon"; -import { roundSliderStyle } from "../../../resources/jquery.roundslider"; +import applyThemesOnElement from "../../../common/dom/apply_themes_on_element"; +import computeStateName from "../../../common/entity/compute_state_name"; +import { hasConfigOrEntityChanged } from "../common/has-changed"; +import { roundSliderStyle } from "../../../resources/jquery.roundslider"; import { HomeAssistant, ClimateEntity } from "../../../types"; import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin"; import { LovelaceCard, LovelaceConfig } from "../types"; -import computeStateName from "../../../common/entity/compute_state_name"; -import { TemplateResult } from "lit-html"; + +import "../../../components/ha-card"; +import "../../../components/ha-icon"; const thermostatConfig = { radius: 150, @@ -37,6 +40,7 @@ const modeIcons = { interface Config extends LovelaceConfig { entity: string; + theme?: string; } function formatTemp(temps: string[]): string { @@ -64,7 +68,7 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) throw new Error("Specify an entity from within the climate domain."); } - this._config = config; + this._config = { theme: "default", ...config }; } protected render(): TemplateResult { @@ -114,16 +118,7 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) } protected shouldUpdate(changedProps: PropertyValues): boolean { - if (changedProps.get("hass")) { - return ( - (changedProps.get("hass") as any).states[this._config!.entity] !== - this.hass!.states[this._config!.entity] - ); - } - if (changedProps.has("_config")) { - return true; - } - return true; + return hasConfigOrEntityChanged(this, changedProps); } protected firstUpdated(): void { @@ -146,8 +141,12 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) }); } - protected updated(): void { - const stateObj = this.hass!.states[this._config!.entity] as ClimateEntity; + protected updated(changedProps: PropertyValues): void { + if (!this._config || !this.hass) { + return; + } + + const stateObj = this.hass.states[this._config.entity] as ClimateEntity; let sliderValue; let uiValue; @@ -171,6 +170,11 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) value: sliderValue, }); this.shadowRoot!.querySelector("#set-temperature")!.innerHTML = uiValue; + + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if (!oldHass || oldHass.themes !== this.hass.themes) { + applyThemesOnElement(this, this.hass.themes, this._config.theme); + } } private renderStyle(): TemplateResult { diff --git a/src/panels/lovelace/common/has-changed.ts b/src/panels/lovelace/common/has-changed.ts new file mode 100644 index 0000000000..d246bebc49 --- /dev/null +++ b/src/panels/lovelace/common/has-changed.ts @@ -0,0 +1,22 @@ +import { HomeAssistant } from "../../../types"; +import { PropertyValues } from "@polymer/lit-element"; + +// Check if config or Entity changed +export function hasConfigOrEntityChanged( + element: any, + changedProps: PropertyValues +): boolean { + if (changedProps.has("_config")) { + return true; + } + + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if (oldHass) { + return ( + oldHass.states[element._config!.entity] !== + element.hass!.states[element._config!.entity] + ); + } + + return true; +}