mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
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:
parent
77c65d43ae
commit
5df758c0b2
1
public/images/image-broken.svg
Normal file
1
public/images/image-broken.svg
Normal 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 |
@ -4,9 +4,9 @@ import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
|||||||
|
|
||||||
import { STATES_OFF } from '../../../common/const.js';
|
import { STATES_OFF } from '../../../common/const.js';
|
||||||
import LocalizeMixin from '../../../mixins/localize-mixin.js';
|
import LocalizeMixin from '../../../mixins/localize-mixin.js';
|
||||||
import isValidObject from '../common/is-valid-object';
|
|
||||||
|
|
||||||
const UPDATE_INTERVAL = 10000;
|
const UPDATE_INTERVAL = 10000;
|
||||||
|
const DEFAULT_FILTER = 'grayscale(100%)';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin LocalizeMixin
|
* @appliesMixin LocalizeMixin
|
||||||
@ -15,35 +15,33 @@ class HuiImage extends LocalizeMixin(PolymerElement) {
|
|||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
.state-off {
|
|
||||||
filter: grayscale(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
height: auto;
|
height: auto;
|
||||||
transition: filter .2s linear;
|
transition: filter .2s linear;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#brokenImage {
|
||||||
|
background: grey url('/static/images/image-broken.svg') center/36px no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<template is="dom-if" if="[[_imageSrc]]">
|
<img
|
||||||
<img
|
id="image"
|
||||||
src="[[_imageSrc]]"
|
src="[[_imageSrc]]"
|
||||||
on-error="_onImageError"
|
on-error="_onImageError"
|
||||||
on-load="_onImageLoad"
|
on-load="_onImageLoad" />
|
||||||
class$="[[_imageClass]]" />
|
<div id="brokenImage"></div>
|
||||||
</template>
|
|
||||||
<template is="dom-if" if="[[_error]]">
|
|
||||||
<div class="error">[[localize('ui.card.camera.not_available')]]</div>
|
|
||||||
</template>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,11 +55,8 @@ class HuiImage extends LocalizeMixin(PolymerElement) {
|
|||||||
image: String,
|
image: String,
|
||||||
stateImage: Object,
|
stateImage: Object,
|
||||||
cameraImage: String,
|
cameraImage: String,
|
||||||
_error: {
|
filter: String,
|
||||||
type: Boolean,
|
stateFilter: Object,
|
||||||
value: false
|
|
||||||
},
|
|
||||||
_imageClass: String,
|
|
||||||
_imageSrc: String
|
_imageSrc: String
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -91,14 +86,16 @@ class HuiImage extends LocalizeMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onImageError() {
|
_onImageError() {
|
||||||
this.setProperties({
|
this._imageSrc = null;
|
||||||
_imageSrc: null,
|
this.$.image.classList.add('hidden');
|
||||||
_error: true
|
this.$.brokenImage.style.setProperty('height', `${this._lastImageHeight || '100'}px`);
|
||||||
});
|
this.$.brokenImage.classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
_onImageLoad() {
|
_onImageLoad() {
|
||||||
this._error = false;
|
this.$.image.classList.remove('hidden');
|
||||||
|
this.$.brokenImage.classList.add('hidden');
|
||||||
|
this._lastImageHeight = this.$.image.offsetHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hassChanged(hass) {
|
_hassChanged(hass) {
|
||||||
@ -106,20 +103,36 @@ class HuiImage extends LocalizeMixin(PolymerElement) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = hass.states[this.entity];
|
const stateObj = hass.states[this.entity];
|
||||||
const unavailable = !isValidObject(state, ['state']);
|
const newState = !stateObj ? 'unavailable' : stateObj.state;
|
||||||
|
|
||||||
|
if (newState === this._currentState) return;
|
||||||
|
this._currentState = newState;
|
||||||
|
|
||||||
|
this._updateStateImage();
|
||||||
|
this._updateStateFilter(stateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateStateImage() {
|
||||||
if (!this.stateImage) {
|
if (!this.stateImage) {
|
||||||
this._imageClass = unavailable || STATES_OFF.includes(state.state) ? 'state-off' : '';
|
this._imageFallback = true;
|
||||||
return;
|
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({
|
const isOff = !stateObj || STATES_OFF.includes(stateObj.state);
|
||||||
_imageClass: !stateImg && (unavailable || STATES_OFF.includes(state.state)) ? 'state-off' : '',
|
this.$.image.style.filter = filter || (isOff && this._imageFallback && DEFAULT_FILTER) || '';
|
||||||
_imageSrc: stateImg || this.image
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateCameraImageSrc() {
|
_updateCameraImageSrc() {
|
||||||
@ -128,17 +141,12 @@ class HuiImage extends LocalizeMixin(PolymerElement) {
|
|||||||
entity_id: this.cameraImage,
|
entity_id: this.cameraImage,
|
||||||
}).then((resp) => {
|
}).then((resp) => {
|
||||||
if (resp.success) {
|
if (resp.success) {
|
||||||
this.setProperties({
|
this._imageSrc = `data:${resp.result.content_type};base64, ${resp.result.content}`;
|
||||||
_imageSrc: `data:${resp.result.content_type};base64, ${resp.result.content}`,
|
this._onImageLoad();
|
||||||
_error: false
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.setProperties({
|
this._onImageError();
|
||||||
_imageSrc: null,
|
|
||||||
_error: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
}, () => this._onImageError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user