diff --git a/src/fake_data/provide_hass.ts b/src/fake_data/provide_hass.ts index 039ed4085e..c5d015b14f 100644 --- a/src/fake_data/provide_hass.ts +++ b/src/fake_data/provide_hass.ts @@ -203,6 +203,7 @@ export const provideHass = ( translationMetadata: translationMetadata as any, dockedSidebar: "auto", vibrate: true, + suspendWhenHidden: false, moreInfoEntityId: null as any, // @ts-ignore async callService(domain, service, data) { diff --git a/src/layouts/home-assistant.ts b/src/layouts/home-assistant.ts index 667af80170..d4ea24beab 100644 --- a/src/layouts/home-assistant.ts +++ b/src/layouts/home-assistant.ts @@ -11,6 +11,7 @@ import { } from "../util/register-service-worker"; import "./ha-init-page"; import "./home-assistant-main"; +import { storeState } from "../util/ha-pref-storage"; @customElement("home-assistant") export class HomeAssistantAppEl extends HassElement { @@ -55,6 +56,10 @@ export class HomeAssistantAppEl extends HassElement { import( /* webpackChunkName: "polyfill-web-animations-next" */ "web-animations-js/web-animations-next-lite.min" ); + this.addEventListener("hass-suspend-when-hidden", (ev) => { + this._updateHass({ suspendWhenHidden: ev.detail.suspend }); + storeState(this.hass!); + }); } protected updated(changedProps: PropertyValues): void { @@ -76,8 +81,6 @@ export class HomeAssistantAppEl extends HassElement { // @ts-ignore this._loadHassTranslations(this.hass!.language, "state"); - this.addEventListener("unsuspend-app", () => this._onVisible(), false); - document.addEventListener( "visibilitychange", () => this._checkVisibility(), @@ -170,15 +173,17 @@ export class HomeAssistantAppEl extends HassElement { 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); + if (this.hass!.suspendWhenHidden !== false) { + // 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 }); } diff --git a/src/layouts/partial-panel-resolver.ts b/src/layouts/partial-panel-resolver.ts index a2db064c91..0d9838cb19 100644 --- a/src/layouts/partial-panel-resolver.ts +++ b/src/layouts/partial-panel-resolver.ts @@ -162,6 +162,10 @@ class PartialPanelResolver extends HassRouterPage { } private _checkVisibility() { + if (this.hass.suspendWhenHidden === false) { + return; + } + if (document.hidden) { this._onHidden(); } else { diff --git a/src/panels/profile/ha-panel-profile.ts b/src/panels/profile/ha-panel-profile.ts index 4f8d07e584..e5837150f4 100644 --- a/src/panels/profile/ha-panel-profile.ts +++ b/src/panels/profile/ha-panel-profile.ts @@ -35,6 +35,7 @@ import "./ha-pick-theme-row"; import "./ha-push-notifications-row"; import "./ha-refresh-tokens-card"; import "./ha-set-vibrate-row"; +import "./ha-set-suspend-row"; class HaPanelProfile extends LitElement { @property() public hass!: HomeAssistant; @@ -137,6 +138,10 @@ class HaPanelProfile extends LitElement { > ` : ""} +
diff --git a/src/panels/profile/ha-set-suspend-row.ts b/src/panels/profile/ha-set-suspend-row.ts new file mode 100644 index 0000000000..d4c4d30b69 --- /dev/null +++ b/src/panels/profile/ha-set-suspend-row.ts @@ -0,0 +1,65 @@ +import { + customElement, + html, + LitElement, + property, + TemplateResult, +} from "lit-element"; +import { fireEvent, HASSDomEvent } from "../../common/dom/fire_event"; +import "../../components/ha-switch"; +import type { HaSwitch } from "../../components/ha-switch"; +import type { HomeAssistant } from "../../types"; +import "./ha-settings-row"; + +declare global { + // for fire event + interface HASSDomEvents { + "hass-suspend-when-hidden": { suspend: HomeAssistant["suspendWhenHidden"] }; + } + // for add event listener + interface HTMLElementEventMap { + "hass-suspend-when-hidden": HASSDomEvent<{ + suspend: HomeAssistant["suspendWhenHidden"]; + }>; + } +} + +@customElement("ha-set-suspend-row") +class HaSetSuspendRow extends LitElement { + @property() public hass!: HomeAssistant; + + @property() public narrow!: boolean; + + protected render(): TemplateResult { + return html` + + + ${this.hass.localize("ui.panel.profile.suspend.header")} + + + ${this.hass.localize("ui.panel.profile.suspend.description")} + + + + `; + } + + private async _checkedChanged(ev: Event) { + const suspend = (ev.target as HaSwitch).checked; + if (suspend === this.hass.suspendWhenHidden) { + return; + } + fireEvent(this, "hass-suspend-when-hidden", { + suspend, + }); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-set-suspend-row": HaSetSuspendRow; + } +} diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts index 43496426a8..a5bb5daa2b 100644 --- a/src/state/connection-mixin.ts +++ b/src/state/connection-mixin.ts @@ -47,6 +47,7 @@ export const connectionMixin = >( translationMetadata, dockedSidebar: "docked", vibrate: true, + suspendWhenHidden: true, moreInfoEntityId: null, hassUrl: (path = "") => new URL(path, auth.data.hassUrl).toString(), callService: async (domain, service, serviceData = {}) => { diff --git a/src/translations/en.json b/src/translations/en.json index aa8e417707..fab0367798 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2106,6 +2106,10 @@ "header": "Vibrate", "description": "Enable or disable vibration on this device when controlling devices." }, + "suspend": { + "header": "Automatically close connection", + "description": "Should we close the connection to the server after being hidden for 5 minutes?" + }, "push_notifications": { "header": "Push Notifications", "description": "Send notifications to this device.", diff --git a/src/types.ts b/src/types.ts index aff205c13b..31684b0bb7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -209,7 +209,7 @@ export interface HomeAssistant { resources: Resources; localize: LocalizeFunc; translationMetadata: TranslationMetadata; - + suspendWhenHidden: boolean; vibrate: boolean; dockedSidebar: "docked" | "always_hidden" | "auto"; defaultPanel: string; diff --git a/src/util/ha-pref-storage.ts b/src/util/ha-pref-storage.ts index ac5319bfa6..404aabb0d9 100644 --- a/src/util/ha-pref-storage.ts +++ b/src/util/ha-pref-storage.ts @@ -5,6 +5,7 @@ const STORED_STATE = [ "selectedTheme", "selectedLanguage", "vibrate", + "suspendWhenHidden", "defaultPanel", ]; const STORAGE = window.localStorage || {};