Handle setTimeout called when tab is shown (#6257)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Paulus Schoutsen 2020-06-29 14:29:05 -07:00 committed by GitHub
parent 7b0e743eca
commit 71faaf2ab1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 46 deletions

View File

@ -76,11 +76,15 @@ export class HomeAssistantAppEl extends HassElement {
// @ts-ignore // @ts-ignore
this._loadHassTranslations(this.hass!.language, "state"); this._loadHassTranslations(this.hass!.language, "state");
this.addEventListener("unsuspend-app", () => this._onVisible(), false);
document.addEventListener( document.addEventListener(
"visibilitychange", "visibilitychange",
() => this._handleVisibilityChange(), () => this._checkVisibility(),
false false
); );
document.addEventListener("freeze", () => this._suspendApp());
document.addEventListener("resume", () => this._checkVisibility());
} }
protected hassReconnected() { protected hassReconnected() {
@ -148,9 +152,19 @@ export class HomeAssistantAppEl extends HassElement {
: route.path.substr(1, dividerPos - 1); : route.path.substr(1, dividerPos - 1);
} }
protected _handleVisibilityChange() { protected _checkVisibility() {
if (document.hidden) { if (document.hidden) {
// If the document is hidden, we will prevent reconnects until we are visible again // If the document is hidden, we will prevent reconnects until we are visible again
this._onHidden();
} else {
this._onVisible();
}
}
private _onHidden() {
if (this._visiblePromiseResolve) {
return;
}
this.hass!.connection.suspendReconnectUntil( this.hass!.connection.suspendReconnectUntil(
new Promise((resolve) => { new Promise((resolve) => {
this._visiblePromiseResolve = resolve; this._visiblePromiseResolve = resolve;
@ -159,9 +173,23 @@ export class HomeAssistantAppEl extends HassElement {
// We close the connection to Home Assistant after being hidden for 5 minutes // We close the connection to Home Assistant after being hidden for 5 minutes
this._hiddenTimeout = window.setTimeout(() => { this._hiddenTimeout = window.setTimeout(() => {
this._hiddenTimeout = undefined; this._hiddenTimeout = undefined;
this.hass!.connection.suspend(); // setTimeout can be delayed in the background and only fire
// when we switch to the tab or app again (Hey Android!)
if (!document.hidden) {
this._suspendApp();
}
}, 300000); }, 300000);
} else { window.addEventListener("focus", () => this._onVisible(), { once: true });
}
private _suspendApp() {
if (!this.hass!.connection.connected) {
return;
}
this.hass!.connection.suspend();
}
private _onVisible() {
// Clear timer to close the connection // Clear timer to close the connection
if (this._hiddenTimeout) { if (this._hiddenTimeout) {
clearTimeout(this._hiddenTimeout); clearTimeout(this._hiddenTimeout);
@ -173,7 +201,6 @@ export class HomeAssistantAppEl extends HassElement {
this._visiblePromiseResolve = undefined; this._visiblePromiseResolve = undefined;
} }
} }
}
} }
declare global { declare global {

View File

@ -99,11 +99,13 @@ class PartialPanelResolver extends HassRouterPage {
protected firstUpdated(changedProps: PropertyValues) { protected firstUpdated(changedProps: PropertyValues) {
super.firstUpdated(changedProps); super.firstUpdated(changedProps);
// Attach listeners for visibility
document.addEventListener( document.addEventListener(
"visibilitychange", "visibilitychange",
() => this._handleVisibilityChange(), () => this._checkVisibility(),
false false
); );
document.addEventListener("resume", () => this._checkVisibility());
} }
protected updated(changedProps: PropertyValues) { protected updated(changedProps: PropertyValues) {
@ -156,10 +158,22 @@ class PartialPanelResolver extends HassRouterPage {
} }
} }
private _handleVisibilityChange() { private _checkVisibility() {
if (document.hidden) { if (document.hidden) {
this._onHidden();
} else {
this._onVisible();
}
}
private _onHidden() {
this._hiddenTimeout = window.setTimeout(() => { this._hiddenTimeout = window.setTimeout(() => {
this._hiddenTimeout = undefined; this._hiddenTimeout = undefined;
// setTimeout can be delayed in the background and only fire
// when we switch to the tab or app again (Hey Android!)
if (!document.hidden) {
return;
}
const curPanel = this.hass.panels[this._currentPage]; const curPanel = this.hass.panels[this._currentPage];
if ( if (
this.lastChild && this.lastChild &&
@ -175,7 +189,10 @@ class PartialPanelResolver extends HassRouterPage {
this.removeChild(this.lastChild); this.removeChild(this.lastChild);
} }
}, 300000); }, 300000);
} else { window.addEventListener("focus", () => this._onVisible(), { once: true });
}
private _onVisible() {
if (this._hiddenTimeout) { if (this._hiddenTimeout) {
clearTimeout(this._hiddenTimeout); clearTimeout(this._hiddenTimeout);
this._hiddenTimeout = undefined; this._hiddenTimeout = undefined;
@ -185,7 +202,6 @@ class PartialPanelResolver extends HassRouterPage {
this._disconnectedPanel = undefined; this._disconnectedPanel = undefined;
} }
} }
}
private async _updateRoutes(oldPanels?: HomeAssistant["panels"]) { private async _updateRoutes(oldPanels?: HomeAssistant["panels"]) {
this.routerOptions = getRoutes(this.hass.panels); this.routerOptions = getRoutes(this.hass.panels);