Allow views to have no selection.
This commit is contained in:
@@ -94,6 +94,7 @@ export class FrigateCardSurround extends LitElement {
|
|||||||
{
|
{
|
||||||
targetView: this.view.view,
|
targetView: this.view.view,
|
||||||
mediaType: this.fetchMedia,
|
mediaType: this.fetchMedia,
|
||||||
|
select: 'latest',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -490,6 +490,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
properties.what === 'background'
|
properties.what === 'background'
|
||||||
? properties.time
|
? properties.time
|
||||||
: this._timeline.getWindow().end,
|
: this._timeline.getWindow().end,
|
||||||
|
select: 'time',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -513,6 +514,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
{
|
{
|
||||||
targetView: 'recording',
|
targetView: 'recording',
|
||||||
targetTime: properties.time,
|
targetTime: properties.time,
|
||||||
|
select: 'time',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -661,6 +663,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
query,
|
query,
|
||||||
{
|
{
|
||||||
targetView: options?.targetView,
|
targetView: options?.targetView,
|
||||||
|
select: 'latest',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (!view) {
|
if (!view) {
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ export class FrigateCardViewer extends LitElement {
|
|||||||
this.view,
|
this.view,
|
||||||
{
|
{
|
||||||
targetView: 'recording',
|
targetView: 'recording',
|
||||||
|
select: 'latest',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -132,6 +133,7 @@ export class FrigateCardViewer extends LitElement {
|
|||||||
{
|
{
|
||||||
targetView: 'media',
|
targetView: 'media',
|
||||||
mediaType: mediaType,
|
mediaType: mediaType,
|
||||||
|
select: 'latest',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -543,13 +545,19 @@ export class FrigateCardViewerCarousel extends LitElement {
|
|||||||
* @returns A template to display to the user.
|
* @returns A template to display to the user.
|
||||||
*/
|
*/
|
||||||
protected _render(): TemplateResult | void {
|
protected _render(): TemplateResult | void {
|
||||||
if ((this.view?.queryResults?.getResultsCount() ?? 0) === 0) {
|
const resultCount = this.view?.queryResults?.getResultsCount() ?? 0;
|
||||||
|
if (!resultCount) {
|
||||||
return dispatchMessageEvent(this, localize('common.no_media'), 'info', {
|
return dispatchMessageEvent(this, localize('common.no_media'), 'info', {
|
||||||
icon: 'mdi:multimedia',
|
icon: 'mdi:multimedia',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const media = this.view?.queryResults?.getSelectedResult();
|
// If there's no selected media, just choose the last (most recent one) to
|
||||||
|
// avoid rendering a blank. This situation should not occur in practice, as
|
||||||
|
// this view should not be called without a selected media.
|
||||||
|
const media =
|
||||||
|
this.view?.queryResults?.getSelectedResult() ??
|
||||||
|
this.view?.queryResults?.getResult(resultCount - 1);
|
||||||
if (!media || !this.view || !this.view.queryResults) {
|
if (!media || !this.view || !this.view.queryResults) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import { errorToConsole } from './basic';
|
|||||||
import { MediaQuery } from '../camera-manager/types';
|
import { MediaQuery } from '../camera-manager/types';
|
||||||
import { MEDIA_CHUNK_SIZE_DEFAULT } from '../const';
|
import { MEDIA_CHUNK_SIZE_DEFAULT } from '../const';
|
||||||
|
|
||||||
|
type ResultSelectType = 'latest' | 'time' | 'none';
|
||||||
|
|
||||||
export const changeViewToRecentEventsForCameraAndDependents = async (
|
export const changeViewToRecentEventsForCameraAndDependents = async (
|
||||||
element: HTMLElement,
|
element: HTMLElement,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@@ -25,6 +27,7 @@ export const changeViewToRecentEventsForCameraAndDependents = async (
|
|||||||
options?: {
|
options?: {
|
||||||
mediaType?: ClipsOrSnapshotsOrAll;
|
mediaType?: ClipsOrSnapshotsOrAll;
|
||||||
targetView?: FrigateCardView;
|
targetView?: FrigateCardView;
|
||||||
|
select?: ResultSelectType;
|
||||||
},
|
},
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const cameraIDs = getAllDependentCameras(cameraManager, view.camera);
|
const cameraIDs = getAllDependentCameras(cameraManager, view.camera);
|
||||||
@@ -42,6 +45,7 @@ export const changeViewToRecentEventsForCameraAndDependents = async (
|
|||||||
(
|
(
|
||||||
await executeMediaQueryForView(element, hass, cameraManager, view, queries, {
|
await executeMediaQueryForView(element, hass, cameraManager, view, queries, {
|
||||||
targetView: options?.targetView,
|
targetView: options?.targetView,
|
||||||
|
select: options?.select,
|
||||||
})
|
})
|
||||||
)?.dispatchChangeEvent(element);
|
)?.dispatchChangeEvent(element);
|
||||||
};
|
};
|
||||||
@@ -81,6 +85,7 @@ export const changeViewToRecentRecordingForCameraAndDependents = async (
|
|||||||
view: View,
|
view: View,
|
||||||
options?: {
|
options?: {
|
||||||
targetView?: 'recording' | 'recordings';
|
targetView?: 'recording' | 'recordings';
|
||||||
|
select?: ResultSelectType;
|
||||||
},
|
},
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const cameraIDs = getAllDependentCameras(cameraManager, view.camera);
|
const cameraIDs = getAllDependentCameras(cameraManager, view.camera);
|
||||||
@@ -100,6 +105,7 @@ export const changeViewToRecentRecordingForCameraAndDependents = async (
|
|||||||
(
|
(
|
||||||
await executeMediaQueryForView(element, hass, cameraManager, view, queries, {
|
await executeMediaQueryForView(element, hass, cameraManager, view, queries, {
|
||||||
targetView: options?.targetView,
|
targetView: options?.targetView,
|
||||||
|
select: options?.select,
|
||||||
})
|
})
|
||||||
)?.dispatchChangeEvent(element);
|
)?.dispatchChangeEvent(element);
|
||||||
};
|
};
|
||||||
@@ -133,6 +139,7 @@ export const executeMediaQueryForView = async (
|
|||||||
targetCameraID?: string;
|
targetCameraID?: string;
|
||||||
targetView?: FrigateCardView;
|
targetView?: FrigateCardView;
|
||||||
targetTime?: Date;
|
targetTime?: Date;
|
||||||
|
select?: ResultSelectType;
|
||||||
},
|
},
|
||||||
): Promise<View | null> => {
|
): Promise<View | null> => {
|
||||||
let mediaArray: ViewMedia[] | null;
|
let mediaArray: ViewMedia[] | null;
|
||||||
@@ -153,12 +160,16 @@ export const executeMediaQueryForView = async (
|
|||||||
if (!mediaArray) {
|
if (!mediaArray) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Select the last item by default (which is the most recent).
|
|
||||||
const selectedIndex = mediaArray.length ? mediaArray.length - 1 : undefined;
|
const queryResults = new MediaQueriesResults(
|
||||||
const queryResults = new MediaQueriesResults(mediaArray, selectedIndex);
|
mediaArray,
|
||||||
|
options?.select === 'latest' && mediaArray.length
|
||||||
|
? mediaArray.length - 1
|
||||||
|
: undefined,
|
||||||
|
);
|
||||||
let viewerContext: ViewContext | undefined = {};
|
let viewerContext: ViewContext | undefined = {};
|
||||||
|
|
||||||
if (options?.targetTime) {
|
if (options?.select === 'time' && options?.targetTime) {
|
||||||
queryResults.selectBestResult((media) =>
|
queryResults.selectBestResult((media) =>
|
||||||
findClosestMediaIndex(media, options.targetTime as Date),
|
findClosestMediaIndex(media, options.targetTime as Date),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ export class MediaQueriesResults {
|
|||||||
if (results) {
|
if (results) {
|
||||||
this.setResults(results);
|
this.setResults(results);
|
||||||
}
|
}
|
||||||
this.selectResult(selectedIndex ?? 0);
|
if (selectedIndex !== undefined) {
|
||||||
|
this.selectResult(selectedIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public clone(): MediaQueriesResults {
|
public clone(): MediaQueriesResults {
|
||||||
|
|||||||
Reference in New Issue
Block a user