From 5df758c0b2c9ae6a48b3d3e10cfaf0b72237d962 Mon Sep 17 00:00:00 2001 From: Jerad Meisner Date: Tue, 10 Jul 2018 02:37:46 -0700 Subject: [PATCH] Add configurable filter and state_filter to hui-image. (#1423) * Add configurable filter and state_filter to hui-image. * Rename state -> stateObj. * Cleanup * Remove unnecessary CSS * Use placeholder for broken images. * Update broken image --- public/images/image-broken.svg | 1 + src/panels/lovelace/components/hui-image.js | 102 +++++++++++--------- 2 files changed, 56 insertions(+), 47 deletions(-) create mode 100644 public/images/image-broken.svg diff --git a/public/images/image-broken.svg b/public/images/image-broken.svg new file mode 100644 index 0000000000..cbd2559a26 --- /dev/null +++ b/public/images/image-broken.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/panels/lovelace/components/hui-image.js b/src/panels/lovelace/components/hui-image.js index 7926501752..5ec4d1accd 100644 --- a/src/panels/lovelace/components/hui-image.js +++ b/src/panels/lovelace/components/hui-image.js @@ -4,9 +4,9 @@ import '@polymer/paper-toggle-button/paper-toggle-button.js'; import { STATES_OFF } from '../../../common/const.js'; import LocalizeMixin from '../../../mixins/localize-mixin.js'; -import isValidObject from '../common/is-valid-object'; const UPDATE_INTERVAL = 10000; +const DEFAULT_FILTER = 'grayscale(100%)'; /* * @appliesMixin LocalizeMixin @@ -15,35 +15,33 @@ class HuiImage extends LocalizeMixin(PolymerElement) { static get template() { return html` - - - + + +
`; } @@ -57,11 +55,8 @@ class HuiImage extends LocalizeMixin(PolymerElement) { image: String, stateImage: Object, cameraImage: String, - _error: { - type: Boolean, - value: false - }, - _imageClass: String, + filter: String, + stateFilter: Object, _imageSrc: String }; } @@ -91,14 +86,16 @@ class HuiImage extends LocalizeMixin(PolymerElement) { } _onImageError() { - this.setProperties({ - _imageSrc: null, - _error: true - }); + this._imageSrc = null; + this.$.image.classList.add('hidden'); + this.$.brokenImage.style.setProperty('height', `${this._lastImageHeight || '100'}px`); + this.$.brokenImage.classList.remove('hidden'); } _onImageLoad() { - this._error = false; + this.$.image.classList.remove('hidden'); + this.$.brokenImage.classList.add('hidden'); + this._lastImageHeight = this.$.image.offsetHeight; } _hassChanged(hass) { @@ -106,20 +103,36 @@ class HuiImage extends LocalizeMixin(PolymerElement) { return; } - const state = hass.states[this.entity]; - const unavailable = !isValidObject(state, ['state']); + const stateObj = hass.states[this.entity]; + const newState = !stateObj ? 'unavailable' : stateObj.state; + if (newState === this._currentState) return; + this._currentState = newState; + + this._updateStateImage(); + this._updateStateFilter(stateObj); + } + + _updateStateImage() { if (!this.stateImage) { - this._imageClass = unavailable || STATES_OFF.includes(state.state) ? 'state-off' : ''; + this._imageFallback = true; return; } + const stateImg = this.stateImage[this._currentState]; + this._imageSrc = stateImg || this.image; + this._imageFallback = !stateImg; + } - const stateImg = !unavailable ? this.stateImage[state.state] : this.stateImage.unavailable; + _updateStateFilter(stateObj) { + let filter; + if (!this.stateFilter) { + filter = this.filter; + } else { + filter = this.stateFilter[this._currentState] || this.filter; + } - this.setProperties({ - _imageClass: !stateImg && (unavailable || STATES_OFF.includes(state.state)) ? 'state-off' : '', - _imageSrc: stateImg || this.image - }); + const isOff = !stateObj || STATES_OFF.includes(stateObj.state); + this.$.image.style.filter = filter || (isOff && this._imageFallback && DEFAULT_FILTER) || ''; } _updateCameraImageSrc() { @@ -128,17 +141,12 @@ class HuiImage extends LocalizeMixin(PolymerElement) { entity_id: this.cameraImage, }).then((resp) => { if (resp.success) { - this.setProperties({ - _imageSrc: `data:${resp.result.content_type};base64, ${resp.result.content}`, - _error: false - }); + this._imageSrc = `data:${resp.result.content_type};base64, ${resp.result.content}`; + this._onImageLoad(); } else { - this.setProperties({ - _imageSrc: null, - _error: true - }); + this._onImageError(); } - }); + }, () => this._onImageError()); } }