Fix shopping list initial data fetch (#6020)

This commit is contained in:
Bram Kragten 2020-05-26 09:44:46 +02:00 committed by GitHub
parent 66409f0fa5
commit 8ad2bf5401
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 90 deletions

View File

@ -12,7 +12,7 @@ export const SubscribeMixin = <T extends Constructor<UpdatingElement>>(
class SubscribeClass extends superClass { class SubscribeClass extends superClass {
@property() public hass?: HomeAssistant; @property() public hass?: HomeAssistant;
private __unsubs?: UnsubscribeFunc[]; private __unsubs?: Array<UnsubscribeFunc | Promise<UnsubscribeFunc>>;
public connectedCallback() { public connectedCallback() {
super.connectedCallback(); super.connectedCallback();
@ -23,7 +23,8 @@ export const SubscribeMixin = <T extends Constructor<UpdatingElement>>(
super.disconnectedCallback(); super.disconnectedCallback();
if (this.__unsubs) { if (this.__unsubs) {
while (this.__unsubs.length) { while (this.__unsubs.length) {
this.__unsubs.pop()!(); const unsub = this.__unsubs.pop()!;
Promise.resolve(unsub).then((unsubFunc) => unsubFunc());
} }
this.__unsubs = undefined; this.__unsubs = undefined;
} }
@ -36,7 +37,9 @@ export const SubscribeMixin = <T extends Constructor<UpdatingElement>>(
} }
} }
protected hassSubscribe(): UnsubscribeFunc[] { protected hassSubscribe(): Array<
UnsubscribeFunc | Promise<UnsubscribeFunc>
> {
return []; return [];
} }

View File

@ -41,7 +41,7 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard {
@property() private _content = ""; @property() private _content = "";
@property() private _unsubRenderTemplate?: UnsubscribeFunc; @property() private _unsubRenderTemplate?: Promise<UnsubscribeFunc>;
public getCardSize(): number { public getCardSize(): number {
return this._config === undefined return this._config === undefined
@ -122,7 +122,7 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard {
} }
try { try {
this._unsubRenderTemplate = await subscribeRenderTemplate( this._unsubRenderTemplate = subscribeRenderTemplate(
this.hass.connection, this.hass.connection,
(result) => { (result) => {
this._content = result; this._content = result;
@ -148,7 +148,8 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard {
} }
try { try {
this._unsubRenderTemplate(); const unsub = await this._unsubRenderTemplate;
unsub();
this._unsubRenderTemplate = undefined; this._unsubRenderTemplate = undefined;
} catch (e) { } catch (e) {
if (e.code === "not_found") { if (e.code === "not_found") {

View File

@ -25,9 +25,12 @@ import {
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { LovelaceCard, LovelaceCardEditor } from "../types"; import { LovelaceCard, LovelaceCardEditor } from "../types";
import { SensorCardConfig, ShoppingListCardConfig } from "./types"; import { SensorCardConfig, ShoppingListCardConfig } from "./types";
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
@customElement("hui-shopping-list-card") @customElement("hui-shopping-list-card")
class HuiShoppingListCard extends LitElement implements LovelaceCard { class HuiShoppingListCard extends SubscribeMixin(LitElement)
implements LovelaceCard {
public static async getConfigElement(): Promise<LovelaceCardEditor> { public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import( await import(
/* webpackChunkName: "hui-shopping-list-editor" */ "../editor/config-elements/hui-shopping-list-editor" /* webpackChunkName: "hui-shopping-list-editor" */ "../editor/config-elements/hui-shopping-list-editor"
@ -47,8 +50,6 @@ class HuiShoppingListCard extends LitElement implements LovelaceCard {
@property() private _checkedItems?: ShoppingListItem[]; @property() private _checkedItems?: ShoppingListItem[];
private _unsubEvents?: Promise<() => Promise<void>>;
public getCardSize(): number { public getCardSize(): number {
return (this._config ? (this._config.title ? 1 : 0) : 0) + 3; return (this._config ? (this._config.title ? 1 : 0) : 0) + 3;
} }
@ -57,27 +58,16 @@ class HuiShoppingListCard extends LitElement implements LovelaceCard {
this._config = config; this._config = config;
this._uncheckedItems = []; this._uncheckedItems = [];
this._checkedItems = []; this._checkedItems = [];
this._fetchData();
} }
public connectedCallback(): void { public hassSubscribe(): Promise<UnsubscribeFunc>[] {
super.connectedCallback(); this._fetchData();
return [
if (this.hass) { this.hass!.connection.subscribeEvents(
this._unsubEvents = this.hass.connection.subscribeEvents(
() => this._fetchData(), () => this._fetchData(),
"shopping_list_updated" "shopping_list_updated"
); ),
this._fetchData(); ];
}
}
public disconnectedCallback(): void {
super.disconnectedCallback();
if (this._unsubEvents) {
this._unsubEvents.then((unsub) => unsub());
}
} }
protected updated(changedProps: PropertyValues): void { protected updated(changedProps: PropertyValues): void {
@ -85,16 +75,15 @@ class HuiShoppingListCard extends LitElement implements LovelaceCard {
if (!this._config || !this.hass) { if (!this._config || !this.hass) {
return; return;
} }
const oldHass = changedProps.get("hass") as HomeAssistant | undefined; const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
const oldConfig = changedProps.get("_config") as const oldConfig = changedProps.get("_config") as
| SensorCardConfig | SensorCardConfig
| undefined; | undefined;
if ( if (
!oldHass || (changedProps.has("hass") && oldHass?.themes !== this.hass.themes) ||
!oldConfig || (changedProps.has("_config") && oldConfig?.theme !== this._config.theme)
oldHass.themes !== this.hass.themes ||
oldConfig.theme !== this._config.theme
) { ) {
applyThemesOnElement(this, this.hass.themes, this._config.theme); applyThemesOnElement(this, this.hass.themes, this._config.theme);
} }
@ -199,6 +188,67 @@ class HuiShoppingListCard extends LitElement implements LovelaceCard {
`; `;
} }
private async _fetchData(): Promise<void> {
if (!this.hass) {
return;
}
const checkedItems: ShoppingListItem[] = [];
const uncheckedItems: ShoppingListItem[] = [];
const items = await fetchItems(this.hass);
for (const key in items) {
if (items[key].complete) {
checkedItems.push(items[key]);
} else {
uncheckedItems.push(items[key]);
}
}
this._checkedItems = checkedItems;
this._uncheckedItems = uncheckedItems;
}
private _completeItem(ev): void {
updateItem(this.hass!, ev.target.itemId, {
complete: ev.target.checked,
}).catch(() => this._fetchData());
}
private _saveEdit(ev): void {
updateItem(this.hass!, ev.target.itemId, {
name: ev.target.value,
}).catch(() => this._fetchData());
ev.target.blur();
}
private _clearItems(): void {
if (this.hass) {
clearItems(this.hass).catch(() => this._fetchData());
}
}
private get _newItem(): PaperInputElement {
return this.shadowRoot!.querySelector(".addBox") as PaperInputElement;
}
private _addItem(ev): void {
const newItem = this._newItem;
if (newItem.value!.length > 0) {
addItem(this.hass!, newItem.value!).catch(() => this._fetchData());
}
newItem.value = "";
if (ev) {
newItem.focus();
}
}
private _addKeyPress(ev): void {
if (ev.keyCode === 13) {
this._addItem(null);
}
}
static get styles(): CSSResult { static get styles(): CSSResult {
return css` return css`
ha-card { ha-card {
@ -257,66 +307,6 @@ class HuiShoppingListCard extends LitElement implements LovelaceCard {
} }
`; `;
} }
private async _fetchData(): Promise<void> {
if (this.hass) {
const checkedItems: ShoppingListItem[] = [];
const uncheckedItems: ShoppingListItem[] = [];
const items = await fetchItems(this.hass);
for (const key in items) {
if (items[key].complete) {
checkedItems.push(items[key]);
} else {
uncheckedItems.push(items[key]);
}
}
this._checkedItems = checkedItems;
this._uncheckedItems = uncheckedItems;
}
}
private _completeItem(ev): void {
updateItem(this.hass!, ev.target.itemId, {
complete: ev.target.checked,
}).catch(() => this._fetchData());
}
private _saveEdit(ev): void {
updateItem(this.hass!, ev.target.itemId, {
name: ev.target.value,
}).catch(() => this._fetchData());
ev.target.blur();
}
private _clearItems(): void {
if (this.hass) {
clearItems(this.hass).catch(() => this._fetchData());
}
}
private get _newItem(): PaperInputElement {
return this.shadowRoot!.querySelector(".addBox") as PaperInputElement;
}
private _addItem(ev): void {
const newItem = this._newItem;
if (newItem.value!.length > 0) {
addItem(this.hass!, newItem.value!).catch(() => this._fetchData());
}
newItem.value = "";
if (ev) {
newItem.focus();
}
}
private _addKeyPress(ev): void {
if (ev.keyCode === 13) {
this._addItem(null);
}
}
} }
declare global { declare global {