Dispatch message if the viewer has no media to show.

This commit is contained in:
Dermot Duffy
2023-01-24 19:36:54 -08:00
parent 5be6ee86e0
commit e0d2dfaa60
8 changed files with 26 additions and 30 deletions
+4 -2
View File
@@ -509,8 +509,10 @@ export class FrigateCardTimelineCore extends LitElement {
targetView: 'media',
},
);
const results = view?.queryResults?.getResults() ?? null;
if (!results || !view) {
const results = view?.queryResults?.getResults();
// Specifically ensure there are _some_ results before dispatching the
// view change.
if (!view || !results || !results.length) {
return null;
}
view.mergeInContext(
+9 -2
View File
@@ -12,7 +12,7 @@ import {
import { customElement, property } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { createRef, Ref, ref } from 'lit/directives/ref.js';
import { renderProgressIndicator } from '../components/message.js';
import { dispatchMessageEvent, renderProgressIndicator } from '../components/message.js';
import viewerStyle from '../scss/viewer.scss';
import viewerCarouselStyle from '../scss/viewer-carousel.scss';
import {
@@ -53,6 +53,7 @@ import {
} from '../utils/media-to-view.js';
import { ViewMedia, ViewMediaClassifier } from '../view-media.js';
import { guard } from 'lit/directives/guard.js';
import { localize } from '../localize/localize.js';
export interface MediaSeek {
// Specifies the point at which this recording should be played, the
@@ -566,6 +567,12 @@ export class FrigateCardViewerCarousel extends LitElement {
* @returns A template to display to the user.
*/
protected _render(): TemplateResult | void {
if ((this.view?.queryResults?.getResultsCount() ?? 0) === 0) {
return dispatchMessageEvent(this, localize('common.no_media'), 'info', {
icon: 'mdi:multimedia',
});
}
const media = this.view?.queryResults?.getSelectedResult();
if (!media || !this.cameras) {
return;
@@ -622,7 +629,7 @@ export class FrigateCardViewerCarousel extends LitElement {
protected _recordingSeekHandler(): void {
const selectedIndex = this.view?.queryResults?.getSelectedIndex() ?? null;
const seek =
selectedIndex !== null
selectedIndex !== null
? this.view?.context?.mediaViewer?.seek.get(selectedIndex)
: null;
const player = this._getPlayer();
+1 -5
View File
@@ -3,11 +3,7 @@
"frigate_card": "Frigate card",
"frigate_card_description": "A Lovelace card for use with Frigate",
"live": "Live",
"no_clip": "No recent clip",
"no_clips": "No clips",
"no_snapshot": "No recent snapshot",
"no_snapshots": "No snapshots",
"no_recording": "No recent recording",
"no_media": "No media to display",
"recordings": "Recordings",
"version": "Version"
},
+1 -4
View File
@@ -3,10 +3,7 @@
"frigate_card": "Frigate card",
"frigate_card_description": "Una scheda Lovelace per l'uso con Frigate",
"live": "Live",
"no_clip": "Nessuna clip recente",
"no_clips": "Nessun clip",
"no_snapshot": "Nessuna istantanea recente",
"no_snapshots": "Nessuna istantanea",
"no_media": "",
"recordings": "Registrazioni",
"version": "Versione"
},
+1 -4
View File
@@ -3,10 +3,7 @@
"frigate_card": "Cartão Frigate",
"frigate_card_description": "Um cartão da Lovelace para usar com Frigate",
"live": "Ao Vivo",
"no_clip": "Sem clip recente",
"no_clips": "Sem clips",
"no_snapshot": "Sem snapshot recente",
"no_snapshots": "Sem snapshots",
"no_media": "",
"recordings": "Gravações",
"version": "Versão"
},
+5 -7
View File
@@ -202,13 +202,11 @@ export class DataManager {
}
}
return mediaArray.length
? new MediaQueriesResults(
orderBy(mediaArray, (media) => media.getStartTime(), 'desc'),
// Select the first (most-recent) item.
0,
)
: null;
return new MediaQueriesResults(
orderBy(mediaArray, (media) => media.getStartTime(), 'desc'),
// Select the first (most-recent) item.
mediaArray.length ? 0 : null,
);
}
public getMediaDownloadPath(media: ViewMedia): string | null {
+2 -2
View File
@@ -54,9 +54,9 @@ export const createViewForEvents = async (
const queries = dataManager.generateDefaultEventQueries(cameraIDs, {
...(options?.limit && { limit: options.limit }),
...((!options?.mediaType || ['clips', 'all'].includes(options.mediaType)) && {
has_clip: true,
hasClip: true,
}),
...(options?.mediaType === 'snapshots' && { has_snapshot: true }),
...(options?.mediaType === 'snapshots' && { hasSnapshot: true }),
});
query = new EventMediaQueries(queries);
}
+3 -4
View File
@@ -6,7 +6,6 @@
// - TODO: Are there elements of ViewMedia (e.g. getEventCount) that should be moved into subclasses (e.g. a recording subclass).
// - TODO: In MediaQueriesBase, do we need to generic? Just have T be a MediaQuery?
// - TODO: Are areEventQueries and areRecordingQueries should be in a classifier to keep with the pattern used elsewhere.
// - TODO: Callers to the creation of new views for events/recordings need to dispatch events themselves when none are found.
// - TODO: In the viewer @click handlers should I use this.selected instead of calling carouselScrollPrevious()
// - TODO: Can _timelineClickHandler be an async method in timeline-core to improve cleanliness?
// - TODO: Can _timelineRangeChangedHandler be an async method in timeline-core to improve cleanliness?
@@ -124,7 +123,7 @@ export class MediaQueriesResults {
protected _resultsTimestamp: Date | null = null;
protected _selectedIndex: number | null = null;
constructor(results?: ViewMedia[], selectedIndex?: number) {
constructor(results?: ViewMedia[], selectedIndex?: number | null) {
if (results) {
this.setResults(results);
}
@@ -177,8 +176,8 @@ export class MediaQueriesResults {
return this._resultsTimestamp;
}
public selectResult(index: number): MediaQueriesResults {
if (this._results && index >= 0 && index < this._results.length) {
public selectResult(index: number | null): MediaQueriesResults {
if (index === null || (this._results && index >= 0 && index < this._results.length)) {
this._selectedIndex = index;
}
return this;