-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
subscribe-mixin.ts
79 lines (70 loc) · 2.16 KB
/
subscribe-mixin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { PropertyValues, ReactiveElement } from "lit";
import { property } from "lit/decorators";
import type { Constructor, HomeAssistant } from "../types";
export interface HassSubscribeElement {
hassSubscribe(): UnsubscribeFunc[];
}
export const SubscribeMixin = <T extends Constructor<ReactiveElement>>(
superClass: T
) => {
class SubscribeClass extends superClass {
@property({ attribute: false }) public hass?: HomeAssistant;
// we wait with subscribing till these properties are set on the host element
protected hassSubscribeRequiredHostProps?: string[];
private __unsubs?: Array<UnsubscribeFunc | Promise<UnsubscribeFunc>>;
public connectedCallback() {
super.connectedCallback();
this.__checkSubscribed();
}
public disconnectedCallback() {
super.disconnectedCallback();
if (this.__unsubs) {
while (this.__unsubs.length) {
const unsub = this.__unsubs.pop()!;
if (unsub instanceof Promise) {
unsub.then((unsubFunc) => unsubFunc());
} else {
unsub();
}
}
this.__unsubs = undefined;
}
}
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
if (changedProps.has("hass")) {
this.__checkSubscribed();
return;
}
if (!this.hassSubscribeRequiredHostProps) {
return;
}
for (const key of changedProps.keys()) {
if (this.hassSubscribeRequiredHostProps.includes(key as string)) {
this.__checkSubscribed();
return;
}
}
}
protected hassSubscribe(): Array<
UnsubscribeFunc | Promise<UnsubscribeFunc>
> {
return [];
}
private __checkSubscribed(): void {
if (
this.__unsubs !== undefined ||
!(this as unknown as Element).isConnected ||
this.hass === undefined ||
this.hassSubscribeRequiredHostProps?.some(
(prop) => this[prop] === undefined
)
) {
return;
}
this.__unsubs = this.hassSubscribe();
}
}
return SubscribeClass;
};