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
This commit is contained in:
Jerad Meisner 2018-07-10 02:37:46 -07:00 committed by Paulus Schoutsen
parent 77c65d43ae
commit 5df758c0b2
2 changed files with 56 additions and 47 deletions

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="36" height="36" viewBox="0 0 24 24"><path fill="#505050" d="M19,3A2,2 0 0,1 21,5V11H19V13H19L17,13V15H15V17H13V19H11V21H5C3.89,21 3,20.1 3,19V5A2,2 0 0,1 5,3H19M21,15V19A2,2 0 0,1 19,21H19L15,21V19H17V17H19V15H21M19,8.5A0.5,0.5 0 0,0 18.5,8H5.5A0.5,0.5 0 0,0 5,8.5V15.5A0.5,0.5 0 0,0 5.5,16H11V15H13V13H15V11H17V9H19V8.5Z" /></svg>

After

Width:  |  Height:  |  Size: 571 B

View File

@ -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`
<style>
.state-off {
filter: grayscale(100%);
}
img {
display: block;
height: auto;
transition: filter .2s linear;
width: 100%;
}
.error {
width: 100%;
height: auto;
text-align: center;
}
.hidden {
display: none;
}
#brokenImage {
background: grey url('/static/images/image-broken.svg') center/36px no-repeat;
}
</style>
<template is="dom-if" if="[[_imageSrc]]">
<img
src="[[_imageSrc]]"
on-error="_onImageError"
on-load="_onImageLoad"
class$="[[_imageClass]]" />
</template>
<template is="dom-if" if="[[_error]]">
<div class="error">[[localize('ui.card.camera.not_available')]]</div>
</template>
<img
id="image"
src="[[_imageSrc]]"
on-error="_onImageError"
on-load="_onImageLoad" />
<div id="brokenImage"></div>
`;
}
@ -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());
}
}