mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 02:06:42 +00:00
Handle setTimeout called when tab is shown (#6257)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
7b0e743eca
commit
71faaf2ab1
@ -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,30 +152,53 @@ 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.hass!.connection.suspendReconnectUntil(
|
this._onHidden();
|
||||||
new Promise((resolve) => {
|
|
||||||
this._visiblePromiseResolve = resolve;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// We close the connection to Home Assistant after being hidden for 5 minutes
|
|
||||||
this._hiddenTimeout = window.setTimeout(() => {
|
|
||||||
this._hiddenTimeout = undefined;
|
|
||||||
this.hass!.connection.suspend();
|
|
||||||
}, 300000);
|
|
||||||
} else {
|
} else {
|
||||||
// Clear timer to close the connection
|
this._onVisible();
|
||||||
if (this._hiddenTimeout) {
|
}
|
||||||
clearTimeout(this._hiddenTimeout);
|
}
|
||||||
this._hiddenTimeout = undefined;
|
|
||||||
}
|
private _onHidden() {
|
||||||
// Unsuspend the reconnect
|
if (this._visiblePromiseResolve) {
|
||||||
if (this._visiblePromiseResolve) {
|
return;
|
||||||
this._visiblePromiseResolve();
|
}
|
||||||
this._visiblePromiseResolve = undefined;
|
this.hass!.connection.suspendReconnectUntil(
|
||||||
|
new Promise((resolve) => {
|
||||||
|
this._visiblePromiseResolve = resolve;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// We close the connection to Home Assistant after being hidden for 5 minutes
|
||||||
|
this._hiddenTimeout = window.setTimeout(() => {
|
||||||
|
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) {
|
||||||
|
this._suspendApp();
|
||||||
}
|
}
|
||||||
|
}, 300000);
|
||||||
|
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
|
||||||
|
if (this._hiddenTimeout) {
|
||||||
|
clearTimeout(this._hiddenTimeout);
|
||||||
|
this._hiddenTimeout = undefined;
|
||||||
|
}
|
||||||
|
// Unsuspend the reconnect
|
||||||
|
if (this._visiblePromiseResolve) {
|
||||||
|
this._visiblePromiseResolve();
|
||||||
|
this._visiblePromiseResolve = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,34 +158,48 @@ class PartialPanelResolver extends HassRouterPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleVisibilityChange() {
|
private _checkVisibility() {
|
||||||
if (document.hidden) {
|
if (document.hidden) {
|
||||||
this._hiddenTimeout = window.setTimeout(() => {
|
this._onHidden();
|
||||||
this._hiddenTimeout = undefined;
|
|
||||||
const curPanel = this.hass.panels[this._currentPage];
|
|
||||||
if (
|
|
||||||
this.lastChild &&
|
|
||||||
// iFrames will lose their state when disconnected
|
|
||||||
// Do not disconnect any iframe panel
|
|
||||||
curPanel.component_name !== "iframe" &&
|
|
||||||
// Do not disconnect any custom panel that embeds into iframe (ie hassio)
|
|
||||||
(curPanel.component_name !== "custom" ||
|
|
||||||
!(curPanel.config as CustomPanelInfo).config._panel_custom
|
|
||||||
.embed_iframe)
|
|
||||||
) {
|
|
||||||
this._disconnectedPanel = this.lastChild;
|
|
||||||
this.removeChild(this.lastChild);
|
|
||||||
}
|
|
||||||
}, 300000);
|
|
||||||
} else {
|
} else {
|
||||||
if (this._hiddenTimeout) {
|
this._onVisible();
|
||||||
clearTimeout(this._hiddenTimeout);
|
}
|
||||||
this._hiddenTimeout = undefined;
|
}
|
||||||
|
|
||||||
|
private _onHidden() {
|
||||||
|
this._hiddenTimeout = window.setTimeout(() => {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
if (this._disconnectedPanel) {
|
const curPanel = this.hass.panels[this._currentPage];
|
||||||
this.appendChild(this._disconnectedPanel);
|
if (
|
||||||
this._disconnectedPanel = undefined;
|
this.lastChild &&
|
||||||
|
// iFrames will lose their state when disconnected
|
||||||
|
// Do not disconnect any iframe panel
|
||||||
|
curPanel.component_name !== "iframe" &&
|
||||||
|
// Do not disconnect any custom panel that embeds into iframe (ie hassio)
|
||||||
|
(curPanel.component_name !== "custom" ||
|
||||||
|
!(curPanel.config as CustomPanelInfo).config._panel_custom
|
||||||
|
.embed_iframe)
|
||||||
|
) {
|
||||||
|
this._disconnectedPanel = this.lastChild;
|
||||||
|
this.removeChild(this.lastChild);
|
||||||
}
|
}
|
||||||
|
}, 300000);
|
||||||
|
window.addEventListener("focus", () => this._onVisible(), { once: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onVisible() {
|
||||||
|
if (this._hiddenTimeout) {
|
||||||
|
clearTimeout(this._hiddenTimeout);
|
||||||
|
this._hiddenTimeout = undefined;
|
||||||
|
}
|
||||||
|
if (this._disconnectedPanel) {
|
||||||
|
this.appendChild(this._disconnectedPanel);
|
||||||
|
this._disconnectedPanel = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user