Wait for WebRTC component to definitely be loaded.
This commit is contained in:
+28
-8
@@ -22,6 +22,7 @@ import {
|
|||||||
import { EmblaOptionsType, EmblaPluginType } from 'embla-carousel';
|
import { EmblaOptionsType, EmblaPluginType } from 'embla-carousel';
|
||||||
import { HomeAssistant } from 'custom-card-helpers';
|
import { HomeAssistant } from 'custom-card-helpers';
|
||||||
import { Ref, createRef, ref } from 'lit/directives/ref.js';
|
import { Ref, createRef, ref } from 'lit/directives/ref.js';
|
||||||
|
import { Task } from '@lit-labs/task';
|
||||||
import { customElement, property, state } from 'lit/decorators.js';
|
import { customElement, property, state } from 'lit/decorators.js';
|
||||||
import { until } from 'lit/directives/until.js';
|
import { until } from 'lit/directives/until.js';
|
||||||
|
|
||||||
@@ -681,6 +682,9 @@ export class FrigateCardLiveWebRTC extends LitElement {
|
|||||||
|
|
||||||
protected hass?: HomeAssistant & ExtendedHomeAssistant;
|
protected hass?: HomeAssistant & ExtendedHomeAssistant;
|
||||||
|
|
||||||
|
// A task to await the load of the WebRTC component.
|
||||||
|
protected _webrtcTask = new Task(this, this._getWebRTCElement, () => [1]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Play the video.
|
* Play the video.
|
||||||
*/
|
*/
|
||||||
@@ -709,14 +713,22 @@ export class FrigateCardLiveWebRTC extends LitElement {
|
|||||||
return this.renderRoot?.querySelector('#video') as HTMLVideoElement | null;
|
return this.renderRoot?.querySelector('#video') as HTMLVideoElement | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async _getWebRTCElement(): Promise<CustomElementConstructor | undefined> {
|
||||||
|
await customElements.whenDefined('webrtc-camera');
|
||||||
|
return customElements.get('webrtc-camera');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the WebRTC element. May throw.
|
* Create the WebRTC element. May throw.
|
||||||
*/
|
*/
|
||||||
protected _createWebRTC(): HTMLElement | undefined {
|
protected _createWebRTC(): HTMLElement | undefined {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const webrtcElement = customElements.get('webrtc-camera') as any;
|
const webrtcElement = this._webrtcTask.value;
|
||||||
if (webrtcElement) {
|
if (webrtcElement && this.hass) {
|
||||||
const webrtc = new webrtcElement();
|
const webrtc = new webrtcElement() as HTMLElement & {
|
||||||
|
hass: HomeAssistant;
|
||||||
|
setConfig: (config: Record<string, unknown>) => void;
|
||||||
|
};
|
||||||
const config = { ...this.webRTCConfig };
|
const config = { ...this.webRTCConfig };
|
||||||
|
|
||||||
// If the live WebRTC configuration does not specify a URL/entity to use,
|
// If the live WebRTC configuration does not specify a URL/entity to use,
|
||||||
@@ -731,9 +743,8 @@ export class FrigateCardLiveWebRTC extends LitElement {
|
|||||||
webrtc.setConfig(config);
|
webrtc.setConfig(config);
|
||||||
webrtc.hass = this.hass;
|
webrtc.hass = this.hass;
|
||||||
return webrtc;
|
return webrtc;
|
||||||
} else {
|
|
||||||
throw new FrigateCardError(localize('error.webrtc_missing'));
|
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -741,9 +752,7 @@ export class FrigateCardLiveWebRTC extends LitElement {
|
|||||||
* @returns A rendered template.
|
* @returns A rendered template.
|
||||||
*/
|
*/
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
if (!this.hass) {
|
const render = (): TemplateResult | void => {
|
||||||
return;
|
|
||||||
}
|
|
||||||
let webrtcElement: HTMLElement | undefined;
|
let webrtcElement: HTMLElement | undefined;
|
||||||
try {
|
try {
|
||||||
webrtcElement = this._createWebRTC();
|
webrtcElement = this._createWebRTC();
|
||||||
@@ -756,6 +765,17 @@ export class FrigateCardLiveWebRTC extends LitElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return html`${webrtcElement}`;
|
return html`${webrtcElement}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use a task to allow us to asynchronously wait for the WebRTC card to
|
||||||
|
// load, but yet still have the card load be followed by the updated()
|
||||||
|
// lifecycle callback (unlike just using `until`).
|
||||||
|
return html`${this._webrtcTask.render({
|
||||||
|
initial: () => renderProgressIndicator(localize('error.webrtc_waiting')),
|
||||||
|
pending: () => renderProgressIndicator(localize('error.webrtc_waiting')),
|
||||||
|
error: (e: unknown) => dispatchErrorMessageEvent(this, (e as Error).message),
|
||||||
|
complete: () => render(),
|
||||||
|
})}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ export class FrigateCardMessage extends LitElement {
|
|||||||
<span>
|
<span>
|
||||||
<ha-icon icon="${icon}"> </ha-icon>
|
<ha-icon icon="${icon}"> </ha-icon>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span> ${this.message ? html`${this.message}` : ''} </span>
|
||||||
${this.message ? html`${this.message}` : ''}
|
|
||||||
</span>
|
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,9 +48,15 @@ export class FrigateCardErrorMessage extends LitElement {
|
|||||||
|
|
||||||
@customElement('frigate-card-progress-indicator')
|
@customElement('frigate-card-progress-indicator')
|
||||||
export class FrigateCardProgressIndicator extends LitElement {
|
export class FrigateCardProgressIndicator extends LitElement {
|
||||||
|
@property({ attribute: false })
|
||||||
|
protected message = '';
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html` <div class="message">
|
return html` <div class="message vertical">
|
||||||
|
<span>
|
||||||
<ha-circular-progress active="true" size="large"> </ha-circular-progress>
|
<ha-circular-progress active="true" size="large"> </ha-circular-progress>
|
||||||
|
</span>
|
||||||
|
${this.message ? html`<span>${this.message}</span>` : html``}
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +79,9 @@ export function renderMessage(message: Message): TemplateResult {
|
|||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderProgressIndicator(): TemplateResult {
|
export function renderProgressIndicator(message?: string): TemplateResult {
|
||||||
return html` <frigate-card-progress-indicator> </frigate-card-progress-indicator> `;
|
return html`
|
||||||
|
<frigate-card-progress-indicator .message=${message || ''}>
|
||||||
|
</frigate-card-progress-indicator>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,8 +179,8 @@
|
|||||||
"invalid_configuration": "Invalid configuration",
|
"invalid_configuration": "Invalid configuration",
|
||||||
"invalid_configuration_no_hint": "No location hint available (bad or missing type?)",
|
"invalid_configuration_no_hint": "No location hint available (bad or missing type?)",
|
||||||
"upgrade_available": "An automated card configuration upgrade is available, please visit the visual card editor",
|
"upgrade_available": "An automated card configuration upgrade is available, please visit the visual card editor",
|
||||||
"webrtc_missing": "WebRTC component not found",
|
|
||||||
"webrtc_reported_error": "WebRTC component reported an error",
|
"webrtc_reported_error": "WebRTC component reported an error",
|
||||||
|
"webrtc_waiting": "Waiting for WebRTC Card to load ...",
|
||||||
"no_cameras": "No valid cameras found, you must configure at least one camera entry",
|
"no_cameras": "No valid cameras found, you must configure at least one camera entry",
|
||||||
"no_camera_id": "Could not determine camera id for the following camera, may need to set 'id' parameter manually",
|
"no_camera_id": "Could not determine camera id for the following camera, may need to set 'id' parameter manually",
|
||||||
"duplicate_camera_id": "Duplicate Frigate camera id for the following camera, use the 'id' parameter to uniquely identify cameras",
|
"duplicate_camera_id": "Duplicate Frigate camera id for the following camera, use the 'id' parameter to uniquely identify cameras",
|
||||||
|
|||||||
@@ -13,6 +13,10 @@
|
|||||||
padding: 10%;
|
padding: 10%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vertical {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.message a {
|
.message a {
|
||||||
color: var(--primary-text-color, white);
|
color: var(--primary-text-color, white);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user