Make Frigate URL context aware.

This commit is contained in:
Dermot Duffy
2021-08-22 07:47:23 -07:00
parent ae1ab1ffe8
commit 6a0b165e40
+61 -49
View File
@@ -1,5 +1,6 @@
// TODO Put heading back // TODO Put heading back
// TODO Verify getCardSize() // TODO Verify getCardSize()
// TODO edit menu mode
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import { import {
@@ -269,18 +270,19 @@ export class FrigateCard extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
protected _viewMode: FrigateCardView = 'live'; protected _viewMode: FrigateCardView = 'live';
@property({ attribute: false })
protected _viewEvent: FrigateEvent | null = null;
@property({ attribute: false })
protected _showMenu = false;
@state()
protected _heading: string | null = null;
protected _interactionTimerID: number | null = null; protected _interactionTimerID: number | null = null;
protected _webrtcElement: any | null = null; protected _webrtcElement: any | null = null;
// Event specifically requested to be shown by the user.
@property({ attribute: false })
protected _requestedEvent: FrigateEvent | null = null;
// Event actually being shown to the user. This may be different from
// _requestedEvent when no particular event is requested (e.g. most recent) --
// in that case the requestedEvent will be null, but _eventBeingShown will be
// the actual event shown.
protected _eventBeingShown: FrigateEvent | null = null;
// Whether or not there is an active clip being played. // Whether or not there is an active clip being played.
protected _clipPlaying = false; protected _clipPlaying = false;
@@ -325,14 +327,23 @@ export class FrigateCard extends LitElement {
} }
this.config = config; this.config = config;
this._setViewModeToDefault(); this._changeView();
} }
// Set the view mode to the configured default. protected _changeView(
protected _setViewModeToDefault(): void { view?: FrigateCardView | undefined,
this._viewMode = this.config.view_default; event?: FrigateEvent | undefined): void {
if (['clip', 'snapshot'].includes(this._viewMode)) { if (view !== undefined) {
this._viewEvent = null; this._viewMode = view;
} else {
this._viewMode = this.config.view_default;
if (['clip', 'snapshot'].includes(this.config.view_default)) {
this._requestedEvent = null;
}
}
this._eventBeingShown = null;
if (event !== undefined) {
this._requestedEvent = event;
} }
} }
@@ -469,9 +480,7 @@ export class FrigateCard extends LitElement {
class="mdc-image-list__image" class="mdc-image-list__image"
src="data:image/png;base64,${event.thumbnail}" src="data:image/png;base64,${event.thumbnail}"
@click=${() => { @click=${() => {
this._showMenu = false; this._changeView(want_clips ? 'clip' : 'snapshot' , event);
this._viewEvent = event;
this._viewMode = want_clips ? 'clip' : 'snapshot';
}} }}
/> />
</div> </div>
@@ -546,27 +555,23 @@ export class FrigateCard extends LitElement {
case 'default': case 'default':
this._controlVideos({ stop: true, control_clip: true }); this._controlVideos({ stop: true, control_clip: true });
this._controlVideos({ stop: true, control_live: true }); this._controlVideos({ stop: true, control_live: true });
this._heading = null; this._changeView();
this._setViewModeToDefault();
break; break;
case 'live': case 'live':
this._controlVideos({ stop: true, control_clip: true }); this._controlVideos({ stop: true, control_clip: true });
this._controlVideos({ stop: false, control_live: true }); this._controlVideos({ stop: false, control_live: true });
this._viewMode = name; this._changeView(name);
this._heading = null;
break; break;
case 'clips': case 'clips':
this._controlVideos({ stop: true, control_live: true }); this._controlVideos({ stop: true, control_live: true });
this._viewMode = name; this._changeView(name);
this._heading = null;
break; break;
case 'snapshots': case 'snapshots':
this._controlVideos({ stop: true, control_clip: true, control_live: true }); this._controlVideos({ stop: true, control_clip: true, control_live: true });
this._viewMode = name; this._changeView(name);
this._heading = null;
break; break;
case 'frigate-ui': case 'frigate-ui':
window.open(this.config.frigate_url); window.open(this._getFrigateURLFromContext());
break; break;
case 'motion': case 'motion':
if (this.config.motion_entity) { if (this.config.motion_entity) {
@@ -578,6 +583,13 @@ export class FrigateCard extends LitElement {
} }
} }
protected _getFrigateURLFromContext(): string {
if (this._eventBeingShown) {
return `${this.config.frigate_url}/events/${this._eventBeingShown.id}`;
}
return `${this.config.frigate_url}/cameras/${this.config.frigate_camera_name}`;
}
protected _getClipURLFromEvent(event: FrigateEvent): string | null { protected _getClipURLFromEvent(event: FrigateEvent): string | null {
if (!event.has_clip) { if (!event.has_clip) {
return null; return null;
@@ -596,8 +608,8 @@ export class FrigateCard extends LitElement {
protected async _renderClipPlayer(): Promise<TemplateResult> { protected async _renderClipPlayer(): Promise<TemplateResult> {
let event: FrigateEvent, events: FrigateGetEventsResponse; let event: FrigateEvent, events: FrigateGetEventsResponse;
let autoplay = true; let autoplay = true;
if (this._viewEvent) { if (this._requestedEvent) {
event = this._viewEvent; event = this._requestedEvent;
} else { } else {
try { try {
events = await this._getEvents({ events = await this._getEvents({
@@ -627,29 +639,30 @@ export class FrigateCard extends LitElement {
return this._renderAttentionIcon('mdi:camera-off', 'No recent clip'); return this._renderAttentionIcon('mdi:camera-off', 'No recent clip');
} }
this._heading = this._getEventTitle(event); this._eventBeingShown = event;
return html` <video return html` <video
class="frigate-card-viewer" class="frigate-card-viewer"
muted muted
controls controls
@play=${() => { @play=${() => {
this._clipPlaying = true; this._clipPlaying = true;
}} }}
@pause=${() => { @pause=${() => {
this._clipPlaying = false; this._clipPlaying = false;
}} }}
?autoplay="${autoplay}" ?autoplay="${autoplay}"
> >
<source src="${clipURL}" type="video/mp4" /> <source src="${clipURL}" type="video/mp4" />
</video>`; </video>
`;
} }
// Render a snapshot. // Render a snapshot.
protected async _renderSnapshotViewer(): Promise<TemplateResult> { protected async _renderSnapshotViewer(): Promise<TemplateResult> {
let event: FrigateEvent, events: FrigateGetEventsResponse; let event: FrigateEvent, events: FrigateGetEventsResponse;
if (this._viewEvent) { if (this._requestedEvent) {
event = this._viewEvent; event = this._requestedEvent;
} else { } else {
try { try {
events = await this._getEvents({ events = await this._getEvents({
@@ -672,15 +685,14 @@ export class FrigateCard extends LitElement {
return this._renderAttentionIcon('mdi:filmstrip-off', 'No recent snapshots'); return this._renderAttentionIcon('mdi:filmstrip-off', 'No recent snapshots');
} }
this._heading = this._getEventTitle(event); this._eventBeingShown = event;
return html` <img return html` <img
class="frigate-card-viewer" class="frigate-card-viewer"
src="${snapshotURL}" src="${snapshotURL}"
@click=${() => { @click=${() => {
if (event.has_clip) { if (event.has_clip) {
this._viewEvent = event; this._changeView('clip', event);
this._viewMode = 'clip';
} }
}} }}
/>`; />`;
@@ -715,7 +727,7 @@ export class FrigateCard extends LitElement {
} }
this._interactionTimerID = window.setTimeout(() => { this._interactionTimerID = window.setTimeout(() => {
this._interactionTimerID = null; this._interactionTimerID = null;
this._setViewModeToDefault(); this._changeView();
}, this.config.view_timeout * 1000); }, this.config.view_timeout * 1000);
} }