From ee9f22f9f768456186ce8f5bf79811f34a6e62bf Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sat, 8 Jan 2022 16:44:20 -0800 Subject: [PATCH] Move overrides to a single configuration section. --- src/card-condition.ts | 41 ++++++++++++++++++++++-------------- src/card.ts | 23 +++++++++++++-------- src/components/live.ts | 15 +++++++++++++- src/types.ts | 47 +++++++++++++++++++++++++----------------- 4 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/card-condition.ts b/src/card-condition.ts index 7b62c284..fb21ae0d 100644 --- a/src/card-condition.ts +++ b/src/card-condition.ts @@ -1,5 +1,6 @@ import type { FrigateCardCondition, + OverrideConfigurationKey, RawFrigateCardConfig, } from './types'; import { merge, cloneDeep } from 'lodash-es'; @@ -27,7 +28,8 @@ export function evaluateCondition( result &&= !!state.view && condition.view.includes(state.view); } if (condition?.fullscreen !== undefined) { - result &&= state.fullscreen !== undefined && condition.fullscreen == state.fullscreen; + result &&= + state.fullscreen !== undefined && condition.fullscreen == state.fullscreen; } if (condition?.camera?.length) { result &&= !!state.camera && condition.camera.includes(state.camera); @@ -78,32 +80,41 @@ export function conditionStateRequestHandler( ev.conditionState = conditionState; } -type Overrides = { +type RawOverrides = { conditions: FrigateCardCondition; overrides: RawFrigateCardConfig; }[]; export function getOverriddenConfig( config: Readonly, + overrides: Readonly | undefined, conditionState?: Readonly, - overrides?: Readonly, ): RawFrigateCardConfig { - const overridesSource = - overrides || (config['overrides'] as Readonly | undefined); - if (!overridesSource) { - return config; - } - const output = cloneDeep(config); let overridden = false; - - for (const override of overridesSource) { - if (evaluateCondition(override.conditions, conditionState)) { - merge(output, override.overrides); - overridden = true; + if (overrides) { + for (const override of overrides) { + if (evaluateCondition(override.conditions, conditionState)) { + merge(output, override.overrides); + overridden = true; + } } } // Attempt to return the same configuration object if it has not been // overridden (to reduce re-renders for a configuration that has not changed). return overridden ? output : config; -} \ No newline at end of file +} + +export function getOverridesByKey( + overrides: Readonly | undefined, + key: OverrideConfigurationKey, +): RawOverrides { + return ( + overrides + ?.filter((o) => key in o.overrides) + .map((o) => ({ + conditions: o.conditions, + overrides: o.overrides[key] as RawFrigateCardConfig, + })) ?? [] + ); +} diff --git a/src/card.ts b/src/card.ts index 13c8b357..753d2789 100644 --- a/src/card.ts +++ b/src/card.ts @@ -26,7 +26,6 @@ import { ActionType, CameraConfig, GetFrigateCardMenuButtonParameters, - LiveConfig, RawFrigateCardConfig, entitySchema, frigateCardConfigSchema, @@ -79,6 +78,7 @@ import { ConditionState, conditionStateRequestHandler, getOverriddenConfig, + getOverridesByKey, } from './card-condition.js'; /** A note on media callbacks: @@ -135,6 +135,9 @@ export class FrigateCard extends LitElement { @state() public config!: FrigateCardConfig; + @state() + public _overriddenConfig?: FrigateCardConfig; + protected _interactionTimerID: number | null = null; @property({ attribute: false }) @@ -226,6 +229,11 @@ export class FrigateCard extends LitElement { fullscreen: screenfull.isEnabled && screenfull.isFullscreen, camera: this._view?.camera, }; + + this._overriddenConfig = getOverriddenConfig( + this.config, + this.config.overrides, + this._conditionState) as FrigateCardConfig; } /** @@ -1040,17 +1048,13 @@ export class FrigateCard extends LitElement { let specificActions: Actions | undefined = undefined; if (this._view?.is('live')) { - const config = getOverriddenConfig( - this.config.live, - this._conditionState, - ) as LiveConfig; - specificActions = config.actions; + specificActions = this._overriddenConfig?.live.actions; } else if (this._view?.isGalleryView()) { - specificActions = this.config.event_gallery?.actions; + specificActions = this._overriddenConfig?.event_gallery?.actions; } else if (this._view?.isViewerView()) { - specificActions = this.config.event_viewer.actions; + specificActions = this._overriddenConfig?.event_viewer.actions; } else if (this._view?.is('image')) { - specificActions = this.config.image?.actions; + specificActions = this._overriddenConfig?.image?.actions; } return { ...this.config.view.actions, ...specificActions }; } @@ -1208,6 +1212,7 @@ export class FrigateCard extends LitElement { .view=${this._view} .liveConfig=${this.config.live} .conditionState=${this._conditionState} + .liveOverrides=${getOverridesByKey(this.config.overrides, 'live')} .cameras=${this._cameras} .preload=${this.config.live.preload && !this._view.is('live')} class="${classMap(liveClasses)}" diff --git a/src/components/live.ts b/src/components/live.ts index 700234cb..6327a0a9 100644 --- a/src/components/live.ts +++ b/src/components/live.ts @@ -24,6 +24,7 @@ import { MediaShowInfo, WebRTCConfig, FrigateCardError, + LiveOverrides, } from '../types.js'; import { EmblaOptionsType } from 'embla-carousel'; import { HomeAssistant } from 'custom-card-helpers'; @@ -79,6 +80,9 @@ export class FrigateCardLive extends LitElement { @property({ attribute: false }) protected liveConfig?: LiveConfig; + @property({ attribute: false }) + protected liveOverrides?: LiveOverrides; + @property({ attribute: false }) protected conditionState?: ConditionState; @@ -177,6 +181,7 @@ export class FrigateCardLive extends LitElement { const config = getOverriddenConfig( this.liveConfig, + this.liveOverrides, this.conditionState, ) as LiveConfig; @@ -192,6 +197,7 @@ export class FrigateCardLive extends LitElement { .liveConfig=${this.liveConfig} .preload=${this._preload} .conditionState=${this.conditionState} + .liveOverrides=${this.liveOverrides} @frigate-card:media-show=${this._mediaShowHandler} @frigate-card:carousel:select=${() => { // Re-rendering the component will cause the thumbnails to be @@ -226,6 +232,9 @@ export class FrigateCardLiveCarousel extends FrigateCardMediaCarousel { @property({ attribute: false }) protected liveConfig?: LiveConfig; + @property({ attribute: false }) + protected liveOverrides?: LiveOverrides; + @property({ attribute: false }) protected preload?: boolean; @@ -366,7 +375,10 @@ export class FrigateCardLiveCarousel extends FrigateCardMediaCarousel { camera: camera, }); - const config = getOverriddenConfig(this.liveConfig, conditionState) as LiveConfig; + const config = getOverriddenConfig( + this.liveConfig, + this.liveOverrides, + conditionState) as LiveConfig; return html`
; const pictureElementsSchema = pictureElementSchema.array().optional(); export type PictureElements = z.infer; -/** - * Configuration overrides - */ - const overridesSchema = z - .object({ - conditions: frigateCardConditionSchema, - overrides: z.record(z.unknown()), - }) - .array() - .optional(); -export type Overrides = z.infer; - /** * View configuration section. */ @@ -562,13 +550,6 @@ const liveConfigSchema = liveOverridableConfigSchema preload: z.boolean().default(liveConfigDefault.preload), lazy_load: z.boolean().default(liveConfigDefault.lazy_load), draggable: z.boolean().default(liveConfigDefault.draggable), - overrides: z - .object({ - conditions: frigateCardConditionSchema, - overrides: liveOverridableConfigSchema, - }) - .array() - .optional(), }) .default(liveConfigDefault); export type LiveConfig = z.infer; @@ -702,6 +683,31 @@ const dimensionsConfigSchema = z }) .default(dimensionsConfigDefault); +/** + * Configuration overrides + */ +const overrideConfigurationSchema = z.object({ + live: liveOverridableConfigSchema.optional(), +}); +export type OverrideConfigurationKey = keyof z.infer; + +const overridesSchema = z + .object({ + conditions: frigateCardConditionSchema, + overrides: overrideConfigurationSchema, + }) + .array() + .optional(); + +const liveOverridesSchema = z + .object({ + conditions: frigateCardConditionSchema, + overrides: liveOverridableConfigSchema, + }) + .array() + .optional(); +export type LiveOverrides = z.infer; + /** * Main card config. */ @@ -717,6 +723,9 @@ export const frigateCardConfigSchema = z.object({ elements: pictureElementsSchema, dimensions: dimensionsConfigSchema, + // Configuration overrides. + overrides: overridesSchema, + // Stock lovelace card config. type: z.string(), test_gui: z.boolean().optional(),