Separate timeout_seconds from refresh_seconds .

This commit is contained in:
Dermot Duffy
2022-01-23 21:01:55 -08:00
parent 1f178fedc2
commit ea9d3b4809
6 changed files with 107 additions and 109 deletions
+67 -38
View File
@@ -151,11 +151,12 @@ export class FrigateCard extends LitElement {
@query('frigate-card-elements')
_elements?: FrigateCardElements;
// Human interaction timer ID.
// Human interaction timer ("screensaver" functionality, return to default
// view after human interaction).
protected _interactionTimerID: number | null = null;
// Whether or not media is actively playing (live or clip).
protected _mediaPlaying = false;
// Automated refreshes of the default view.
protected _updateTimerID: number | null = null;
// Information about the most recently loaded media item.
protected _mediaShowInfo: MediaShowInfo | null = null;
@@ -619,10 +620,6 @@ export class FrigateCard extends LitElement {
this._cameras = undefined;
this._view = undefined;
if (this._getConfig().view.update_force) {
// If update force is enabled, start a timer right away.
this._resetInteractionTimer();
}
this._changeView();
}
@@ -640,6 +637,7 @@ export class FrigateCard extends LitElement {
}
if (args?.view === undefined) {
// Load the default view.
let camera = this._view?.camera;
if (this._cameras?.size) {
if (!camera) {
@@ -658,6 +656,14 @@ export class FrigateCard extends LitElement {
camera: camera,
});
this._generateConditionState();
// The default view has been loaded, so can abandon any running
// 'screensaver' timer.
this._clearInteractionTimer();
// Restart the update timer, so the default view is refreshed at a fixed
// interval from now (if so configured).
this._startUpdateTimer();
}
} else {
this._view = args.view;
@@ -692,8 +698,7 @@ export class FrigateCard extends LitElement {
// Assistant update if there's been recent interaction (e.g. clicks on the
// card) or if there is media active playing.
if (
(this._getConfig().view.update_force ||
!(this._interactionTimerID && this._mediaPlaying)) &&
this._isAutomatedViewUpdateAllowed() &&
shouldUpdateBasedOnHass(
this._hass,
oldHass,
@@ -701,9 +706,8 @@ export class FrigateCard extends LitElement {
)
) {
// If entities being monitored have changed then reset the view to the
// default and allow a re-render. Note that as per the Lit lifecycle,
// the setting of the view itself will not trigger an *additional*
// re-render here.
// default. Note that as per the Lit lifecycle, the setting of the view
// itself will not trigger an *additional* re-render here.
this._changeView();
return true;
}
@@ -891,25 +895,66 @@ export class FrigateCard extends LitElement {
) {
handleAction(node, this._hass as HomeAssistant, config, ev.detail.action);
}
this._resetInteractionTimer();
// Set the 'screensaver' timer.
this._startInteractionTimer();
}
protected _resetInteractionTimer(): void {
/**
* Clear the human interaction ('screensaver') timer.
*/
protected _clearInteractionTimer(): void {
if (this._interactionTimerID) {
window.clearTimeout(this._interactionTimerID);
this._interactionTimerID = null;
}
}
/**
* Start the human interaction ('screensaver') timer to reset the view to
* default `view.timeout_seconds` after human interaction.
*/
protected _startInteractionTimer(): void {
this._clearInteractionTimer();
if (this._getConfig().view.timeout_seconds) {
if (this._interactionTimerID) {
window.clearTimeout(this._interactionTimerID);
}
this._interactionTimerID = window.setTimeout(() => {
this._interactionTimerID = null;
this._changeView();
if (this._getConfig().view.update_force) {
// If force is enabled, the timer just resets and starts over.
this._resetInteractionTimer();
}
}, this._getConfig().view.timeout_seconds * 1000);
}
}
/**
* Set the update timer to trigger an update refresh every
* `view.update_seconds`.
*/
protected _startUpdateTimer(): void {
if (this._updateTimerID) {
window.clearTimeout(this._updateTimerID);
this._updateTimerID = null;
}
if (this._getConfig().view.update_seconds) {
this._updateTimerID = window.setTimeout(() => {
if (this._isAutomatedViewUpdateAllowed()) {
this._changeView();
} else {
// Not allowed to update this time around, but try again at the next
// interval.
this._startUpdateTimer();
}
}, this._getConfig().view.update_seconds * 1000);
}
}
/**
* Determine if an automated view update is allowed.
* @returns `true` if it's allowed, `false` otherwise.
*/
protected _isAutomatedViewUpdateAllowed(): boolean {
return (
this._getConfig().view.update_force || !this._interactionTimerID
);
}
/**
* Render the card menu.
* @returns A rendered template.
@@ -929,20 +974,6 @@ export class FrigateCard extends LitElement {
`;
}
/**
* Handler for media play event.
*/
protected _playHandler(): void {
this._mediaPlaying = true;
}
/**
* Handler for media pause event.
*/
protected _pauseHandler(): void {
this._mediaPlaying = false;
}
/**
* Set the message to display and trigger an update.
* @param message The message to display.
@@ -1115,8 +1146,6 @@ export class FrigateCard extends LitElement {
@frigate-card:message=${this._messageHandler}
@frigate-card:change-view=${this._changeViewHandler}
@frigate-card:media-show=${this._mediaShowHandler}
@frigate-card:pause=${this._pauseHandler}
@frigate-card:play=${this._playHandler}
>
${this._getConfig().menu.mode == 'above' ? this._renderMenu() : ''}
<div class="container outer" style="${styleMap(outerStyle)}">
-16
View File
@@ -114,22 +114,6 @@ export function dispatchFrigateCardEvent<T>(
);
}
/**
* Dispatch a Frigate card play event.
* @param element The element to send the event.
*/
export function dispatchPlayEvent(element: HTMLElement): void {
dispatchFrigateCardEvent(element, 'play');
}
/**
* Dispatch a Frigate card pause event.
* @param element The element to send the event.
*/
export function dispatchPauseEvent(element: HTMLElement): void {
dispatchFrigateCardEvent(element, 'pause');
}
/**
* Create a MediaShowInfo object.
* @param source An event or HTMLElement that should be used as a source.
+1 -25
View File
@@ -40,8 +40,6 @@ import {
dispatchExistingMediaShowInfoAsEvent,
dispatchMediaShowEvent,
dispatchMessageEvent,
dispatchPauseEvent,
dispatchPlayEvent,
getCameraIcon,
getCameraTitle,
homeAssistantSignPath,
@@ -701,7 +699,7 @@ export class FrigateCardLiveWebRTC extends LitElement {
* @returns The player or `null` if not found.
*/
protected _getPlayer(): HTMLVideoElement | null {
return this.renderRoot.querySelector('#video') as HTMLVideoElement | null;
return this.renderRoot?.querySelector('#video') as HTMLVideoElement | null;
}
/**
@@ -763,8 +761,6 @@ export class FrigateCardLiveWebRTC extends LitElement {
const video = this._getPlayer();
if (video) {
const onloadedmetadata = video.onloadedmetadata;
const onplay = video.onplay;
const onpause = video.onpause;
video.onloadedmetadata = (e) => {
if (onloadedmetadata) {
@@ -772,18 +768,6 @@ export class FrigateCardLiveWebRTC extends LitElement {
}
dispatchMediaShowEvent(this, video);
};
video.onplay = (e) => {
if (onplay) {
onplay.call(video, e);
}
dispatchPlayEvent(this);
};
video.onpause = (e) => {
if (onpause) {
onpause.call(video, e);
}
dispatchPauseEvent(this);
};
}
});
}
@@ -864,14 +848,6 @@ export class FrigateCardLiveJSMPEG extends LitElement {
url,
{
canvas: this._jsmpegCanvasElement,
hooks: {
play: () => {
dispatchPlayEvent(this);
},
pause: () => {
dispatchPauseEvent(this);
},
},
},
{
pauseWhenHidden: false,
+1 -8
View File
@@ -12,12 +12,7 @@
import { TemplateResult, css, html } from 'lit';
import { Ref, createRef, ref } from 'lit/directives/ref';
import { customElement } from 'lit/decorators.js';
import {
dispatchMediaShowEvent,
dispatchPauseEvent,
dispatchPlayEvent,
} from '../common.js';
import { dispatchMediaShowEvent } from '../common.js';
customElements.whenDefined('ha-hls-player').then(() => {
@customElement('frigate-card-ha-hls-player')
@@ -54,8 +49,6 @@ customElements.whenDefined('ha-hls-player').then(() => {
@loadeddata=${(e) => {
dispatchMediaShowEvent(this, e);
}}
@pause=${() => dispatchPauseEvent(this)}
@play=${() => dispatchPlayEvent(this)}
></video>
`;
}
+4 -2
View File
@@ -370,7 +370,8 @@ export type PictureElements = z.infer<typeof pictureElementsSchema>;
*/
const viewConfigDefault = {
default: 'live' as const,
timeout: 180,
timeout_seconds: 300,
update_seconds: 0,
update_force: false,
update_cycle_camera: false,
};
@@ -380,7 +381,8 @@ const viewConfigSchema = z
.enum(FRIGATE_CARD_VIEWS_USER_SPECIFIED)
.optional()
.default(viewConfigDefault.default),
timeout_seconds: z.number().default(viewConfigDefault.timeout),
timeout_seconds: z.number().default(viewConfigDefault.timeout_seconds),
update_seconds: z.number().default(viewConfigDefault.update_seconds),
update_force: z.boolean().default(viewConfigDefault.update_force),
update_cycle_camera: z.boolean().default(viewConfigDefault.update_cycle_camera),
update_entities: z.string().array().optional(),