From be678b02c5c741b6da4273dc8fd0c8bf99451a31 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Mon, 21 Oct 2019 13:04:08 -0500 Subject: [PATCH] Convert more-info-weather to LitElement (#4073) * Convert more-info-weather to LitElement * address comments * add shouldUpdate --- .../more-info/controls/more-info-weather.js | 235 -------------- .../more-info/controls/more-info-weather.ts | 288 ++++++++++++++++++ 2 files changed, 288 insertions(+), 235 deletions(-) delete mode 100644 src/dialogs/more-info/controls/more-info-weather.js create mode 100644 src/dialogs/more-info/controls/more-info-weather.ts diff --git a/src/dialogs/more-info/controls/more-info-weather.js b/src/dialogs/more-info/controls/more-info-weather.js deleted file mode 100644 index a9309905cd..0000000000 --- a/src/dialogs/more-info/controls/more-info-weather.js +++ /dev/null @@ -1,235 +0,0 @@ -import "@polymer/iron-icon/iron-icon"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import LocalizeMixin from "../../../mixins/localize-mixin"; - -/* - * @appliesMixin LocalizeMixin - */ -class MoreInfoWeather extends LocalizeMixin(PolymerElement) { - static get template() { - return html` - - -
- -
- [[localize('ui.card.weather.attributes.temperature')]] -
-
- [[stateObj.attributes.temperature]] [[getUnit('temperature')]] -
-
- - - - - - - - - `; - } - - static get properties() { - return { - hass: Object, - stateObj: Object, - }; - } - - constructor() { - super(); - this.cardinalDirections = [ - "N", - "NNE", - "NE", - "ENE", - "E", - "ESE", - "SE", - "SSE", - "S", - "SSW", - "SW", - "WSW", - "W", - "WNW", - "NW", - "NNW", - "N", - ]; - this.weatherIcons = { - "clear-night": "hass:weather-night", - cloudy: "hass:weather-cloudy", - exceptional: "hass:alert-circle-outline", - fog: "hass:weather-fog", - hail: "hass:weather-hail", - lightning: "hass:weather-lightning", - "lightning-rainy": "hass:weather-lightning-rainy", - partlycloudy: "hass:weather-partly-cloudy", - pouring: "hass:weather-pouring", - rainy: "hass:weather-rainy", - snowy: "hass:weather-snowy", - "snowy-rainy": "hass:weather-snowy-rainy", - sunny: "hass:weather-sunny", - windy: "hass:weather-windy", - "windy-variant": "hass:weather-windy-variant", - }; - } - - computeDate(data) { - const date = new Date(data); - return date.toLocaleDateString(this.hass.language, { - weekday: "long", - month: "short", - day: "numeric", - }); - } - - computeDateTime(data) { - const date = new Date(data); - return date.toLocaleDateString(this.hass.language, { - weekday: "long", - hour: "numeric", - }); - } - - getUnit(measure) { - const lengthUnit = this.hass.config.unit_system.length || ""; - switch (measure) { - case "air_pressure": - return lengthUnit === "km" ? "hPa" : "inHg"; - case "length": - return lengthUnit; - case "precipitation": - return lengthUnit === "km" ? "mm" : "in"; - default: - return this.hass.config.unit_system[measure] || ""; - } - } - - windBearingToText(degree) { - const degreenum = parseInt(degree); - if (isFinite(degreenum)) { - return this.cardinalDirections[(((degreenum + 11.25) / 22.5) | 0) % 16]; - } - return degree; - } - - getWind(speed, bearing, localize) { - if (bearing != null) { - const cardinalDirection = this.windBearingToText(bearing); - return `${speed} ${this.getUnit("length")}/h (${localize( - `ui.card.weather.cardinal_direction.${cardinalDirection.toLowerCase()}` - ) || cardinalDirection})`; - } - return `${speed} ${this.getUnit("length")}/h`; - } - - getWeatherIcon(condition) { - return this.weatherIcons[condition]; - } - - _showValue(item) { - return typeof item !== "undefined" && item !== null; - } -} - -customElements.define("more-info-weather", MoreInfoWeather); diff --git a/src/dialogs/more-info/controls/more-info-weather.ts b/src/dialogs/more-info/controls/more-info-weather.ts new file mode 100644 index 0000000000..8d14f80cac --- /dev/null +++ b/src/dialogs/more-info/controls/more-info-weather.ts @@ -0,0 +1,288 @@ +import "@polymer/iron-icon/iron-icon"; +import { + LitElement, + property, + CSSResult, + css, + customElement, + PropertyValues, +} from "lit-element"; +import { HassEntity } from "home-assistant-js-websocket"; +import { TemplateResult, html } from "lit-html"; + +import { HomeAssistant } from "../../../types"; + +const cardinalDirections = [ + "N", + "NNE", + "NE", + "ENE", + "E", + "ESE", + "SE", + "SSE", + "S", + "SSW", + "SW", + "WSW", + "W", + "WNW", + "NW", + "NNW", + "N", +]; + +const weatherIcons = { + "clear-night": "hass:weather-night", + cloudy: "hass:weather-cloudy", + exceptional: "hass:alert-circle-outline", + fog: "hass:weather-fog", + hail: "hass:weather-hail", + lightning: "hass:weather-lightning", + "lightning-rainy": "hass:weather-lightning-rainy", + partlycloudy: "hass:weather-partly-cloudy", + pouring: "hass:weather-pouring", + rainy: "hass:weather-rainy", + snowy: "hass:weather-snowy", + "snowy-rainy": "hass:weather-snowy-rainy", + sunny: "hass:weather-sunny", + windy: "hass:weather-windy", + "windy-variant": "hass:weather-windy-variant", +}; + +@customElement("more-info-weather") +class MoreInfoWeather extends LitElement { + @property() public hass!: HomeAssistant; + @property() public stateObj?: HassEntity; + + protected shouldUpdate(changedProps: PropertyValues): boolean { + if (changedProps.has("stateObj")) { + return true; + } + + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if ( + !oldHass || + oldHass.language !== this.hass.language || + oldHass.config.unit_system !== this.hass.config.unit_system + ) { + return true; + } + + return false; + } + + protected render(): TemplateResult | void { + if (!this.hass || !this.stateObj) { + return html``; + } + + return html` +
+ +
+ ${this.hass.localize("ui.card.weather.attributes.temperature")} +
+
+ ${this.stateObj.attributes.temperature} ${this.getUnit("temperature")} +
+
+ ${this.stateObj.attributes.pressure + ? html` +
+ +
+ ${this.hass.localize("ui.card.weather.attributes.air_pressure")} +
+
+ ${this.stateObj.attributes.pressure} + ${this.getUnit("air_pressure")} +
+
+ ` + : ""} + ${this.stateObj.attributes.humidity + ? html` +
+ +
+ ${this.hass.localize("ui.card.weather.attributes.humidity")} +
+
${this.stateObj.attributes.humidity} %
+
+ ` + : ""} + ${this.stateObj.attributes.wind_speed + ? html` +
+ +
+ ${this.hass.localize("ui.card.weather.attributes.wind_speed")} +
+
+ ${this.getWind( + this.stateObj.attributes.wind_speed, + this.stateObj.attributes.wind_bearing + )} +
+
+ ` + : ""} + ${this.stateObj.attributes.visibility + ? html` +
+ +
+ ${this.hass.localize("ui.card.weather.attributes.visibility")} +
+
+ ${this.stateObj.attributes.visibility} ${this.getUnit("length")} +
+
+ ` + : ""} + ${this.stateObj.attributes.forecast + ? html` +
+ ${this.hass.localize("ui.card.weather.forecast")}: +
+ ${this.stateObj.attributes.forecast.map((item) => { + return html` +
+ ${item.condition + ? html` + + ` + : ""} + ${!item.templow + ? html` +
+ ${this.computeDateTime(item.datetime)} +
+ ` + : ""} + ${item.templow + ? html` +
+ ${this.computeDate(item.datetime)} +
+
+ ${item.templow} ${this.getUnit("temperature")} +
+ ` + : ""}; +
+ ${item.temperature} ${this.getUnit("temperature")} +
+
+ `; + })} + ` + : ""} + ${this.stateObj.attributes.attribution + ? html` +
+ ${this.stateObj.attributes.attribution} +
+ ` + : ""} + `; + } + + static get styles(): CSSResult { + return css` + iron-icon { + color: var(--paper-item-icon-color); + } + .section { + margin: 16px 0 8px 0; + font-size: 1.2em; + } + + .flex { + display: flex; + height: 32px; + align-items: center; + } + + .main { + flex: 1; + margin-left: 24px; + } + + .temp, + .templow { + min-width: 48px; + text-align: right; + } + + .templow { + margin: 0 16px; + color: var(--secondary-text-color); + } + + .attribution { + color: var(--secondary-text-color); + text-align: center; + } + `; + } + + private computeDate(data) { + const date = new Date(data); + return date.toLocaleDateString(this.hass.language, { + weekday: "long", + month: "short", + day: "numeric", + }); + } + + private computeDateTime(data) { + const date = new Date(data); + return date.toLocaleDateString(this.hass.language, { + weekday: "long", + hour: "numeric", + }); + } + + private getUnit(measure: string): string { + const lengthUnit = this.hass.config.unit_system.length || ""; + switch (measure) { + case "air_pressure": + return lengthUnit === "km" ? "hPa" : "inHg"; + case "length": + return lengthUnit; + case "precipitation": + return lengthUnit === "km" ? "mm" : "in"; + default: + return this.hass.config.unit_system[measure] || ""; + } + } + + private windBearingToText(degree: string): string { + const degreenum = parseInt(degree, 10); + if (isFinite(degreenum)) { + // tslint:disable-next-line: no-bitwise + return cardinalDirections[(((degreenum + 11.25) / 22.5) | 0) % 16]; + } + return degree; + } + + private getWind(speed: string, bearing: string) { + if (bearing != null) { + const cardinalDirection = this.windBearingToText(bearing); + return `${speed} ${this.getUnit("length")}/h (${this.hass.localize( + `ui.card.weather.cardinal_direction.${cardinalDirection.toLowerCase()}` + ) || cardinalDirection})`; + } + return `${speed} ${this.getUnit("length")}/h`; + } +} + +declare global { + interface HTMLElementTagNameMap { + "more-info-weather": MoreInfoWeather; + } +}