From dfc6a8ad169498ece5fc910a155ee815da431b33 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 7 Nov 2023 19:43:38 +0000 Subject: [PATCH 1/2] Notification toggle --- ...gle.js => ha-push-notifications-toggle.ts} | 80 +++++++--------- .../profile/ha-push-notifications-row.js | 91 ------------------- .../profile/ha-push-notifications-row.ts | 72 +++++++++++++++ 3 files changed, 107 insertions(+), 136 deletions(-) rename src/components/{ha-push-notifications-toggle.js => ha-push-notifications-toggle.ts} (69%) delete mode 100644 src/panels/profile/ha-push-notifications-row.js create mode 100644 src/panels/profile/ha-push-notifications-row.ts diff --git a/src/components/ha-push-notifications-toggle.js b/src/components/ha-push-notifications-toggle.ts similarity index 69% rename from src/components/ha-push-notifications-toggle.js rename to src/components/ha-push-notifications-toggle.ts index dfb876b9a750..350ac6320503 100644 --- a/src/components/ha-push-notifications-toggle.js +++ b/src/components/ha-push-notifications-toggle.ts @@ -1,10 +1,10 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; +import { LitElement, TemplateResult, html } from "lit"; +import { customElement, property } from "lit/decorators"; import { getAppKey } from "../data/notify_html5"; import { showPromptDialog } from "../dialogs/generic/show-dialog-box"; -import { EventsMixin } from "../mixins/events-mixin"; -import "./ha-switch"; +import { HaSwitch } from "./ha-switch"; +import { HomeAssistant } from "../types"; +import { fireEvent } from "../common/dom/fire_event"; export const pushSupported = "serviceWorker" in navigator && @@ -13,39 +13,27 @@ export const pushSupported = document.location.hostname === "localhost" || document.location.hostname === "127.0.0.1"); -/* - * @appliesMixin EventsMixin - */ -class HaPushNotificationsToggle extends EventsMixin(PolymerElement) { - static get template() { +@customElement("ha-push-notifications-toggle") +class HaPushNotificationsToggle extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public disabled: boolean = false; + + @property() public pushChecked: boolean = + "Notification" in window && Notification.permission === "granted"; + + @property() public loading: boolean = true; + + protected render(): TemplateResult { return html` `; } - static get properties() { - return { - hass: { type: Object, value: null }, - disabled: { - type: Boolean, - value: false, - }, - pushChecked: { - type: Boolean, - value: - "Notification" in window && Notification.permission === "granted", - }, - loading: { - type: Boolean, - value: true, - }, - }; - } - async connectedCallback() { super.connectedCallback(); @@ -65,12 +53,13 @@ class HaPushNotificationsToggle extends EventsMixin(PolymerElement) { } } - handlePushChange(event) { + private _handlePushChange(ev: Event) { // Somehow this is triggered on Safari on page load causing // it to get into a loop and crash the page. if (!pushSupported) return; - if (event.target.checked) { + const pushnotifications = (ev.target as HaSwitch).checked; + if (pushnotifications) { this.subscribePushNotifications(); } else { this.unsubscribePushNotifications(); @@ -82,7 +71,7 @@ class HaPushNotificationsToggle extends EventsMixin(PolymerElement) { let sub; try { - let browserName; + let browserName: string; if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1) { browserName = "firefox"; } else { @@ -102,7 +91,7 @@ class HaPushNotificationsToggle extends EventsMixin(PolymerElement) { return; } - let applicationServerKey; + let applicationServerKey: Uint8Array | null; try { applicationServerKey = await getAppKey(this.hass); } catch (ex) { @@ -123,7 +112,7 @@ class HaPushNotificationsToggle extends EventsMixin(PolymerElement) { browser: browserName, name, }); - } catch (err) { + } catch (err: any) { const message = err.message || "Notification registration failed."; if (sub) { await sub.unsubscribe(); @@ -132,7 +121,7 @@ class HaPushNotificationsToggle extends EventsMixin(PolymerElement) { // eslint-disable-next-line console.error(err); - this.fire("hass-notification", { message }); + fireEvent(this, "hass-notification", { message }); this.pushChecked = false; } } @@ -147,24 +136,25 @@ class HaPushNotificationsToggle extends EventsMixin(PolymerElement) { await this.hass.callApi("DELETE", "notify.html5", { subscription: sub }); await sub.unsubscribe(); - } catch (err) { + } catch (err: any) { const message = err.message || "Failed unsubscribing for push notifications."; // eslint-disable-next-line console.error("Error in unsub push", err); - this.fire("hass-notification", { message }); + fireEvent(this, "hass-notification", { message }); this.pushChecked = true; } } - _compDisabled(disabled, loading) { + private _compDisabled(disabled: boolean, loading: boolean) { return disabled || loading; } } -customElements.define( - "ha-push-notifications-toggle", - HaPushNotificationsToggle -); +declare global { + interface HTMLElementTagNameMap { + "ha-push-notifications-toggle": HaPushNotificationsToggle; + } +} diff --git a/src/panels/profile/ha-push-notifications-row.js b/src/panels/profile/ha-push-notifications-row.js deleted file mode 100644 index 69f2e5424656..000000000000 --- a/src/panels/profile/ha-push-notifications-row.js +++ /dev/null @@ -1,91 +0,0 @@ -import "@polymer/iron-flex-layout/iron-flex-layout-classes"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import { isComponentLoaded } from "../../common/config/is_component_loaded"; -import { pushSupported } from "../../components/ha-push-notifications-toggle"; -import "../../components/ha-settings-row"; -import LocalizeMixin from "../../mixins/localize-mixin"; -import { documentationUrl } from "../../util/documentation-url"; - -/* - * @appliesMixin LocalizeMixin - */ -class HaPushNotificationsRow extends LocalizeMixin(PolymerElement) { - static get template() { - return html` - - - [[localize('ui.panel.profile.push_notifications.header')]] - - [[localize(_descrLocalizeKey)]] - [[localize('ui.panel.profile.push_notifications.link_promo')]] - - - - `; - } - - static get properties() { - return { - hass: Object, - narrow: Boolean, - _descrLocalizeKey: { - type: String, - computed: "_descriptionKey(_platformLoaded, _pushSupported)", - }, - _platformLoaded: { - type: Boolean, - computed: "_compPlatformLoaded(hass)", - }, - _pushSupported: { - type: Boolean, - value: pushSupported, - }, - _error: { - type: Boolean, - computed: "_compError(_platformLoaded, _pushSupported)", - }, - }; - } - - _computeDocumentationUrl(hass) { - return documentationUrl(hass, "/integrations/html5"); - } - - _compPlatformLoaded(hass) { - return isComponentLoaded(hass, "notify.html5"); - } - - _compError(platformLoaded, pushSupported_) { - return !platformLoaded || !pushSupported_; - } - - _descriptionKey(platformLoaded, pushSupported_) { - let key; - if (!pushSupported_) { - key = "error_use_https"; - } else if (!platformLoaded) { - key = "error_load_platform"; - } else { - key = "description"; - } - return `ui.panel.profile.push_notifications.${key}`; - } -} - -customElements.define("ha-push-notifications-row", HaPushNotificationsRow); diff --git a/src/panels/profile/ha-push-notifications-row.ts b/src/panels/profile/ha-push-notifications-row.ts new file mode 100644 index 000000000000..92b2fc546f4c --- /dev/null +++ b/src/panels/profile/ha-push-notifications-row.ts @@ -0,0 +1,72 @@ +import { LitElement, TemplateResult, css, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import { isComponentLoaded } from "../../common/config/is_component_loaded"; +import { pushSupported } from "../../components/ha-push-notifications-toggle"; +import "../../components/ha-settings-row"; +import { documentationUrl } from "../../util/documentation-url"; +import { HomeAssistant } from "../../types"; + +@customElement("ha-push-notifications-row") +class HaPushNotificationsRow extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public narrow!: boolean; + + protected render(): TemplateResult { + const platformLoaded = isComponentLoaded(this.hass, "notify.html5"); + let descriptionKey: + | "error_use_https" + | "error_load_platform" + | "description"; + if (!pushSupported) { + descriptionKey = "error_use_https"; + } else if (!platformLoaded) { + descriptionKey = "error_load_platform"; + } else { + descriptionKey = "description"; + } + + const isDisabled = !platformLoaded || !pushSupported; + + return html` + + ${this.hass.localize( + "ui.panel.profile.push_notifications.header" + )} + + ${this.hass.localize( + `ui.panel.profile.push_notifications.${descriptionKey}` + )} + ${this.hass.localize( + "ui.panel.profile.push_notifications.link_promo" + )} + + + + `; + } + + static get styles() { + return css` + a { + color: var(--primary-color); + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-push-notifications-row": HaPushNotificationsRow; + } +} From 0603d885a7c5d463d78017086274b29f7475fd9a Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 8 Nov 2023 17:57:59 +0000 Subject: [PATCH 2/2] private functions --- .../ha-push-notifications-toggle.ts | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/components/ha-push-notifications-toggle.ts b/src/components/ha-push-notifications-toggle.ts index 350ac6320503..2dfc895d744e 100644 --- a/src/components/ha-push-notifications-toggle.ts +++ b/src/components/ha-push-notifications-toggle.ts @@ -1,5 +1,5 @@ import { LitElement, TemplateResult, html } from "lit"; -import { customElement, property } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { getAppKey } from "../data/notify_html5"; import { showPromptDialog } from "../dialogs/generic/show-dialog-box"; import { HaSwitch } from "./ha-switch"; @@ -17,18 +17,18 @@ export const pushSupported = class HaPushNotificationsToggle extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property() public disabled: boolean = false; + @state() private _disabled: boolean = false; - @property() public pushChecked: boolean = + @state() private _pushChecked: boolean = "Notification" in window && Notification.permission === "granted"; - @property() public loading: boolean = true; + @state() private _loading: boolean = true; protected render(): TemplateResult { return html` `; @@ -45,8 +45,8 @@ class HaPushNotificationsToggle extends LitElement { return; } reg.pushManager.getSubscription().then((subscription) => { - this.loading = false; - this.pushChecked = !!subscription; + this._loading = false; + this._pushChecked = !!subscription; }); } catch (err) { // We don't set loading to `false` so we remain disabled @@ -60,13 +60,13 @@ class HaPushNotificationsToggle extends LitElement { const pushnotifications = (ev.target as HaSwitch).checked; if (pushnotifications) { - this.subscribePushNotifications(); + this._subscribePushNotifications(); } else { - this.unsubscribePushNotifications(); + this._unsubscribePushNotifications(); } } - async subscribePushNotifications() { + private async _subscribePushNotifications() { const reg = await navigator.serviceWorker.ready; let sub; @@ -87,7 +87,7 @@ class HaPushNotificationsToggle extends LitElement { ), }); if (name == null) { - this.pushChecked = false; + this._pushChecked = false; return; } @@ -122,11 +122,11 @@ class HaPushNotificationsToggle extends LitElement { console.error(err); fireEvent(this, "hass-notification", { message }); - this.pushChecked = false; + this._pushChecked = false; } } - async unsubscribePushNotifications() { + private async _unsubscribePushNotifications() { const reg = await navigator.serviceWorker.ready; try { @@ -144,13 +144,9 @@ class HaPushNotificationsToggle extends LitElement { console.error("Error in unsub push", err); fireEvent(this, "hass-notification", { message }); - this.pushChecked = true; + this._pushChecked = true; } } - - private _compDisabled(disabled: boolean, loading: boolean) { - return disabled || loading; - } } declare global {