Dispatch message if the viewer has no media to show.
This commit is contained in:
@@ -509,8 +509,10 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
targetView: 'media',
|
targetView: 'media',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const results = view?.queryResults?.getResults() ?? null;
|
const results = view?.queryResults?.getResults();
|
||||||
if (!results || !view) {
|
// Specifically ensure there are _some_ results before dispatching the
|
||||||
|
// view change.
|
||||||
|
if (!view || !results || !results.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
view.mergeInContext(
|
view.mergeInContext(
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
import { customElement, property } from 'lit/decorators.js';
|
import { customElement, property } from 'lit/decorators.js';
|
||||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||||
import { createRef, Ref, ref } from 'lit/directives/ref.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 viewerStyle from '../scss/viewer.scss';
|
||||||
import viewerCarouselStyle from '../scss/viewer-carousel.scss';
|
import viewerCarouselStyle from '../scss/viewer-carousel.scss';
|
||||||
import {
|
import {
|
||||||
@@ -53,6 +53,7 @@ import {
|
|||||||
} from '../utils/media-to-view.js';
|
} from '../utils/media-to-view.js';
|
||||||
import { ViewMedia, ViewMediaClassifier } from '../view-media.js';
|
import { ViewMedia, ViewMediaClassifier } from '../view-media.js';
|
||||||
import { guard } from 'lit/directives/guard.js';
|
import { guard } from 'lit/directives/guard.js';
|
||||||
|
import { localize } from '../localize/localize.js';
|
||||||
|
|
||||||
export interface MediaSeek {
|
export interface MediaSeek {
|
||||||
// Specifies the point at which this recording should be played, the
|
// 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.
|
* @returns A template to display to the user.
|
||||||
*/
|
*/
|
||||||
protected _render(): TemplateResult | void {
|
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();
|
const media = this.view?.queryResults?.getSelectedResult();
|
||||||
if (!media || !this.cameras) {
|
if (!media || !this.cameras) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -3,11 +3,7 @@
|
|||||||
"frigate_card": "Frigate card",
|
"frigate_card": "Frigate card",
|
||||||
"frigate_card_description": "A Lovelace card for use with Frigate",
|
"frigate_card_description": "A Lovelace card for use with Frigate",
|
||||||
"live": "Live",
|
"live": "Live",
|
||||||
"no_clip": "No recent clip",
|
"no_media": "No media to display",
|
||||||
"no_clips": "No clips",
|
|
||||||
"no_snapshot": "No recent snapshot",
|
|
||||||
"no_snapshots": "No snapshots",
|
|
||||||
"no_recording": "No recent recording",
|
|
||||||
"recordings": "Recordings",
|
"recordings": "Recordings",
|
||||||
"version": "Version"
|
"version": "Version"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,10 +3,7 @@
|
|||||||
"frigate_card": "Frigate card",
|
"frigate_card": "Frigate card",
|
||||||
"frigate_card_description": "Una scheda Lovelace per l'uso con Frigate",
|
"frigate_card_description": "Una scheda Lovelace per l'uso con Frigate",
|
||||||
"live": "Live",
|
"live": "Live",
|
||||||
"no_clip": "Nessuna clip recente",
|
"no_media": "",
|
||||||
"no_clips": "Nessun clip",
|
|
||||||
"no_snapshot": "Nessuna istantanea recente",
|
|
||||||
"no_snapshots": "Nessuna istantanea",
|
|
||||||
"recordings": "Registrazioni",
|
"recordings": "Registrazioni",
|
||||||
"version": "Versione"
|
"version": "Versione"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,10 +3,7 @@
|
|||||||
"frigate_card": "Cartão Frigate",
|
"frigate_card": "Cartão Frigate",
|
||||||
"frigate_card_description": "Um cartão da Lovelace para usar com Frigate",
|
"frigate_card_description": "Um cartão da Lovelace para usar com Frigate",
|
||||||
"live": "Ao Vivo",
|
"live": "Ao Vivo",
|
||||||
"no_clip": "Sem clip recente",
|
"no_media": "",
|
||||||
"no_clips": "Sem clips",
|
|
||||||
"no_snapshot": "Sem snapshot recente",
|
|
||||||
"no_snapshots": "Sem snapshots",
|
|
||||||
"recordings": "Gravações",
|
"recordings": "Gravações",
|
||||||
"version": "Versão"
|
"version": "Versão"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -202,13 +202,11 @@ export class DataManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mediaArray.length
|
return new MediaQueriesResults(
|
||||||
? new MediaQueriesResults(
|
|
||||||
orderBy(mediaArray, (media) => media.getStartTime(), 'desc'),
|
orderBy(mediaArray, (media) => media.getStartTime(), 'desc'),
|
||||||
// Select the first (most-recent) item.
|
// Select the first (most-recent) item.
|
||||||
0,
|
mediaArray.length ? 0 : null,
|
||||||
)
|
);
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getMediaDownloadPath(media: ViewMedia): string | null {
|
public getMediaDownloadPath(media: ViewMedia): string | null {
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ export const createViewForEvents = async (
|
|||||||
const queries = dataManager.generateDefaultEventQueries(cameraIDs, {
|
const queries = dataManager.generateDefaultEventQueries(cameraIDs, {
|
||||||
...(options?.limit && { limit: options.limit }),
|
...(options?.limit && { limit: options.limit }),
|
||||||
...((!options?.mediaType || ['clips', 'all'].includes(options.mediaType)) && {
|
...((!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);
|
query = new EventMediaQueries(queries);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -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: 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: 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: 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: 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 _timelineClickHandler be an async method in timeline-core to improve cleanliness?
|
||||||
// - TODO: Can _timelineRangeChangedHandler 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 _resultsTimestamp: Date | null = null;
|
||||||
protected _selectedIndex: number | null = null;
|
protected _selectedIndex: number | null = null;
|
||||||
|
|
||||||
constructor(results?: ViewMedia[], selectedIndex?: number) {
|
constructor(results?: ViewMedia[], selectedIndex?: number | null) {
|
||||||
if (results) {
|
if (results) {
|
||||||
this.setResults(results);
|
this.setResults(results);
|
||||||
}
|
}
|
||||||
@@ -177,8 +176,8 @@ export class MediaQueriesResults {
|
|||||||
return this._resultsTimestamp;
|
return this._resultsTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public selectResult(index: number): MediaQueriesResults {
|
public selectResult(index: number | null): MediaQueriesResults {
|
||||||
if (this._results && index >= 0 && index < this._results.length) {
|
if (index === null || (this._results && index >= 0 && index < this._results.length)) {
|
||||||
this._selectedIndex = index;
|
this._selectedIndex = index;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
Reference in New Issue
Block a user