mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 10:16:46 +00:00
Better fix for ha-entity-toggle (#2873)
This commit is contained in:
parent
178e4de452
commit
9383d80354
@ -10,14 +10,19 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
css,
|
css,
|
||||||
property,
|
property,
|
||||||
|
PropertyValues,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
|
const isOn = (stateObj?: HassEntity) =>
|
||||||
|
stateObj !== undefined && !STATES_OFF.includes(stateObj.state);
|
||||||
|
|
||||||
class HaEntityToggle extends LitElement {
|
class HaEntityToggle extends LitElement {
|
||||||
// hass is not a property so that we only re-render on stateObj changes
|
// hass is not a property so that we only re-render on stateObj changes
|
||||||
public hass?: HomeAssistant;
|
public hass?: HomeAssistant;
|
||||||
@property() public stateObj?: HassEntity;
|
@property() public stateObj?: HassEntity;
|
||||||
|
@property() private _isOn: boolean = false;
|
||||||
|
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
if (!this.stateObj) {
|
if (!this.stateObj) {
|
||||||
@ -26,26 +31,24 @@ class HaEntityToggle extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isOn = this._isOn;
|
|
||||||
|
|
||||||
if (this.stateObj.attributes.assumed_state) {
|
if (this.stateObj.attributes.assumed_state) {
|
||||||
return html`
|
return html`
|
||||||
<paper-icon-button
|
<paper-icon-button
|
||||||
icon="hass:flash-off"
|
icon="hass:flash-off"
|
||||||
@click=${this._turnOff}
|
@click=${this._turnOff}
|
||||||
?state-active=${!isOn}
|
?state-active=${!this._isOn}
|
||||||
></paper-icon-button>
|
></paper-icon-button>
|
||||||
<paper-icon-button
|
<paper-icon-button
|
||||||
icon="hass:flash"
|
icon="hass:flash"
|
||||||
@click=${this._turnOn}
|
@click=${this._turnOn}
|
||||||
?state-active=${isOn}
|
?state-active=${this._isOn}
|
||||||
></paper-icon-button>
|
></paper-icon-button>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<paper-toggle-button
|
<paper-toggle-button
|
||||||
.checked=${isOn}
|
.checked=${this._isOn}
|
||||||
@change=${this._toggleChanged}
|
@change=${this._toggleChanged}
|
||||||
></paper-toggle-button>
|
></paper-toggle-button>
|
||||||
`;
|
`;
|
||||||
@ -56,10 +59,10 @@ class HaEntityToggle extends LitElement {
|
|||||||
this.addEventListener("click", (ev) => ev.stopPropagation());
|
this.addEventListener("click", (ev) => ev.stopPropagation());
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _isOn(): boolean {
|
protected updated(changedProps: PropertyValues): void {
|
||||||
return (
|
if (changedProps.has("stateObj")) {
|
||||||
this.stateObj !== undefined && !STATES_OFF.includes(this.stateObj.state)
|
this._isOn = isOn(this.stateObj);
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _toggleChanged(ev) {
|
private _toggleChanged(ev) {
|
||||||
@ -106,6 +109,9 @@ class HaEntityToggle extends LitElement {
|
|||||||
|
|
||||||
const currentState = this.stateObj;
|
const currentState = this.stateObj;
|
||||||
|
|
||||||
|
// Optimistic update.
|
||||||
|
this._isOn = turnOn;
|
||||||
|
|
||||||
await this.hass.callService(serviceDomain, service, {
|
await this.hass.callService(serviceDomain, service, {
|
||||||
entity_id: this.stateObj.entity_id,
|
entity_id: this.stateObj.entity_id,
|
||||||
});
|
});
|
||||||
@ -113,18 +119,8 @@ class HaEntityToggle extends LitElement {
|
|||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
// If after 2 seconds we have not received a state update
|
// If after 2 seconds we have not received a state update
|
||||||
// reset the switch to it's original state.
|
// reset the switch to it's original state.
|
||||||
if (this.stateObj !== currentState) {
|
if (this.stateObj === currentState) {
|
||||||
return;
|
this._isOn = isOn(this.stateObj);
|
||||||
}
|
|
||||||
// Force a re-render. It's not good enough to just call this.requestUpdate()
|
|
||||||
// because the value has changed outside of Lit's render function, and so Lit
|
|
||||||
// won't update the property again, because it's the same as last update.
|
|
||||||
// So we just temporarily unset the stateObj and set it again.
|
|
||||||
this.stateObj = undefined;
|
|
||||||
await this.updateComplete;
|
|
||||||
// Make sure that a stateObj was not set in between.
|
|
||||||
if (this.stateObj === undefined) {
|
|
||||||
this.stateObj = currentState;
|
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user