Viewer fixes to avoid resetting carousel when not necessary.
This commit is contained in:
+8
-1
@@ -43,6 +43,7 @@ import { FrigateCardElements } from './components/elements.js';
|
|||||||
import { FRIGATE_BUTTON_MENU_ICON, FrigateCardMenu } from './components/menu.js';
|
import { FRIGATE_BUTTON_MENU_ICON, FrigateCardMenu } from './components/menu.js';
|
||||||
import { View } from './view.js';
|
import { View } from './view.js';
|
||||||
import {
|
import {
|
||||||
|
contentsChanged,
|
||||||
convertActionToFrigateCardCustomAction,
|
convertActionToFrigateCardCustomAction,
|
||||||
createFrigateCardCustomAction,
|
createFrigateCardCustomAction,
|
||||||
getActionConfigGivenAction,
|
getActionConfigGivenAction,
|
||||||
@@ -231,11 +232,17 @@ export class FrigateCard extends LitElement {
|
|||||||
camera: this._view?.camera,
|
camera: this._view?.camera,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._overriddenConfig = getOverriddenConfig(
|
const overriddenConfig = getOverriddenConfig(
|
||||||
this._baseConfig,
|
this._baseConfig,
|
||||||
this._baseConfig.overrides,
|
this._baseConfig.overrides,
|
||||||
this._conditionState,
|
this._conditionState,
|
||||||
) as FrigateCardConfig;
|
) as FrigateCardConfig;
|
||||||
|
|
||||||
|
// Save on Lit re-rendering costs by only updating the configuration if it
|
||||||
|
// actually changes.
|
||||||
|
if (contentsChanged(overriddenConfig, this._overriddenConfig)) {
|
||||||
|
this._overriddenConfig = overriddenConfig;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { HassEntity, MessageBase } from 'home-assistant-js-websocket';
|
|||||||
import { HomeAssistant, stateIcon } from 'custom-card-helpers';
|
import { HomeAssistant, stateIcon } from 'custom-card-helpers';
|
||||||
import { StyleInfo } from 'lit/directives/style-map';
|
import { StyleInfo } from 'lit/directives/style-map';
|
||||||
import { ZodSchema, z } from 'zod';
|
import { ZodSchema, z } from 'zod';
|
||||||
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
import { localize } from './localize/localize.js';
|
import { localize } from './localize/localize.js';
|
||||||
import {
|
import {
|
||||||
@@ -483,3 +484,15 @@ export function arrayMove(target: unknown[], from: number, to: number): void {
|
|||||||
target.splice(from, 1);
|
target.splice(from, 1);
|
||||||
target.splice(to, 0, element);
|
target.splice(to, 0, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the contents of the n(ew) and o(ld) values have changed. For use
|
||||||
|
* in lit web components that may have a value that changes address but not
|
||||||
|
* contents -- and for which a re-render is expensive/jarring.
|
||||||
|
* @param n The new value.
|
||||||
|
* @param o The old value.
|
||||||
|
* @returns `true` is the contents have changed.
|
||||||
|
*/
|
||||||
|
export function contentsChanged(n: unknown, o: unknown): boolean {
|
||||||
|
return !isEqual(n, o);
|
||||||
|
}
|
||||||
+7
-23
@@ -1,4 +1,3 @@
|
|||||||
// TODO use the schema default remover code to simplify config schema
|
|
||||||
// TODO in fullscreen mode on live view with mixed cameras, center video
|
// TODO in fullscreen mode on live view with mixed cameras, center video
|
||||||
// TODO verify README links worked correctly (e.g. basic cameras configuration)
|
// TODO verify README links worked correctly (e.g. basic cameras configuration)
|
||||||
|
|
||||||
@@ -26,7 +25,6 @@ import {
|
|||||||
import { EmblaOptionsType } from 'embla-carousel';
|
import { EmblaOptionsType } from 'embla-carousel';
|
||||||
import { HomeAssistant } from 'custom-card-helpers';
|
import { HomeAssistant } from 'custom-card-helpers';
|
||||||
import { customElement, property, state } from 'lit/decorators.js';
|
import { customElement, property, state } from 'lit/decorators.js';
|
||||||
import { isEqual } from 'lodash-es';
|
|
||||||
import { ref } from 'lit/directives/ref';
|
import { ref } from 'lit/directives/ref';
|
||||||
import { until } from 'lit/directives/until.js';
|
import { until } from 'lit/directives/until.js';
|
||||||
|
|
||||||
@@ -38,6 +36,7 @@ import { ThumbnailCarouselTap } from './thumbnail-carousel.js';
|
|||||||
import { View } from '../view.js';
|
import { View } from '../view.js';
|
||||||
import { localize } from '../localize/localize.js';
|
import { localize } from '../localize/localize.js';
|
||||||
import {
|
import {
|
||||||
|
contentsChanged,
|
||||||
dispatchErrorMessageEvent,
|
dispatchErrorMessageEvent,
|
||||||
dispatchExistingMediaShowInfoAsEvent,
|
dispatchExistingMediaShowInfoAsEvent,
|
||||||
dispatchMediaShowEvent,
|
dispatchMediaShowEvent,
|
||||||
@@ -518,7 +517,7 @@ export class FrigateCardLiveProvider extends LitElement {
|
|||||||
|
|
||||||
// Label that is used for ARIA support and as tooltip.
|
// Label that is used for ARIA support and as tooltip.
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public label = "";
|
public label = '';
|
||||||
|
|
||||||
protected _getResolvedProvider(): LiveProvider {
|
protected _getResolvedProvider(): LiveProvider {
|
||||||
if (this.cameraConfig?.live_provider === 'auto') {
|
if (this.cameraConfig?.live_provider === 'auto') {
|
||||||
@@ -531,7 +530,9 @@ export class FrigateCardLiveProvider extends LitElement {
|
|||||||
}
|
}
|
||||||
return frigateCardConfigDefaults.cameras.live_provider;
|
return frigateCardConfigDefaults.cameras.live_provider;
|
||||||
}
|
}
|
||||||
return this.cameraConfig?.live_provider || frigateCardConfigDefaults.cameras.live_provider;
|
return (
|
||||||
|
this.cameraConfig?.live_provider || frigateCardConfigDefaults.cameras.live_provider
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -618,18 +619,7 @@ export class FrigateCardLiveFrigate extends LitElement {
|
|||||||
// - https://github.com/AlexxIT/WebRTC
|
// - https://github.com/AlexxIT/WebRTC
|
||||||
@customElement('frigate-card-live-webrtc')
|
@customElement('frigate-card-live-webrtc')
|
||||||
export class FrigateCardLiveWebRTC extends LitElement {
|
export class FrigateCardLiveWebRTC extends LitElement {
|
||||||
@property({
|
@property({ attribute: false, hasChanged: contentsChanged })
|
||||||
attribute: false,
|
|
||||||
|
|
||||||
// Resetting the WebRTC/JSMPEG configuration is expensive as the connections
|
|
||||||
// need to be re-established. These configurations may be overridden which
|
|
||||||
// creates semantically equal configurations at different addresses --
|
|
||||||
// ensure LIT only considers the property as having changed if it's actually
|
|
||||||
// different.
|
|
||||||
hasChanged(n: WebRTCConfig, o: WebRTCConfig): boolean {
|
|
||||||
return !isEqual(n, o);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
protected webRTCConfig?: WebRTCConfig;
|
protected webRTCConfig?: WebRTCConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
@@ -734,13 +724,7 @@ export class FrigateCardLiveJSMPEG extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
protected cameraConfig?: CameraConfig;
|
protected cameraConfig?: CameraConfig;
|
||||||
|
|
||||||
@property({
|
@property({ attribute: false, hasChanged: contentsChanged })
|
||||||
attribute: false,
|
|
||||||
// See note under FrigateCardLiveWebRTC.
|
|
||||||
hasChanged(n: JSMPEGConfig, o: JSMPEGConfig): boolean {
|
|
||||||
return !isEqual(n, o);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
protected jsmpegConfig?: JSMPEGConfig;
|
protected jsmpegConfig?: JSMPEGConfig;
|
||||||
|
|
||||||
protected hass?: HomeAssistant & ExtendedHomeAssistant;
|
protected hass?: HomeAssistant & ExtendedHomeAssistant;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import {
|
|||||||
} from './thumbnail-carousel.js';
|
} from './thumbnail-carousel.js';
|
||||||
import { ResolvedMediaCache, ResolvedMediaUtil } from '../resolved-media.js';
|
import { ResolvedMediaCache, ResolvedMediaUtil } from '../resolved-media.js';
|
||||||
import { View } from '../view.js';
|
import { View } from '../view.js';
|
||||||
import { createMediaShowInfo, dispatchErrorMessageEvent } from '../common.js';
|
import { contentsChanged, createMediaShowInfo, dispatchErrorMessageEvent } from '../common.js';
|
||||||
import { renderProgressIndicator } from '../components/message.js';
|
import { renderProgressIndicator } from '../components/message.js';
|
||||||
|
|
||||||
import './next-prev-control.js';
|
import './next-prev-control.js';
|
||||||
@@ -111,7 +111,8 @@ export class FrigateCardViewerCore extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
protected view?: Readonly<View>;
|
protected view?: Readonly<View>;
|
||||||
|
|
||||||
@property({ attribute: false })
|
// See note on viewerConfig in <frigate-card-viewer-carousel>.
|
||||||
|
@property({ attribute: false, hasChanged: contentsChanged })
|
||||||
protected viewerConfig?: ViewerConfig;
|
protected viewerConfig?: ViewerConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
@@ -186,7 +187,12 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
protected view?: Readonly<View>;
|
protected view?: Readonly<View>;
|
||||||
|
|
||||||
@property({ attribute: false })
|
// Resetting the viewer configuration causes a full reset so ensure the config
|
||||||
|
// has actually changed with a full comparison (dynamic configuration
|
||||||
|
// overrides may causes changes elsewhere in the full card configuration that
|
||||||
|
// could lead to the address of the viewerConfig changing without it being
|
||||||
|
// semantically different).
|
||||||
|
@property({ attribute: false, hasChanged: contentsChanged })
|
||||||
protected viewerConfig?: ViewerConfig;
|
protected viewerConfig?: ViewerConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ img,video {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
// Center vertically in the viewport.
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.embla__viewport.is-draggable {
|
.embla__viewport.is-draggable {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
|
|||||||
Reference in New Issue
Block a user