Add consistent initialization logic to improve Chromecast support.
This commit is contained in:
+17
@@ -57,6 +57,7 @@ import {
|
||||
homeAssistantWSRequest,
|
||||
isValidMediaShowInfo,
|
||||
shouldUpdateBasedOnHass,
|
||||
sideLoadHomeAssistantElements,
|
||||
} from './common.js';
|
||||
import { localize } from './localize/localize.js';
|
||||
import { renderMessage, renderProgressIndicator } from './components/message.js';
|
||||
@@ -186,6 +187,9 @@ export class FrigateCard extends LitElement {
|
||||
// per second for performance reasons.
|
||||
protected _boundMouseHandler = throttle(this._mouseHandler.bind(this), 1 * 1000);
|
||||
|
||||
// Whether the card has been successfully initialized.
|
||||
protected _initialized = false;
|
||||
|
||||
/**
|
||||
* Set the Home Assistant object.
|
||||
*/
|
||||
@@ -830,6 +834,19 @@ export class FrigateCard extends LitElement {
|
||||
this._changeView({ view: e.detail });
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before each update.
|
||||
*/
|
||||
protected willUpdate(): void {
|
||||
if (!this._initialized) {
|
||||
sideLoadHomeAssistantElements().then((success) => {
|
||||
if (success) {
|
||||
this._initialized = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the element should be updated.
|
||||
* @param changedProps The changed properties if any.
|
||||
|
||||
+50
-9
@@ -21,6 +21,7 @@ import {
|
||||
ActionsConfig,
|
||||
ActionType,
|
||||
CameraConfig,
|
||||
CardHelpers,
|
||||
ExtendedHomeAssistant,
|
||||
FrigateCardAction,
|
||||
FrigateCardCustomAction,
|
||||
@@ -33,7 +34,7 @@ import {
|
||||
signedPathSchema,
|
||||
StateParameters,
|
||||
} from './types.js';
|
||||
import { stateIcon } from './icons/state-icon.js'
|
||||
import { stateIcon } from './icons/state-icon.js';
|
||||
|
||||
const MEDIA_INFO_HEIGHT_CUTOFF = 50;
|
||||
const MEDIA_INFO_WIDTH_CUTOFF = MEDIA_INFO_HEIGHT_CUTOFF;
|
||||
@@ -290,10 +291,10 @@ export function convertActionToFrigateCardCustomAction(
|
||||
export function createFrigateCardCustomAction(
|
||||
action: FrigateCardAction,
|
||||
args?: {
|
||||
camera?: string,
|
||||
media_player?: string,
|
||||
media_player_action?: 'play' | 'stop',
|
||||
}
|
||||
camera?: string;
|
||||
media_player?: string;
|
||||
media_player_action?: 'play' | 'stop';
|
||||
},
|
||||
): FrigateCardCustomAction | null {
|
||||
if (action === 'camera_select') {
|
||||
if (!args?.camera) {
|
||||
@@ -473,10 +474,7 @@ export function getEntityTitle(
|
||||
* @param hass The Home Assistant object.
|
||||
* @returns The icon or undefined.
|
||||
*/
|
||||
export function getEntityIcon(
|
||||
hass?: HomeAssistant,
|
||||
entity?: string,
|
||||
): string {
|
||||
export function getEntityIcon(hass?: HomeAssistant, entity?: string): string {
|
||||
return stateIcon(entity ? hass?.states[entity] : null);
|
||||
}
|
||||
|
||||
@@ -682,3 +680,46 @@ export function getEventDurationString(event: FrigateEvent): string {
|
||||
duration += `${seconds}s`;
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Side loads the HA elements this card needs. This trickery is unfortunate
|
||||
* necessary, see:
|
||||
* - https://github.com/thomasloven/hass-config/wiki/PreLoading-Lovelace-Elements
|
||||
* @returns `true` if the load is successful, `false` otherwise.
|
||||
*/
|
||||
export const sideLoadHomeAssistantElements = async (): Promise<boolean> => {
|
||||
const neededElements = [
|
||||
'ha-selector',
|
||||
'ha-menu-button',
|
||||
'ha-camera-stream',
|
||||
'ha-hls-player',
|
||||
'ha-web-rtc-player',
|
||||
'ha-icon',
|
||||
'ha-circular-progress',
|
||||
'ha-icon-button',
|
||||
'ha-card',
|
||||
'ha-svg-icon',
|
||||
'ha-button-menu',
|
||||
];
|
||||
|
||||
if (neededElements.every((element) => customElements.get(element))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const helpers: CardHelpers = await (window as any).loadCardHelpers();
|
||||
|
||||
// The picture-glance editor loads everything this card needs. In particular:
|
||||
//
|
||||
// See: https://github.com/thomasloven/hass-config/wiki/PreLoading-Lovelace-Elements
|
||||
const pictureGlance = await helpers.createCardElement({
|
||||
type: 'picture-glance',
|
||||
entities: [],
|
||||
camera_image: 'dummy-to-load-editor-components',
|
||||
});
|
||||
if (pictureGlance.constructor.getConfigElement) {
|
||||
await pictureGlance.constructor.getConfigElement();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
+16
-39
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
|
||||
@@ -90,7 +89,12 @@ import {
|
||||
CONF_VIEW_UPDATE_FORCE,
|
||||
CONF_VIEW_UPDATE_SECONDS,
|
||||
} from './const.js';
|
||||
import { arrayMove, getCameraID, getCameraTitle } from './common.js';
|
||||
import {
|
||||
arrayMove,
|
||||
getCameraID,
|
||||
getCameraTitle,
|
||||
sideLoadHomeAssistantElements,
|
||||
} from './common.js';
|
||||
import {
|
||||
copyConfig,
|
||||
deleteConfigValue,
|
||||
@@ -183,7 +187,6 @@ const options: EditorOptions = {
|
||||
export class FrigateCardEditor extends LitElement implements LovelaceCardEditor {
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
@state() protected _config?: RawFrigateCardConfig;
|
||||
@state() protected _helpers?: any;
|
||||
protected _initialized = false;
|
||||
protected _configUpgradeable = false;
|
||||
|
||||
@@ -386,15 +389,19 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
// such, RawFrigateCardConfig is used as the type.
|
||||
this._config = config;
|
||||
this._configUpgradeable = isConfigUpgradeable(config);
|
||||
this.loadCardHelpers();
|
||||
}
|
||||
|
||||
protected shouldUpdate(): boolean {
|
||||
/**
|
||||
* Called before each update.
|
||||
*/
|
||||
protected willUpdate(): void {
|
||||
if (!this._initialized) {
|
||||
this._initialize();
|
||||
sideLoadHomeAssistantElements().then((success) => {
|
||||
if (success) {
|
||||
this._initialized = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected _getEntities(domain: string): string[] {
|
||||
@@ -929,7 +936,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
if (!this.hass || !this._helpers || !this._config) {
|
||||
if (!this.hass || !this._config) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
@@ -1219,36 +1226,6 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify editor is initialized.
|
||||
*/
|
||||
protected _initialize(): void {
|
||||
if (this.hass === undefined) return;
|
||||
if (this._config === undefined) return;
|
||||
if (this._helpers === undefined) return;
|
||||
|
||||
(async (): Promise<void> => {
|
||||
// The picture-glance editor loads the ha-selectors.
|
||||
// See: https://github.com/thomasloven/hass-config/wiki/PreLoading-Lovelace-Elements
|
||||
const pictureGlance = await this._helpers.createCardElement({
|
||||
type: 'picture-glance',
|
||||
entities: [],
|
||||
camera_image: 'dummy-to-load-editor-components',
|
||||
});
|
||||
if (pictureGlance.constructor.getConfigElement) {
|
||||
await pictureGlance.constructor.getConfigElement();
|
||||
this._initialized = true;
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load card helpers.
|
||||
*/
|
||||
protected async loadCardHelpers(): Promise<void> {
|
||||
this._helpers = await (window as any).loadCardHelpers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the editor menu with the given domain.
|
||||
* @param targetDomain The menu domain to close.
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
CustomActionConfig,
|
||||
HomeAssistant,
|
||||
LovelaceCard,
|
||||
LovelaceCardConfig,
|
||||
LovelaceCardEditor,
|
||||
MoreInfoActionConfig,
|
||||
NavigateActionConfig,
|
||||
@@ -1152,6 +1153,14 @@ export interface FrigateCardMediaPlayer {
|
||||
unmute(): void;
|
||||
}
|
||||
|
||||
export interface CardHelpers {
|
||||
createCardElement(config: LovelaceCardConfig): Promise<{
|
||||
constructor: {
|
||||
getConfigElement(): HTMLElement
|
||||
};
|
||||
}>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Home Assistant API types.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user