Converge view mode lists.

This commit is contained in:
Dermot Duffy
2021-08-15 18:59:35 -07:00
parent 5962e7f024
commit 505ea85afa
3 changed files with 45 additions and 52 deletions
+18 -18
View File
@@ -73,15 +73,15 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
this._helpers.importMoreInfoControl('climate'); this._helpers.importMoreInfoControl('climate');
// You can restrict on domain type // You can restrict on domain type
const camera_entities = this._getEntities('camera'); const cameraEntities = this._getEntities('camera');
const binary_sensor_entities = this._getEntities('binary_sensor'); const binarySensorEntities = this._getEntities('binary_sensor');
const webrtc_camera_entity = const webrtcCameraEntity =
this._config?.webrtc && (this._config?.webrtc as any).entity ? this._config?.webrtc && (this._config?.webrtc as any).entity ?
(this._config?.webrtc as any).entity : (this._config?.webrtc as any).entity :
''; '';
const view_modes = { const viewModes = {
"": "", "": "",
"live": "Live view", "live": "Live view",
"clips": "Clip gallery", "clips": "Clip gallery",
@@ -90,7 +90,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
"snapshot": "Latest snapshot", "snapshot": "Latest snapshot",
} }
const live_provider = { const liveProvider = {
"": "", "": "",
"frigate": "Frigate", "frigate": "Frigate",
"webrtc": "WebRTC", "webrtc": "WebRTC",
@@ -113,8 +113,8 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
.configValue=${'camera_entity'} .configValue=${'camera_entity'}
> >
<paper-listbox slot="dropdown-content" .selected=${camera_entities.indexOf(this._config?.camera_entity || '')}> <paper-listbox slot="dropdown-content" .selected=${cameraEntities.indexOf(this._config?.camera_entity || '')}>
${camera_entities.map(entity => { ${cameraEntities.map(entity => {
return html` return html`
<paper-item>${entity}</paper-item> <paper-item>${entity}</paper-item>
`; `;
@@ -145,8 +145,8 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
.configValue=${'motion_entity'} .configValue=${'motion_entity'}
> >
<paper-listbox slot="dropdown-content" .selected=${binary_sensor_entities.indexOf(this._config?.motion_entity || '')}> <paper-listbox slot="dropdown-content" .selected=${binarySensorEntities.indexOf(this._config?.motion_entity || '')}>
${binary_sensor_entities.map(entity => { ${binarySensorEntities.map(entity => {
return html` return html`
<paper-item>${entity}</paper-item> <paper-item>${entity}</paper-item>
`; `;
@@ -164,11 +164,11 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
.configValue=${'view_default'} .configValue=${'view_default'}
> >
<paper-listbox slot="dropdown-content" .selected=${Object.keys(view_modes).indexOf(this._config?.view_default || '')}> <paper-listbox slot="dropdown-content" .selected=${Object.keys(viewModes).indexOf(this._config?.view_default || '')}>
${Object.keys(view_modes).map(key => { ${Object.keys(viewModes).map(key => {
return html` return html`
<paper-item .label="${key}"> <paper-item .label="${key}">
${view_modes[key]} ${viewModes[key]}
</paper-item> </paper-item>
`; `;
})} })}
@@ -185,13 +185,13 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
<paper-dropdown-menu <paper-dropdown-menu
label="Live provider (Optional)" label="Live provider (Optional)"
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
.configValue=${'live_provider'} .configValue=${'liveProvider'}
> >
<paper-listbox slot="dropdown-content" .selected=${Object.keys(live_provider).indexOf(this._config?.live_provider || '')}> <paper-listbox slot="dropdown-content" .selected=${Object.keys(liveProvider).indexOf(this._config?.live_provider || '')}>
${Object.keys(live_provider).map(key => { ${Object.keys(liveProvider).map(key => {
return html` return html`
<paper-item .label="${key}" <paper-item .label="${key}"
>${live_provider[key]} >${liveProvider[key]}
</paper-item> </paper-item>
`; `;
})} })}
@@ -202,8 +202,8 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
.configValue=${'webrtc.entity'} .configValue=${'webrtc.entity'}
> >
<paper-listbox slot="dropdown-content" .selected=${camera_entities.indexOf(webrtc_camera_entity)}> <paper-listbox slot="dropdown-content" .selected=${cameraEntities.indexOf(webrtcCameraEntity)}>
${camera_entities.map(entity => { ${cameraEntities.map(entity => {
return html` return html`
<paper-item>${entity}</paper-item> <paper-item>${entity}</paper-item>
`; `;
+15 -33
View File
@@ -33,7 +33,7 @@ import frigate_card_style from './frigate-card.scss'
import frigate_card_menu_style from './frigate-card-menu.scss' import frigate_card_menu_style from './frigate-card-menu.scss'
import { frigateCardConfigSchema, frigateGetEventsResponseSchema } from './types'; import { frigateCardConfigSchema, frigateGetEventsResponseSchema } from './types';
import type { FrigateCardConfig, FrigateEvent, FrigateGetEventsResponse, GetEventsParameters, ControlVideosParameters } from './types'; import type { FrigateCardView, FrigateCardConfig, FrigateEvent, FrigateGetEventsResponse, GetEventsParameters, ControlVideosParameters } from './types';
import { CARD_VERSION } from './const'; import { CARD_VERSION } from './const';
import { localize } from './localize/localize'; import { localize } from './localize/localize';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -59,14 +59,6 @@ console.info(
description: 'A lovelace card for use with Frigate', description: 'A lovelace card for use with Frigate',
}); });
enum FrigateCardView {
LIVE, // Show the live camera.
CLIP, // Show a clip video.
CLIPS, // Show the clips gallery.
SNAPSHOT, // Show a snapshot.
SNAPSHOTS, // Show the snapshots gallery.
}
type FrigateCardMenuCallback = (name: string) => any; type FrigateCardMenuCallback = (name: string) => any;
// A menu for the Frigate card. // A menu for the Frigate card.
@@ -207,7 +199,7 @@ export class FrigateCard extends LitElement {
// Constructor for FrigateCard. // Constructor for FrigateCard.
constructor() { constructor() {
super(); super();
this._viewMode = FrigateCardView.LIVE; this._viewMode = "live";
this._viewEvent = null; this._viewEvent = null;
this._interactionTimerID = null; this._interactionTimerID = null;
this._webrtcElement = null; this._webrtcElement = null;
@@ -295,17 +287,8 @@ export class FrigateCard extends LitElement {
// Set the view mode to the configured default. // Set the view mode to the configured default.
protected _setViewModeToDefault(): void { protected _setViewModeToDefault(): void {
if (this.config.view_default == "live") { this._viewMode = this.config.view_default;
this._viewMode = FrigateCardView.LIVE; if (["clip", "snapshot"].includes(this._viewMode)) {
} else if (this.config.view_default == "clips") {
this._viewMode = FrigateCardView.CLIPS;
} else if (this.config.view_default == "clip") {
this._viewMode = FrigateCardView.CLIP;
this._viewEvent = null;
} else if (this.config.view_default == "snapshots") {
this._viewMode = FrigateCardView.SNAPSHOTS;
} else if (this.config.view_default == "snapshot") {
this._viewMode = FrigateCardView.SNAPSHOT;
this._viewEvent = null; this._viewEvent = null;
} }
} }
@@ -419,7 +402,7 @@ export class FrigateCard extends LitElement {
// Render Frigate events into a card gallery. // Render Frigate events into a card gallery.
protected async _renderEvents() : Promise<TemplateResult> { protected async _renderEvents() : Promise<TemplateResult> {
const want_clips = this._viewMode == FrigateCardView.CLIPS; const want_clips = (this._viewMode == "clips");
let events; let events;
try { try {
events = await this._getEvents({ events = await this._getEvents({
@@ -446,8 +429,7 @@ export class FrigateCard extends LitElement {
@click=${() => { @click=${() => {
this._showMenu = false; this._showMenu = false;
this._viewEvent = event; this._viewEvent = event;
this._viewMode = want_clips ? this._viewMode = want_clips ? "clip" : "snapshot";
FrigateCardView.CLIP : FrigateCardView.SNAPSHOT;
}} }}
> >
</div> </div>
@@ -525,15 +507,15 @@ export class FrigateCard extends LitElement {
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 = FrigateCardView.LIVE; this._viewMode = name;
break; break;
case "clips": case "clips":
this._controlVideos({stop: true, control_live: true}); this._controlVideos({stop: true, control_live: true});
this._viewMode = FrigateCardView.CLIPS; this._viewMode = name;
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 = FrigateCardView.SNAPSHOTS; this._viewMode = name;
break; break;
case "frigate-ui": case "frigate-ui":
window.open(this.config.frigate_url); window.open(this.config.frigate_url);
@@ -608,7 +590,7 @@ export class FrigateCard extends LitElement {
if (this._webrtcElement) { if (this._webrtcElement) {
return html` return html`
<div <div
class=${this._viewMode == FrigateCardView.LIVE ? 'visible' : 'invisible'} class=${this._viewMode == "live" ? 'visible' : 'invisible'}
> >
${this._webrtcElement} ${this._webrtcElement}
</div>`; </div>`;
@@ -619,7 +601,7 @@ export class FrigateCard extends LitElement {
.stateObj=${this._hass.states[this.config.camera_entity]} .stateObj=${this._hass.states[this.config.camera_entity]}
.controls=${true} .controls=${true}
.muted=${true} .muted=${true}
class=${this._viewMode == FrigateCardView.LIVE ? 'visible' : 'invisible'} class=${this._viewMode == "live" ? 'visible' : 'invisible'}
> >
</ha-camera-stream>`; </ha-camera-stream>`;
} }
@@ -654,22 +636,22 @@ export class FrigateCard extends LitElement {
.actionCallback=${this._menuActionHandler.bind(this)} .actionCallback=${this._menuActionHandler.bind(this)}
> >
</frigate-card-menu> </frigate-card-menu>
${this._viewMode == FrigateCardView.CLIPS ? ${this._viewMode == "clips" ?
html`<div class="frigate-card-gallery"> html`<div class="frigate-card-gallery">
${until(this._renderEvents(), this._renderProgressIndicator())} ${until(this._renderEvents(), this._renderProgressIndicator())}
</div>` : `` </div>` : ``
} }
${this._viewMode == FrigateCardView.SNAPSHOTS ? ${this._viewMode == "snapshots" ?
html`<div class="frigate-card-gallery"> html`<div class="frigate-card-gallery">
${until(this._renderEvents(), this._renderProgressIndicator())} ${until(this._renderEvents(), this._renderProgressIndicator())}
</div>` : `` </div>` : ``
} }
${this._viewMode == FrigateCardView.CLIP ? ${this._viewMode == "clip" ?
html`<div class="frigate-card-viewer"> html`<div class="frigate-card-viewer">
${until(this._renderClipPlayer(), this._renderProgressIndicator())} ${until(this._renderClipPlayer(), this._renderProgressIndicator())}
</div>` : `` </div>` : ``
} }
${this._viewMode == FrigateCardView.SNAPSHOT ? ${this._viewMode == "snapshot" ?
html`<div class="frigate-card-viewer"> html`<div class="frigate-card-viewer">
${until(this._renderSnapshotViewer(), this._renderProgressIndicator())} ${until(this._renderSnapshotViewer(), this._renderProgressIndicator())}
</div>` : `` </div>` : ``
+12 -1
View File
@@ -12,12 +12,23 @@ declare global {
* Internal types. * Internal types.
*/ */
// enum FrigateCardView {
// LIVE = "live", // Show the live camera.
// CLIP = "clip", // Show a clip video.
// CLIPS = "clips", // Show the clips gallery.
// SNAPSHOT = "snapshot", // Show a snapshot.
// SNAPSHOTS = "snapshots", // Show the snapshots gallery.
// }
export const FRIGATE_CARD_VIEWS = ["live", "clip", "clips", "snapshot", "snapshots"] as const;
export type FrigateCardView = typeof FRIGATE_CARD_VIEWS[number];
export const frigateCardConfigSchema = z.object({ export const frigateCardConfigSchema = z.object({
camera_entity: z.string(), camera_entity: z.string(),
motion_entity: z.string().optional(), motion_entity: z.string().optional(),
frigate_url: z.string().url(), frigate_url: z.string().url(),
frigate_camera_name: z.string().optional(), frigate_camera_name: z.string().optional(),
view_default: z.enum(["live", "clips", "clip", "snapshots", "snapshot"]).optional().default("live"), view_default: z.enum(FRIGATE_CARD_VIEWS).optional().default("live"),
view_timeout: z.number().or(z.string().regex(/^\d+$/).transform(val => Number(val))).optional(), view_timeout: z.number().or(z.string().regex(/^\d+$/).transform(val => Number(val))).optional(),
live_provider: z.enum(["frigate", "webrtc"]).default("frigate"), live_provider: z.enum(["frigate", "webrtc"]).default("frigate"),