Initial code for major engine refactor.
This commit is contained in:
+57
-76
@@ -53,8 +53,6 @@ import {
|
||||
FrigateCardView,
|
||||
FRIGATE_CARD_VIEWS_USER_SPECIFIED,
|
||||
MediaLoadedInfo,
|
||||
MEDIA_TYPE_IMAGE,
|
||||
MEDIA_TYPE_VIDEO,
|
||||
MESSAGE_TYPE_PRIORITIES,
|
||||
MenuButton,
|
||||
Message,
|
||||
@@ -80,7 +78,6 @@ import {
|
||||
isTriggeredState,
|
||||
sideLoadHomeAssistantElements,
|
||||
} from './utils/ha';
|
||||
import { getEventID } from './utils/ha/browse-media.js';
|
||||
import { DeviceList, getAllDevices } from './utils/ha/device-registry.js';
|
||||
import {
|
||||
ExtendedEntityCache,
|
||||
@@ -94,8 +91,10 @@ import { isValidMediaLoadedInfo } from './utils/media-info.js';
|
||||
import { View } from './view.js';
|
||||
import pkg from '../package.json';
|
||||
import { ViewContext } from 'view';
|
||||
import { DataManager } from './utils/data-manager.js';
|
||||
import { DataManager } from './utils/data/data-manager.js';
|
||||
import { setLowPerformanceProfile, setPerformanceCSSStyles } from './performance.js';
|
||||
import { DataManagerEngineFactory } from './utils/data/data-manager-engine-factory.js';
|
||||
import { RequestCache } from './utils/data/data-manager-cache.js';
|
||||
|
||||
/** A note on media callbacks:
|
||||
*
|
||||
@@ -144,6 +143,8 @@ console.info(
|
||||
documentationURL: REPO_URL,
|
||||
});
|
||||
|
||||
type InitializedType = 'initialized' | 'initializing';
|
||||
|
||||
/**
|
||||
* Main FrigateCard class.
|
||||
*/
|
||||
@@ -204,7 +205,6 @@ export class FrigateCard extends LitElement {
|
||||
// A cache of resolved media URLs/mimetypes for use in the whole card.
|
||||
protected _resolvedMediaCache = new ResolvedMediaCache();
|
||||
|
||||
// Shared timeline data manager (for main timeline view and mini-timelines).
|
||||
protected _dataManager?: DataManager;
|
||||
|
||||
// The mouse handler may be called continually, throttle it to at most once
|
||||
@@ -212,8 +212,7 @@ export class FrigateCard extends LitElement {
|
||||
protected _boundMouseHandler = throttle(this._mouseHandler.bind(this), 1 * 1000);
|
||||
|
||||
// Whether the card has been successfully initialized.
|
||||
protected _loadedHAElements = false;
|
||||
protected _loadedLanguages = false;
|
||||
protected _initialized?: InitializedType;
|
||||
|
||||
protected _triggers: Map<string, Date> = new Map();
|
||||
protected _untriggerTimerID: number | null = null;
|
||||
@@ -530,7 +529,8 @@ export class FrigateCard extends LitElement {
|
||||
|
||||
if (
|
||||
!this._isBeingCasted() &&
|
||||
(this._view?.isViewerView() || (this._view?.is('timeline') && !!this._view?.media))
|
||||
(this._view?.isViewerView() ||
|
||||
(this._view?.is('timeline') && !!this._view?.queryResults?.hasSelectedResult()))
|
||||
) {
|
||||
buttons.push({
|
||||
icon: 'mdi:download',
|
||||
@@ -1016,6 +1016,7 @@ export class FrigateCard extends LitElement {
|
||||
}
|
||||
|
||||
protected _changeView(args?: { view?: View; resetMessage?: boolean }): void {
|
||||
console.debug(`Frigate Card view change: `, args?.view ?? '[default]');
|
||||
const changeView = (view: View): void => {
|
||||
if (View.isMediaChange(this._view, view)) {
|
||||
this._currentMediaLoadedInfo = null;
|
||||
@@ -1099,18 +1100,12 @@ export class FrigateCard extends LitElement {
|
||||
* Called before each update.
|
||||
*/
|
||||
protected willUpdate(changedProps: PropertyValues): void {
|
||||
// Side load the necessary elements if not already initialized (do not need
|
||||
// to block for the loading to complete).
|
||||
if (!this._loadedHAElements) {
|
||||
sideLoadHomeAssistantElements().then((success) => {
|
||||
if (success) {
|
||||
this._loadedHAElements = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this._cameras && (changedProps.has('_config') || changedProps.has('_cameras'))) {
|
||||
this._dataManager = new DataManager(this._cameras);
|
||||
this._dataManager = new DataManager(
|
||||
new DataManagerEngineFactory(),
|
||||
this._cameras,
|
||||
new RequestCache(),
|
||||
);
|
||||
}
|
||||
|
||||
if (changedProps.has('_cardWideConfig')) {
|
||||
@@ -1237,6 +1232,12 @@ export class FrigateCard extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the card.
|
||||
*/
|
||||
protected async _initialize(): Promise<void> {
|
||||
await Promise.all([sideLoadHomeAssistantElements(), loadLanguages()]);
|
||||
}
|
||||
/**
|
||||
* Determine whether the element should be updated.
|
||||
* @param changedProps The changed properties if any.
|
||||
@@ -1244,11 +1245,13 @@ export class FrigateCard extends LitElement {
|
||||
*/
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
// Load the relevant languages. Cannot do anything until then.
|
||||
if (!this._loadedLanguages) {
|
||||
loadLanguages().then(() => {
|
||||
this._loadedLanguages = true;
|
||||
this.requestUpdate();
|
||||
});
|
||||
if (this._initialized !== 'initialized') {
|
||||
if (this._initialized !== 'initializing') {
|
||||
this._initialize().then(() => {
|
||||
this._initialized = 'initialized';
|
||||
this.requestUpdate();
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1318,12 +1321,9 @@ export class FrigateCard extends LitElement {
|
||||
// Should not occur.
|
||||
return;
|
||||
}
|
||||
const media = this._view.queryResults?.getSelectedResult();
|
||||
|
||||
if (
|
||||
!this._view.media ||
|
||||
(this._view.media.media_content_type !== MEDIA_TYPE_VIDEO &&
|
||||
this._view.media.media_content_type !== MEDIA_TYPE_IMAGE)
|
||||
) {
|
||||
if (!media) {
|
||||
this._setMessageAndUpdate({
|
||||
message: localize('error.download_no_media'),
|
||||
type: 'error',
|
||||
@@ -1336,35 +1336,8 @@ export class FrigateCard extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
let path: string;
|
||||
if (this._view.media.frigate?.event) {
|
||||
const event_id = getEventID(this._view.media);
|
||||
if (!event_id) {
|
||||
this._setMessageAndUpdate({
|
||||
message: localize('error.download_no_event_id'),
|
||||
type: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
path =
|
||||
`/api/frigate/${cameraConfig.frigate.client_id}` +
|
||||
`/notifications/${event_id}/` +
|
||||
`${
|
||||
this._view.media.media_content_type === MEDIA_TYPE_VIDEO
|
||||
? 'clip.mp4'
|
||||
: 'snapshot.jpg'
|
||||
}` +
|
||||
`?download=true`;
|
||||
} else if (this._view.media.frigate?.recording) {
|
||||
const recording = this._view.media.frigate.recording;
|
||||
path =
|
||||
`/api/frigate/${cameraConfig.frigate.client_id}` +
|
||||
`/recording/${cameraConfig.frigate.camera_name}` +
|
||||
`/start/${recording.start_time}` +
|
||||
`/end/${recording.end_time}` +
|
||||
`?download=true`;
|
||||
} else {
|
||||
const path = this._dataManager?.getMediaDownloadPath(media);
|
||||
if (!path) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1412,30 +1385,35 @@ export class FrigateCard extends LitElement {
|
||||
* @returns
|
||||
*/
|
||||
protected _mediaPlayerAction(mediaPlayer: string, action: 'play' | 'stop'): void {
|
||||
if (!['play', 'stop'].includes(action)) {
|
||||
if (!['play', 'stop'].includes(action) || !this._view) {
|
||||
return;
|
||||
}
|
||||
|
||||
let media_content_id: string;
|
||||
let media_content_type: string;
|
||||
const extra = {};
|
||||
const cameraConfig = this._getSelectedCameraConfig();
|
||||
const cameraEntity = cameraConfig?.camera_entity ?? null;
|
||||
let media_content_id: string | null = null;
|
||||
let media_content_type: string | null = null;
|
||||
let title: string | null = null;
|
||||
let thumbnail: string | null = null;
|
||||
|
||||
if (this._view?.isViewerView() && this._view.media) {
|
||||
media_content_id = this._view.media.media_content_id;
|
||||
media_content_type = this._view.media.media_content_type;
|
||||
extra['thumb'] = this._view.media.thumbnail;
|
||||
extra['title'] = this._view.media.title;
|
||||
const cameraConfig = this._getSelectedCameraConfig();
|
||||
if (!cameraConfig) {
|
||||
return;
|
||||
}
|
||||
const cameraEntity = cameraConfig.camera_entity ?? null;
|
||||
const media = this._view.queryResults?.getSelectedResult();
|
||||
|
||||
if (this._view.isViewerView() && media && this._cameras) {
|
||||
media_content_id = media.getContentID(cameraConfig);
|
||||
media_content_type = media.getContentType();
|
||||
title = media.getTitle(cameraConfig);
|
||||
thumbnail = media.getThumbnail(cameraConfig);
|
||||
} else if (this._view?.is('live') && cameraEntity) {
|
||||
if (this._hass?.states && cameraEntity in this._hass.states) {
|
||||
extra['thumb'] =
|
||||
this._hass.states[cameraEntity].attributes.entity_picture ?? null;
|
||||
}
|
||||
extra['title'] = getCameraTitle(this._hass, cameraConfig);
|
||||
media_content_id = `media-source://camera/${cameraEntity}`;
|
||||
media_content_type = 'application/vnd.apple.mpegurl';
|
||||
} else {
|
||||
title = getCameraTitle(this._hass, cameraConfig);
|
||||
thumbnail = this._hass?.states[cameraEntity]?.attributes?.entity_picture ?? null;
|
||||
}
|
||||
|
||||
if (!media_content_id || !media_content_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1444,7 +1422,10 @@ export class FrigateCard extends LitElement {
|
||||
entity_id: mediaPlayer,
|
||||
media_content_id: media_content_id,
|
||||
media_content_type: media_content_type,
|
||||
extra: extra,
|
||||
extra: {
|
||||
...(title && { title: title }),
|
||||
...(thumbnail && { thumb: thumbnail }),
|
||||
},
|
||||
});
|
||||
} else if (action === 'stop') {
|
||||
this._hass?.callService('media_player', 'media_stop', {
|
||||
|
||||
Reference in New Issue
Block a user