Initial support for grid for live and media viewer.

This commit is contained in:
Dermot Duffy
2023-08-08 22:26:25 -07:00
parent 69249b6c33
commit b663e0b731
59 changed files with 3308 additions and 429 deletions
+66 -8
View File
@@ -59,6 +59,7 @@ import {
Message,
MESSAGE_TYPE_PRIORITIES,
RawFrigateCardConfig,
ViewDisplayMode,
} from './types.js';
import {
convertActionToFrigateCardCustomAction,
@@ -97,6 +98,7 @@ import {
} from './utils/substream';
import { Timer } from './utils/timer';
import { getParseErrorPaths } from './utils/zod.js';
import { ViewMediaClassifier } from './view/media-classifier';
import { View } from './view/view.js';
/** A note on media callbacks:
@@ -186,6 +188,9 @@ class FrigateCard extends LitElement {
@state()
protected _expand = false;
@state()
protected _viewDisplayMode?: ViewDisplayMode;
protected _microphoneController?: MicrophoneController;
protected _conditionController?: ConditionController;
protected _automationsController?: AutomationsController;
@@ -414,6 +419,7 @@ class FrigateCard extends LitElement {
state: this._hass.states,
}),
media_loaded: this._mediaLoadedInfoController.has(),
displayMode: undefined,
});
}
@@ -466,6 +472,7 @@ class FrigateCard extends LitElement {
this._conditionController?.setState({
view: this._view.view,
camera: this._view.camera,
displayMode: this._view.displayMode ?? undefined,
});
};
@@ -493,10 +500,14 @@ class FrigateCard extends LitElement {
}
if (cameraID) {
const viewName = args?.viewName ?? this._getConfig().view.default;
const displayMode =
this._viewDisplayMode ?? this._getDefaultDisplayModeForView(viewName);
changeView(
new View({
view: args?.viewName ?? this._getConfig().view.default,
view: viewName,
camera: cameraID,
displayMode: displayMode,
}),
);
@@ -641,7 +652,10 @@ class FrigateCard extends LitElement {
targetCamera &&
(this._view.camera !== targetCamera || !this._view.is('live'))
) {
this._changeView({ view: new View({ view: 'live', camera: targetCamera }) });
this._changeView({
viewName: 'live',
cameraID: targetCamera,
});
changedCamera = true;
}
}
@@ -1003,7 +1017,7 @@ class FrigateCard extends LitElement {
if (this._view.isViewerView() && media) {
media_content_id = media.getContentID();
media_content_type = media.getContentType();
media_content_type = ViewMediaClassifier.isVideo(media) ? 'video' : 'image';
title = media.getTitle();
thumbnail = media.getThumbnail();
} else if (this._view?.is('live') && cameraEntity) {
@@ -1049,6 +1063,24 @@ class FrigateCard extends LitElement {
}
}
protected _getDefaultDisplayModeForView(view: FrigateCardView): ViewDisplayMode {
let mode: ViewDisplayMode | null = null;
switch (view) {
case 'clip':
case 'clips':
case 'recording':
case 'recordings':
case 'snapshot':
case 'snapshots':
mode = this._getConfig().media_viewer.display?.mode ?? null;
break;
case 'live':
mode = this._getConfig().live.display?.mode ?? null;
break;
}
return mode ?? 'single';
}
protected _cardActionHandler(frigateCardAction: FrigateCardCustomAction): void {
// Note: This function needs to process (view-related) commands even when
// _view has not yet been initialized (since it may be used to set a view
@@ -1119,7 +1151,8 @@ class FrigateCard extends LitElement {
? targetView
: FRIGATE_CARD_VIEW_DEFAULT;
this._changeView({
view: new View({ view: actualView, camera: selectCameraID }),
viewName: actualView,
cameraID: selectCameraID,
});
}
break;
@@ -1203,6 +1236,25 @@ class FrigateCard extends LitElement {
}
});
break;
case 'display_mode_select':
this._viewDisplayMode = frigateCardAction.display_mode;
this._conditionController?.setState({
displayMode: this._viewDisplayMode,
});
// If the new mode is for all cameras, but the current query does not
// have a query for every cameraID, reset it.
const resetQuery =
frigateCardAction.mode === 'grid' &&
!this._view?.query?.hasQueriesForCameraIDs(
this._cameraManager.getStore().getVisibleCameraIDs(),
);
this._changeView({
view: this._view?.evolve({
displayMode: frigateCardAction.display_mode,
...(resetQuery && { query: null, queryResults: null }),
}),
});
break;
default:
console.warn(`Frigate card received unknown card action: ${action}`);
}
@@ -1501,15 +1553,21 @@ class FrigateCard extends LitElement {
? `${lastKnown.width} / ${lastKnown.height}`
: 'unset',
);
// Non-media mays have no intrinsic dimensions and so we need to explicit
// request the dialog to use all available space.
// Non-media may have no intrinsic dimensions (or multiple media items in a
// grid) and so we need to explicit request the dialog to use all available
// space.
const isGrid = this._view?.isGrid();
this.style.setProperty(
'--frigate-card-expand-width',
this._view?.isAnyMediaView() ? 'none' : 'var(--frigate-card-expand-max-width)',
!isGrid && this._view?.isAnyMediaView()
? 'none'
: 'var(--frigate-card-expand-max-width)',
);
this.style.setProperty(
'--frigate-card-expand-height',
this._view?.isAnyMediaView() ? 'none' : 'var(--frigate-card-expand-max-height)',
!isGrid && this._view?.isAnyMediaView()
? 'none'
: 'var(--frigate-card-expand-max-height)',
);
}