diff --git a/src/panels/logbook/ha-logbook-renderer.ts b/src/panels/logbook/ha-logbook-renderer.ts index 560cbd1f08..e5384b8778 100644 --- a/src/panels/logbook/ha-logbook-renderer.ts +++ b/src/panels/logbook/ha-logbook-renderer.ts @@ -1,4 +1,5 @@ import "@lit-labs/virtualizer"; +import { VisibilityChangedEvent } from "@lit-labs/virtualizer/Virtualizer"; import { css, CSSResultGroup, @@ -34,6 +35,12 @@ import { import { HomeAssistant } from "../../types"; import { brandsUrl } from "../../util/brands-url"; +declare global { + interface HASSDomEvents { + "hass-logbook-live": { enable: boolean }; + } +} + const triggerDomains = ["script", "automation"]; const hasContext = (item: LogbookEntry) => @@ -102,6 +109,7 @@ class HaLogbookRenderer extends LitElement { > ${this.virtualize ? html` Promise) | void>; + private _liveUpdatesEnabled = true; + + private _pendingStreamMessages: LogbookStreamMessage[] = []; + private _throttleGetLogbookEntries = throttle( () => this._getLogBookData(), 1000 @@ -126,6 +130,7 @@ export class HaLogbook extends LitElement { .entries=${this._logbookEntries} .traceContexts=${this._traceContexts} .userIdToName=${this._userIdToName} + @hass-logbook-live=${this._handleLogbookLive} > `; } @@ -150,6 +155,10 @@ export class HaLogbook extends LitElement { this._throttleGetLogbookEntries(); } + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + } + protected shouldUpdate(changedProps: PropertyValues): boolean { if (changedProps.size !== 1 || !changedProps.has("hass")) { return true; @@ -185,6 +194,17 @@ export class HaLogbook extends LitElement { } } + private _handleLogbookLive(ev: CustomEvent) { + if (ev.detail.enable && !this._liveUpdatesEnabled) { + // Process everything we queued up while we were scrolled down + this._pendingStreamMessages.forEach((msg) => + this._processStreamMessage(msg) + ); + this._pendingStreamMessages = []; + } + this._liveUpdatesEnabled = ev.detail.enable; + } + private get _filterAlwaysEmptyResults(): boolean { const entityIds = ensureArray(this.entityIds); const deviceIds = ensureArray(this.deviceIds); @@ -283,12 +303,7 @@ export class HaLogbook extends LitElement { // Message came in before we had a chance to unload return; } - this._processStreamMessage( - streamMessage, - "recent" in this.time - ? findStartOfRecentTime(new Date(), this.time.recent) - : undefined - ); + this._processOrQueueStreamMessage(streamMessage); }, logbookPeriod.startTime.toISOString(), logbookPeriod.endTime.toISOString(), @@ -334,10 +349,21 @@ export class HaLogbook extends LitElement { ) : this._logbookEntries; - private _processStreamMessage = ( - streamMessage: LogbookStreamMessage, - purgeBeforePythonTime: number | undefined + private _processOrQueueStreamMessage = ( + streamMessage: LogbookStreamMessage ) => { + if (this._liveUpdatesEnabled) { + this._processStreamMessage(streamMessage); + return; + } + this._pendingStreamMessages.push(streamMessage); + }; + + private _processStreamMessage = (streamMessage: LogbookStreamMessage) => { + const purgeBeforePythonTime = + "recent" in this.time + ? findStartOfRecentTime(new Date(), this.time.recent) + : undefined; // Put newest ones on top. Reverse works in-place so // make a copy first. const newEntries = [...streamMessage.events].reverse();