Converge view mode lists.
This commit is contained in:
+18
-18
@@ -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
@@ -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,18 +287,9 @@ 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;
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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
@@ -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"),
|
||||||
|
|||||||
Reference in New Issue
Block a user