Refactor camera initialization into the camera engines.

This commit is contained in:
Dermot Duffy
2023-02-12 16:10:22 -08:00
parent 587f483f40
commit 06b4cc914c
30 changed files with 1249 additions and 842 deletions
+9 -15
View File
@@ -10,7 +10,6 @@ import {
import { customElement, property, state } from 'lit/decorators.js';
import galleryStyle from '../scss/gallery.scss';
import {
CameraConfig,
CardWideConfig,
ExtendedHomeAssistant,
frigateCardConfigDefaults,
@@ -24,7 +23,7 @@ import {
} from '../utils/media-to-view.js';
import { CameraManager, ExtendedMediaQueryResult } from '../camera-manager/manager.js';
import { View } from '../view/view.js';
import { renderProgressIndicator } from './message.js';
import { dispatchMessageEvent, renderProgressIndicator } from './message.js';
import './thumbnail.js';
import { THUMBNAIL_DETAILS_WIDTH_MIN } from './thumbnail.js';
import { createRef, Ref } from 'lit/directives/ref.js';
@@ -36,6 +35,7 @@ import { errorToConsole } from '../utils/basic';
import './media-filter';
import "./surround-basic";
import { ViewMedia } from '../view/media';
import { localize } from '../localize/localize';
const GALLERY_MEDIA_CHUNK_SIZE = 100;
@@ -55,9 +55,6 @@ export class FrigateCardGallery extends LitElement {
@property({ attribute: false })
public galleryConfig?: GalleryConfig;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public cameraManager?: CameraManager;
@@ -72,7 +69,6 @@ export class FrigateCardGallery extends LitElement {
if (
!this.hass ||
!this.view ||
!this.cameras ||
!this.view.isGalleryView() ||
!this.cameraManager
) {
@@ -85,7 +81,6 @@ export class FrigateCardGallery extends LitElement {
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
);
} else {
@@ -98,7 +93,6 @@ export class FrigateCardGallery extends LitElement {
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
...(mediaType && { mediaType: mediaType }),
@@ -120,7 +114,6 @@ export class FrigateCardGallery extends LitElement {
${this.galleryConfig && this.galleryConfig.controls.filter.mode !== 'none'
? html` <frigate-card-media-filter
.hass=${this.hass}
.cameras=${this.cameras}
.cameraManager=${this.cameraManager}
.view=${this.view}
.mediaLimit=${GALLERY_MEDIA_CHUNK_SIZE}
@@ -132,7 +125,6 @@ export class FrigateCardGallery extends LitElement {
.hass=${this.hass}
.view=${this.view}
.galleryConfig=${this.galleryConfig}
.cameras=${this.cameras}
.cameraManager=${this.cameraManager}
.cardWideConfig=${this.cardWideConfig}
>
@@ -166,9 +158,6 @@ export class FrigateCardGalleryCore extends LitElement {
@property({ attribute: false })
public galleryConfig?: GalleryConfig;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public cameraManager?: CameraManager;
@@ -330,12 +319,17 @@ export class FrigateCardGalleryCore extends LitElement {
!this._media ||
!this.hass ||
!this.view ||
!this.view.isGalleryView() ||
!this.cameras
!this.view.isGalleryView()
) {
return html``;
}
if ((this.view?.queryResults?.getResultsCount() ?? 0) === 0) {
return dispatchMessageEvent(this, localize('common.no_media'), 'info', {
icon: 'mdi:multimedia',
});
}
return html`
${this._media.map(
(media, index) =>
+20 -23
View File
@@ -104,9 +104,6 @@ export class FrigateCardLive extends LitElement {
@property({ attribute: false })
public view?: Readonly<View>;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public liveConfig?: LiveConfig;
@@ -200,7 +197,7 @@ export class FrigateCardLive extends LitElement {
* @returns A rendered template.
*/
protected render(): TemplateResult | void {
if (!this.hass || !this.liveConfig || !this.cameras || !this.view) {
if (!this.hass || !this.liveConfig || !this.cameraManager || !this.view) {
return;
}
@@ -229,7 +226,6 @@ export class FrigateCardLive extends LitElement {
.fetchMedia=${config.controls.thumbnails.media}
.thumbnailConfig=${config.controls.thumbnails}
.timelineConfig=${config.controls.timeline}
.cameras=${this.cameras}
.cameraManager=${this.cameraManager}
.inBackground=${this._inBackground}
@frigate-card:message=${(ev: CustomEvent<Message>) => {
@@ -254,7 +250,6 @@ export class FrigateCardLive extends LitElement {
<frigate-card-live-carousel
.hass=${this.hass}
.view=${this.view}
.cameras=${this.cameras}
.liveConfig=${this.liveConfig}
.inBackground=${this._inBackground}
.conditionState=${this.conditionState}
@@ -286,9 +281,6 @@ export class FrigateCardLiveCarousel extends LitElement {
@property({ attribute: false })
public view?: Readonly<View>;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public liveConfig?: LiveConfig;
@@ -345,10 +337,11 @@ export class FrigateCardLiveCarousel extends LitElement {
}
protected _getSelectedCameraIndex(): number {
if (!this.cameras || !this.view) {
const cameraIDs = this.cameraManager?.getCameraIDs();
if (!cameraIDs || !this.view) {
return 0;
}
return Math.max(0, Array.from(this.cameras.keys()).indexOf(this.view.camera));
return Math.max(0, Array.from(cameraIDs).indexOf(this.view.camera));
}
/**
@@ -367,9 +360,10 @@ export class FrigateCardLiveCarousel extends LitElement {
* @returns A list of EmblaOptionsTypes.
*/
protected _getPlugins(): EmblaCarouselPlugins {
const cameras = this.cameraManager?.getCameraIDs();
return [
// Only enable wheel plugin if there is more than one camera.
...(this.cameras && this.cameras.size > 1
...(cameras && cameras.size > 1
? [
WheelGesturesPlugin({
// Whether the carousel is vertical or horizontal, interpret y-axis wheel
@@ -424,14 +418,15 @@ export class FrigateCardLiveCarousel extends LitElement {
* name to slide number.
*/
protected _getSlides(): [TemplateResult[], Record<string, number>] {
if (!this.cameras) {
const cameras = this.cameraManager?.getCameras();
if (!cameras) {
return [[], {}];
}
const slides: TemplateResult[] = [];
const cameraToSlide: Record<string, number> = {};
for (const [camera, cameraConfig] of this.cameras) {
for (const [camera, cameraConfig] of cameras) {
const slide = this._renderLive(camera, cameraConfig, slides.length);
if (slide) {
cameraToSlide[camera] = slides.length;
@@ -445,8 +440,9 @@ export class FrigateCardLiveCarousel extends LitElement {
* Handle the user selecting a new slide in the carousel.
*/
protected _setViewHandler(ev: CustomEvent<CarouselSelect>): void {
if (this.cameras && ev.detail.index !== this._getSelectedCameraIndex()) {
this._setViewCameraID(Array.from(this.cameras.keys())[ev.detail.index]);
const cameras = this.cameraManager?.getCameras();
if (cameras && ev.detail.index !== this._getSelectedCameraIndex()) {
this._setViewCameraID(Array.from(cameras.keys())[ev.detail.index]);
}
}
@@ -534,19 +530,20 @@ export class FrigateCardLiveCarousel extends LitElement {
}
protected _getCameraIDsOfNeighbors(): [string | null, string | null] {
if (!this.cameras || !this.view || !this.hass) {
const cameras = this.cameraManager?.getCameras();
if (!cameras || !this.view || !this.hass) {
return [null, null];
}
const keys = Array.from(this.cameras.keys());
const keys = Array.from(cameras.keys());
const currentIndex = keys.indexOf(this.view.camera);
if (currentIndex < 0 || this.cameras.size <= 1) {
if (currentIndex < 0 || cameras.size <= 1) {
return [null, null];
}
return [
keys[currentIndex > 0 ? currentIndex - 1 : this.cameras.size - 1],
keys[currentIndex + 1 < this.cameras.size ? currentIndex + 1 : 0],
keys[currentIndex > 0 ? currentIndex - 1 : cameras.size - 1],
keys[currentIndex + 1 < cameras.size ? currentIndex + 1 : 0],
];
}
@@ -602,11 +599,11 @@ export class FrigateCardLiveCarousel extends LitElement {
<frigate-card-media-carousel
${ref(this._refMediaCarousel)}
.carouselOptions=${guard(
[this.cameras, this.liveConfig],
[this.cameraManager, this.liveConfig],
this._getOptions.bind(this),
)}
.carouselPlugins=${guard(
[this.cameras, this.liveConfig],
[this.cameraManager, this.liveConfig],
this._getPlugins.bind(this),
) as EmblaCarouselPlugins}
.label="${cameraMetadataCurrent ? `${localize('common.live')}: ${cameraMetadataCurrent.title}` : ''}"
+28 -41
View File
@@ -13,7 +13,6 @@ import { createRef, ref, Ref } from 'lit/directives/ref.js';
import { DateRange } from '../camera-manager/range';
import { localize } from '../localize/localize';
import mediaFilterStyle from '../scss/media-filter.scss';
import { CameraConfig } from '../types';
import { createViewForEvents, createViewForRecordings } from '../utils/media-to-view.js';
import { errorToConsole, formatDate, prettifyTitle } from '../utils/basic';
import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin';
@@ -77,9 +76,6 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
@property({ attribute: false })
public hass?: HomeAssistant;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public cameraManager?: CameraManager;
@@ -173,7 +169,8 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_ev: CustomEvent<{ value: unknown }>,
): Promise<void> {
if (!this.hass || !this.cameras || !this.cameraManager || !this.view) {
const cameras = this.cameraManager?.getCameras();
if (!this.hass || !cameras || !this.cameraManager || !this.view) {
return;
}
@@ -187,7 +184,7 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
};
const cameraIDs =
getArrayValueAsSet(this._refCamera.value?.value) ?? new Set(this.cameras.keys());
getArrayValueAsSet(this._refCamera.value?.value) ?? new Set(cameras.keys());
const mediaType = this._refMediaType.value?.value as
| MediaFilterMediaType
| undefined;
@@ -229,20 +226,13 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
];
(
await createViewForEvents(
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
query: new EventMediaQueries(queries),
await createViewForEvents(this, this.hass, this.cameraManager, this.view, {
query: new EventMediaQueries(queries),
// See 'A note on views' above for these two arguments.
...(cameraIDs.size === 1 && { targetCameraID: [...cameraIDs][0] }),
targetView: mediaType === MediaFilterMediaType.Clips ? 'clips' : 'snapshots',
},
)
// See 'A note on views' above for these two arguments.
...(cameraIDs.size === 1 && { targetCameraID: [...cameraIDs][0] }),
targetView: mediaType === MediaFilterMediaType.Clips ? 'clips' : 'snapshots',
})
)?.dispatchChangeEvent(this);
} else if (mediaType === MediaFilterMediaType.Recordings) {
const query: RecordingQuery = {
@@ -252,32 +242,28 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
};
(
await createViewForRecordings(
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
query: new RecordingMediaQueries([query]),
await createViewForRecordings(this, this.hass, this.cameraManager, this.view, {
query: new RecordingMediaQueries([query]),
// See 'A note on views' above for these two arguments.
...(cameraIDs.size === 1 && { targetCameraID: [...cameraIDs][0] }),
targetView: 'recordings',
},
)
// See 'A note on views' above for these two arguments.
...(cameraIDs.size === 1 && { targetCameraID: [...cameraIDs][0] }),
targetView: 'recordings',
})
)?.dispatchChangeEvent(this);
}
}
protected willUpdate(changedProps: PropertyValues): void {
if (changedProps.has('cameras') && this.cameras) {
this._cameraOptions = Array.from(this.cameras.keys()).map((cameraID) => ({
value: cameraID,
label: this.hass
? this.cameraManager?.getCameraMetadata(this.hass, cameraID)?.title ?? ''
: '',
}));
if (changedProps.has('cameraManager')) {
const cameras = this.cameraManager?.getCameras();
if (cameras) {
this._cameraOptions = Array.from(cameras.keys()).map((cameraID) => ({
value: cameraID,
label: this.hass
? this.cameraManager?.getCameraMetadata(this.hass, cameraID)?.title ?? ''
: '',
}));
}
}
if (changedProps.has('cameraManager') && this.hass && this.cameraManager) {
@@ -321,7 +307,8 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
protected _getDefaultsFromView(): MediaFilterCoreDefaults | null {
const queries = this.view?.query?.getQueries();
if (!this.view || !queries) {
const cameras = this.cameraManager?.getCameras();
if (!this.view || !queries || !cameras) {
return null;
}
@@ -337,7 +324,7 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
);
// Special note: If all cameras are selected, this is the same as no
// selector at all.
if (cameraIDSets.length === 1 && queries[0].cameraIDs.size !== this.cameras?.size) {
if (cameraIDSets.length === 1 && queries[0].cameraIDs.size !== cameras.size) {
cameraIDs = [...queries[0].cameraIDs];
}
+4 -10
View File
@@ -9,7 +9,6 @@ import {
import { customElement, property } from 'lit/decorators.js';
import surroundStyle from '../scss/surround.scss';
import {
CameraConfig,
ClipsOrSnapshotsOrAll,
ExtendedHomeAssistant,
MiniTimelineControlConfig,
@@ -55,9 +54,6 @@ export class FrigateCardSurround extends LitElement {
@property({ attribute: false, hasChanged: contentsChanged })
public fetchMedia?: ClipsOrSnapshotsOrAll;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public cameraManager?: CameraManager;
@@ -71,7 +67,6 @@ export class FrigateCardSurround extends LitElement {
*/
protected async _fetchMedia(): Promise<void> {
if (
!this.cameras ||
!this.cameraManager ||
!this.fetchMedia ||
this.inBackground ||
@@ -88,7 +83,6 @@ export class FrigateCardSurround extends LitElement {
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
targetView: this.view.view,
@@ -138,11 +132,12 @@ export class FrigateCardSurround extends LitElement {
}
protected _getCameraIDsForTimeline(): Set<string> | null {
if (!this.view || !this.cameras) {
const cameras = this.cameraManager?.getCameras();
if (!this.view || !cameras) {
return null;
}
if (this.view?.is('live')) {
return getAllDependentCameras(this.cameras, this.view.camera);
return getAllDependentCameras(cameras, this.view.camera);
}
if (this.view.isViewerView()) {
return new Set(
@@ -160,7 +155,7 @@ export class FrigateCardSurround extends LitElement {
* @returns A rendered template.
*/
protected render(): TemplateResult | void {
if (!this.hass || !this.view || !this.thumbnailConfig || !this.cameras) {
if (!this.hass || !this.view || !this.thumbnailConfig) {
return;
}
@@ -220,7 +215,6 @@ export class FrigateCardSurround extends LitElement {
slot=${this.timelineConfig.mode}
.hass=${this.hass}
.view=${this.view}
.cameras=${this.cameras}
.cameraIDs=${this._cameraIDsForTimeline}
.mini=${true}
.timelineConfig=${this.timelineConfig}
-1
View File
@@ -13,7 +13,6 @@ import { classMap } from 'lit/directives/class-map.js';
import { createRef, ref, Ref } from 'lit/directives/ref.js';
import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
import {
CameraConfig,
ExtendedHomeAssistant,
ThumbnailsControlConfig,
} from '../types.js';
+27 -39
View File
@@ -26,7 +26,6 @@ import {
TimelineOptionsCluster,
TimelineWindow,
} from 'vis-timeline/esnext';
import { CAMERA_BIRDSEYE } from '../const';
import { localize } from '../localize/localize';
import timelineCoreStyle from '../scss/timeline-core.scss';
import {
@@ -165,9 +164,6 @@ export class FrigateCardTimelineCore extends LitElement {
@property({ attribute: false })
public view?: Readonly<View>;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false, hasChanged: contentsChanged })
public timelineConfig?: TimelineCoreConfig;
@@ -240,11 +236,12 @@ export class FrigateCardTimelineCore extends LitElement {
protected _handleThumbnailDataRequest(request: ThumbnailDataRequestEvent): void {
const item = request.detail.item;
const media = this._timelineSource?.dataset.get(item)?.media;
const cameraConfig = media
? this.cameraManager?.getCameraConfig(media.getCameraID()) ?? undefined
: undefined;
request.detail.hass = this.hass;
request.detail.cameraConfig = media
? this.cameras?.get(media.getCameraID())
: undefined;
request.detail.cameraConfig = cameraConfig;
request.detail.cameraManager = this.cameraManager;
request.detail.media = media;
request.detail.view = this.view;
@@ -255,13 +252,13 @@ export class FrigateCardTimelineCore extends LitElement {
* @returns A rendered template.
*/
protected render(): TemplateResult | void {
if (!this.hass || !this.view || !this.timelineConfig) {
const cameraIDs = this._getTimelineCameraIDs();
if (!this.hass || !this.view || !this.timelineConfig || !cameraIDs) {
return;
}
const capabilities = this.cameraManager?.getAggregateCameraCapabilities(
this._getTimelineCameraIDs(),
);
const capabilities = this.cameraManager?.getAggregateCameraCapabilities(cameraIDs);
return html` ${capabilities?.supportsTimeline
? html` <div
@frigate-card:timeline:thumbnail-data-request=${this._handleThumbnailDataRequest.bind(
@@ -292,7 +289,7 @@ export class FrigateCardTimelineCore extends LitElement {
* Get all the keys of the cameras in scope for this timeline.
* @returns A set of camera ids (may be empty).
*/
protected _getTimelineCameraIDs(): Set<string> {
protected _getTimelineCameraIDs(): Set<string> | null {
return this.cameraIDs ?? this._getAllCameraIDs();
}
@@ -300,8 +297,8 @@ export class FrigateCardTimelineCore extends LitElement {
* Get all the keys of all cameras.
* @returns A set of camera ids (may be empty).
*/
protected _getAllCameraIDs(): Set<string> {
return new Set(this.cameras?.keys());
protected _getAllCameraIDs(): Set<string> | null {
return this.cameraManager?.getCameraIDs() ?? null;
}
/**
@@ -395,6 +392,7 @@ export class FrigateCardTimelineCore extends LitElement {
): Promise<void> {
const results = this.view?.queryResults;
const media = results?.getResults();
const cameraIDs = this._getTimelineCameraIDs();
if (
!media ||
!results ||
@@ -402,7 +400,7 @@ export class FrigateCardTimelineCore extends LitElement {
!this.view ||
!this.hass ||
!this.cameraManager ||
!this.cameraManager ||
!cameraIDs ||
// Skip range changes that do not have hammerjs pan directions associated
// with them, as these outliers cause media matching issues below.
!properties.event.additionalEvent
@@ -420,7 +418,7 @@ export class FrigateCardTimelineCore extends LitElement {
findClosestMediaIndex(
media,
targetTime,
this._getTimelineCameraIDs(),
cameraIDs,
properties.event.additionalEvent === 'panright' ? 'end' : 'start',
),
);
@@ -462,13 +460,14 @@ export class FrigateCardTimelineCore extends LitElement {
stopEventFromActivatingCardWideActions(properties.event);
}
const timelineCameraIDs = this._getTimelineCameraIDs();
if (
this._ignoreClick ||
!this.hass ||
!this._timeline ||
!this.cameras ||
!this.view ||
!this.cameraManager ||
!timelineCameraIDs ||
!properties.what
) {
return;
@@ -484,7 +483,6 @@ export class FrigateCardTimelineCore extends LitElement {
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
targetTime:
@@ -501,10 +499,9 @@ export class FrigateCardTimelineCore extends LitElement {
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
cameraIDs: this._getAllCameraIDs(),
cameraIDs: timelineCameraIDs,
start: startOfHour(properties.time),
end: endOfHour(properties.time),
targetTime: properties.time,
@@ -514,9 +511,7 @@ export class FrigateCardTimelineCore extends LitElement {
const newResults = this.view.queryResults
?.clone()
.resetSelectedResult()
.selectResultIfFound(
(media) => !!this.cameras && media.getID() === properties.item,
);
.selectResultIfFound((media) => media.getID() === properties.item);
if (!newResults || !newResults.hasSelectedResult()) {
// This can happen if this is a recording query (with recorded hours)
@@ -588,7 +583,7 @@ export class FrigateCardTimelineCore extends LitElement {
}
this._removeTargetBar();
if (!this.hass || !this.cameras) {
if (!this.hass) {
return;
}
@@ -646,14 +641,13 @@ export class FrigateCardTimelineCore extends LitElement {
selectedItem?: IdType;
},
): Promise<View | null> {
if (!this.hass || !this.cameraManager || !this.cameras || !this.view || !query) {
if (!this.hass || !this.cameraManager || !this.view || !query) {
return null;
}
const view = await createViewForEvents(
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
query: query,
@@ -666,7 +660,7 @@ export class FrigateCardTimelineCore extends LitElement {
}
if (options?.selectedItem) {
view.queryResults?.selectResultIfFound(
(media) => !!this.cameras && media.getID() === options.selectedItem,
(media) => media.getID() === options.selectedItem,
);
} else {
// If not asked to select a new item, persist the currently selected item
@@ -687,10 +681,8 @@ export class FrigateCardTimelineCore extends LitElement {
*/
protected _getGroups(): DataGroupCollectionType {
const groups: FrigateCardGroupData[] = [];
this._getTimelineCameraIDs().forEach((cameraID) => {
const cameraConfig = this.cameras?.get(cameraID);
if (!this.hass || !cameraConfig || !this.cameraManager) {
(this._getTimelineCameraIDs() ?? []).forEach((cameraID) => {
if (!this.hass || !this.cameraManager) {
return;
}
const cameraMetadata = this.cameraManager.getCameraMetadata(this.hass, cameraID);
@@ -806,10 +798,6 @@ export class FrigateCardTimelineCore extends LitElement {
maxItems: this.timelineConfig.clustering_threshold,
clusterCriteria: (first: TimelineItem, second: TimelineItem): boolean => {
if (!this.cameras) {
return false;
}
const media = this.view?.queryResults?.getSelectedResult();
const selectedId = media?.getID();
const firstMedia = (<FrigateCardTimelineItem>first).media;
@@ -866,7 +854,7 @@ export class FrigateCardTimelineCore extends LitElement {
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
protected shouldUpdate(_changedProps: PropertyValues): boolean {
return !!this.hass && !!this.cameras && this.cameras.size > 0;
return !!this.hass && !!this.cameraManager;
}
/**
@@ -875,7 +863,6 @@ export class FrigateCardTimelineCore extends LitElement {
protected async _updateTimelineFromView(): Promise<void> {
if (
!this.hass ||
!this.cameras ||
!this.view ||
!this.timelineConfig ||
!this._timelineSource ||
@@ -1040,10 +1027,11 @@ export class FrigateCardTimelineCore extends LitElement {
changedProps.has('timelineConfig') ||
changedProps.has('cameraIDs')
) {
if (this.cameraManager && this.cameras && this.timelineConfig) {
const cameraIDs = this._getTimelineCameraIDs();
if (cameraIDs && this.cameraManager && this.timelineConfig) {
this._timelineSource = new TimelineDataSource(
this.cameraManager,
this._getTimelineCameraIDs(),
cameraIDs,
this.timelineConfig.media,
);
} else {
+1 -6
View File
@@ -1,7 +1,7 @@
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import timelineStyle from '../scss/timeline.scss';
import { CameraConfig, ExtendedHomeAssistant, TimelineConfig } from '../types';
import { ExtendedHomeAssistant, TimelineConfig } from '../types';
import { CameraManager } from '../camera-manager/manager';
import { View } from '../view/view';
import './surround.js';
@@ -20,9 +20,6 @@ export class FrigateCardTimeline extends LitElement {
@property({ attribute: false })
public view?: Readonly<View>;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public timelineConfig?: TimelineConfig;
@@ -43,12 +40,10 @@ export class FrigateCardTimeline extends LitElement {
.view=${this.view}
.thumbnailConfig=${this.timelineConfig.controls.thumbnails}
.cameraManager=${this.cameraManager}
.cameras=${this.cameras}
>
<frigate-card-timeline-core
.hass=${this.hass}
.view=${this.view}
.cameras=${this.cameras}
.timelineConfig=${this.timelineConfig}
.thumbnailDetails=${this.timelineConfig.controls.thumbnails.show_details}
.thumbnailSize=${this.timelineConfig.controls.thumbnails.size}
+7 -21
View File
@@ -16,7 +16,6 @@ import { dispatchMessageEvent, renderProgressIndicator } from '../components/mes
import viewerStyle from '../scss/viewer.scss';
import viewerCarouselStyle from '../scss/viewer-carousel.scss';
import {
CameraConfig,
CardWideConfig,
ExtendedHomeAssistant,
frigateCardConfigDefaults,
@@ -78,9 +77,6 @@ export class FrigateCardViewer extends LitElement {
@property({ attribute: false })
public viewerConfig?: ViewerConfig;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public resolvedMediaCache?: ResolvedMediaCache;
@@ -98,7 +94,6 @@ export class FrigateCardViewer extends LitElement {
if (
!this.hass ||
!this.view ||
!this.cameras ||
!this.viewerConfig ||
!this.cameraManager
) {
@@ -120,7 +115,6 @@ export class FrigateCardViewer extends LitElement {
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
targetView: 'recording',
@@ -131,7 +125,6 @@ export class FrigateCardViewer extends LitElement {
this,
this.hass,
this.cameraManager,
this.cameras,
this.view,
{
targetView: 'media',
@@ -148,12 +141,10 @@ export class FrigateCardViewer extends LitElement {
.thumbnailConfig=${this.viewerConfig.controls.thumbnails}
.timelineConfig=${this.viewerConfig.controls.timeline}
.cameraManager=${this.cameraManager}
.cameras=${this.cameras}
>
<frigate-card-viewer-carousel
.hass=${this.hass}
.view=${this.view}
.cameras=${this.cameras}
.viewerConfig=${this.viewerConfig}
.resolvedMediaCache=${this.resolvedMediaCache}
.cameraManager=${this.cameraManager}
@@ -195,9 +186,6 @@ export class FrigateCardViewerCarousel extends LitElement {
@property({ attribute: false })
public cardWideConfig?: CardWideConfig;
@property({ attribute: false })
public cameras?: Map<string, CameraConfig>;
@property({ attribute: false })
public cameraManager?: CameraManager;
@@ -205,19 +193,17 @@ export class FrigateCardViewerCarousel extends LitElement {
// A task to resolve target media if lazy loading is disabled.
protected _mediaResolutionTask = new Task<
[ViewerConfig | undefined, Map<string, CameraConfig> | undefined, View | undefined],
[ViewerConfig | undefined, View | undefined],
void
>(
this,
async ([viewerConfig, cameras, view]: [
async ([viewerConfig, view]: [
ViewerConfig | undefined,
Map<string, CameraConfig> | undefined,
View | undefined,
]): Promise<void> => {
if (
!this.hass ||
!viewerConfig?.lazy_load ||
!cameras ||
!view ||
!view.queryResults?.hasResults()
) {
@@ -234,7 +220,7 @@ export class FrigateCardViewerCarousel extends LitElement {
});
await Promise.all(promises);
},
() => [this.viewerConfig, this.cameras, this.view],
() => [this.viewerConfig, this.view],
);
/**
@@ -453,7 +439,7 @@ export class FrigateCardViewerCarousel extends LitElement {
* @param slide The slide to lazy load.
*/
protected _lazyloadSlide(index: number, slide: HTMLElement): void {
if (!this.hass || !this.view || !this.view.query || !this.cameras) {
if (!this.hass || !this.view || !this.view.query) {
return;
}
@@ -512,7 +498,7 @@ export class FrigateCardViewerCarousel extends LitElement {
* Determine if all the media in the carousel are resolved.
*/
protected _isMediaFullyResolved(): boolean {
if (!this.resolvedMediaCache || !this.cameras) {
if (!this.resolvedMediaCache) {
return false;
}
for (const media of this.view?.queryResults?.getResults() ?? []) {
@@ -560,7 +546,7 @@ export class FrigateCardViewerCarousel extends LitElement {
}
const media = this.view?.queryResults?.getSelectedResult();
if (!media || !this.cameras || !this.view || !this.view.queryResults) {
if (!media || !this.view || !this.view.queryResults) {
return;
}
@@ -649,7 +635,7 @@ export class FrigateCardViewerCarousel extends LitElement {
*/
protected _renderMediaItem(media: ViewMedia, index: number): TemplateResult | null {
// Skip folders as they cannot be rendered by this viewer.
if (!this.hass || !this.view || !this.viewerConfig || !this.cameras) {
if (!this.hass || !this.view || !this.viewerConfig) {
return null;
}