From 5547bc7356a5f4cccc437d7cac6583ee05d0b343 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 26 Mar 2024 20:53:05 +0100 Subject: [PATCH] Add question based matter commissioning flow (#20188) * Create add device dialog * Add translations and shared design * Disable add buttons when no code * Use right endpoint * Add loading state * Update logos * Add native flow * Add store links to download app * Always display qr code and link * Update translations * Share assets and translations with app dialog --- public/static/images/appstore.svg | 1 + public/static/images/logo_apple_home.png | Bin 0 -> 19245 bytes public/static/images/logo_google_home.png | Bin 0 -> 8785 bytes public/static/images/playstore.svg | 1 + public/static/images/qr-appstore.svg | 1 + public/static/images/qr-playstore.svg | 1 + src/onboarding/dialogs/app-dialog.ts | 6743 +---------------- .../matter/dialog-matter-add-device.ts | 211 +- .../matter-add-device-apple-home.ts | 80 + .../matter-add-device-commissioning.ts | 47 + .../matter-add-device-existing.ts | 123 + .../matter-add-device-generic.ts | 48 + .../matter-add-device-google-home-fallback.ts | 85 + .../matter-add-device-google-home.ts | 82 + .../matter-add-device-main.ts | 80 + .../matter-add-device-new.ts | 113 + .../matter-add-device-shared-styles.ts | 35 + src/translations/en.json | 71 +- 18 files changed, 991 insertions(+), 6731 deletions(-) create mode 100644 public/static/images/appstore.svg create mode 100644 public/static/images/logo_apple_home.png create mode 100644 public/static/images/logo_google_home.png create mode 100644 public/static/images/playstore.svg create mode 100644 public/static/images/qr-appstore.svg create mode 100644 public/static/images/qr-playstore.svg create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-apple-home.ts create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-commissioning.ts create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-existing.ts create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-generic.ts create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home-fallback.ts create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home.ts create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-main.ts create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-new.ts create mode 100644 src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-shared-styles.ts diff --git a/public/static/images/appstore.svg b/public/static/images/appstore.svg new file mode 100644 index 0000000000..da50ed4ce7 --- /dev/null +++ b/public/static/images/appstore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/images/logo_apple_home.png b/public/static/images/logo_apple_home.png new file mode 100644 index 0000000000000000000000000000000000000000..b37416b56b0cf43b13f04cc978328f0a77269715 GIT binary patch literal 19245 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

Y0WUmJ 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 YmJV`9F7R6+z%E2a0xDi4s_XTC07M0uRR910 literal 0 HcmV?d00001 diff --git a/public/static/images/logo_google_home.png b/public/static/images/logo_google_home.png new file mode 100644 index 0000000000000000000000000000000000000000..1658b336f48cf500b3cb2fbd8a58a63130b72827 GIT binary patch literal 8785 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 \ No newline at end of file diff --git a/public/static/images/qr-appstore.svg b/public/static/images/qr-appstore.svg new file mode 100644 index 0000000000..3c6605bb8d --- /dev/null +++ b/public/static/images/qr-appstore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/static/images/qr-playstore.svg b/public/static/images/qr-playstore.svg new file mode 100644 index 0000000000..af088506ae --- /dev/null +++ b/public/static/images/qr-playstore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/onboarding/dialogs/app-dialog.ts b/src/onboarding/dialogs/app-dialog.ts index 3f66189792..1dd5675cc1 100644 --- a/src/onboarding/dialogs/app-dialog.ts +++ b/src/onboarding/dialogs/app-dialog.ts @@ -27,6696 +27,47 @@ class DialogApp extends LitElement { @closed=${this.closeDialog} .heading=${createCloseHeading( undefined, - this.localize("ui.panel.page-onboarding.welcome.download_app") + this.localize("ui.panel.page-onboarding.welcome.download_app") || + "Click here to download the app" )} >

- - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
`; } @@ -6725,31 +76,19 @@ class DialogApp extends LitElement { ha-dialog { --mdc-dialog-min-width: min(500px, 90vw); } - div { + .app-qr { + margin: 24px auto 0 auto; display: flex; justify-content: space-between; - } - a:first-child { - margin-right: 16px; - margin-inline-end: 16px; - margin-inline-start: initial; - } - svg { + padding: 0 24px; + box-sizing: border-box; + gap: 16px; width: 100%; + max-width: 400px; } - .light { - fill: var(--card-background-color); - } - .dark { - fill: var(--primary-text-color); - } - @media (prefers-color-scheme: dark) { - .mask { - fill: var(--primary-text-color); - } - .logo { - filter: invert(100%); - } + .app-qr a, + .app-qr img { + flex: 1; } `; } diff --git a/src/panels/config/integrations/integration-panels/matter/dialog-matter-add-device.ts b/src/panels/config/integrations/integration-panels/matter/dialog-matter-add-device.ts index ed14994f2c..55a5165ffd 100644 --- a/src/panels/config/integrations/integration-panels/matter/dialog-matter-add-device.ts +++ b/src/panels/config/integrations/integration-panels/matter/dialog-matter-add-device.ts @@ -1,17 +1,56 @@ -import "@material/mwc-button/mwc-button"; +import { mdiClose } from "@mdi/js"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { dynamicElement } from "../../../../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../../../../common/dom/fire_event"; -import "../../../../../components/ha-circular-progress"; -import { createCloseHeading } from "../../../../../components/ha-dialog"; +import "../../../../../components/ha-dialog-header"; +import "../../../../../components/ha-icon-button"; +import "../../../../../components/ha-icon-button-arrow-prev"; import { - addMatterDevice, - canCommissionMatterExternal, + commissionMatterDevice, redirectOnNewMatterDevice, } from "../../../../../data/matter"; import { haStyleDialog } from "../../../../../resources/styles"; import { HomeAssistant } from "../../../../../types"; +import "./matter-add-device/matter-add-device-apple-home"; +import "./matter-add-device/matter-add-device-existing"; +import "./matter-add-device/matter-add-device-generic"; +import "./matter-add-device/matter-add-device-google-home"; +import "./matter-add-device/matter-add-device-google-home-fallback"; +import "./matter-add-device/matter-add-device-main"; +import "./matter-add-device/matter-add-device-new"; +import "./matter-add-device/matter-add-device-commissioning"; +import { showToast } from "../../../../../util/toast"; + +export type MatterAddDeviceStep = + | "main" + | "new" + | "existing" + | "google_home" + | "google_home_fallback" + | "apple_home" + | "generic" + | "commissioning"; + +declare global { + interface HASSDomEvents { + "step-selected": { step: MatterAddDeviceStep }; + "pairing-code-changed": { code: string }; + } +} + +const BACK_STEP: Record = + { + main: undefined, + new: "main", + existing: "main", + google_home: "existing", + google_home_fallback: "google_home", + apple_home: "existing", + generic: "existing", + commissioning: undefined, + }; @customElement("dialog-matter-add-device") class DialogMatterAddDevice extends LitElement { @@ -19,50 +58,145 @@ class DialogMatterAddDevice extends LitElement { @state() private _open = false; + @state() _pairingCode = ""; + + @state() _step: MatterAddDeviceStep = "main"; + private _unsub?: UnsubscribeFunc; public showDialog(): void { this._open = true; - if (!canCommissionMatterExternal(this.hass)) { - return; - } this._unsub = redirectOnNewMatterDevice(this.hass, () => this.closeDialog() ); - addMatterDevice(this.hass); } public closeDialog(): void { this._open = false; + this._step = "main"; + this._pairingCode = ""; this._unsub?.(); this._unsub = undefined; fireEvent(this, "dialog-closed", { dialog: this.localName }); } + private _handleStepSelected(ev: CustomEvent) { + this._step = ev.detail.step; + this._pairingCode = ""; + } + + private _handlePairingCodeChanged(ev: CustomEvent) { + this._pairingCode = ev.detail.code; + } + + private _back() { + const backStep = BACK_STEP[this._step]; + if (!backStep) return; + this._step = backStep; + } + + private _renderStep() { + return html` +
+ ${dynamicElement( + `matter-add-device-${this._step.replaceAll("_", "-")}`, + { + hass: this.hass, + } + )} +
+ `; + } + + private async _addDevice() { + const code = this._pairingCode; + const savedStep = this._step; + try { + this._step = "commissioning"; + await commissionMatterDevice(this.hass, code); + } catch (err) { + showToast(this, { + message: this.hass.localize( + "ui.dialogs.matter-add-device.add_device_failed" + ), + duration: 2000, + }); + } + this._step = savedStep; + } + + private _renderActions() { + if ( + this._step === "apple_home" || + this._step === "google_home_fallback" || + this._step === "generic" + ) { + return html` + + ${this.hass.localize("ui.dialogs.matter-add-device.add_device")} + + `; + } + if (this._step === "new") { + return html` + + ${this.hass.localize("ui.common.ok")} + + `; + } + return nothing; + } + protected render() { if (!this._open) { return nothing; } + const title = this.hass.localize( + `ui.dialogs.matter-add-device.${this._step}.header` + ); + + const hasBackStep = BACK_STEP[this._step]; + + const actions = this._renderActions(); + return html` -
- ${!canCommissionMatterExternal(this.hass) - ? this.hass.localize( - "ui.panel.config.integrations.config_flow.matter_mobile_app" - ) - : html``} -
- - ${this.hass.localize("ui.common.cancel")} - + + ${hasBackStep + ? html` + + ` + : html` + + `} + ${title} + + ${this._renderStep()} ${actions}
`; } @@ -70,11 +204,34 @@ class DialogMatterAddDevice extends LitElement { static styles = [ haStyleDialog, css` - div { - display: grid; + :host { + --horizontal-padding: 24px; } - ha-circular-progress { - justify-self: center; + ha-dialog { + --dialog-content-padding: 0; + } + ha-dialog { + --mdc-dialog-min-width: 450px; + --mdc-dialog-max-width: 450px; + } + @media all and (max-width: 450px), all and (max-height: 500px) { + :host { + --horizontal-padding: 16px; + } + ha-dialog { + --mdc-dialog-min-width: calc( + 100vw - env(safe-area-inset-right) - env(safe-area-inset-left) + ); + --mdc-dialog-max-width: calc( + 100vw - env(safe-area-inset-right) - env(safe-area-inset-left) + ); + } + } + .loading { + padding: 24px; + display: flex; + align-items: center; + justify-content: center; } `, ]; diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-apple-home.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-apple-home.ts new file mode 100644 index 0000000000..f8dbef454c --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-apple-home.ts @@ -0,0 +1,80 @@ +import { LitElement, html } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../../../../../common/dom/fire_event"; +import "../../../../../../components/ha-icon-next"; +import "../../../../../../components/ha-list-item-new"; +import "../../../../../../components/ha-list-new"; +import { HomeAssistant } from "../../../../../../types"; +import { sharedStyles } from "./matter-add-device-shared-styles"; + +@customElement("matter-add-device-apple-home") +class MatterAddDeviceAppleHome extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @state() private _code: string = ""; + + render() { + return html` +
+
    +
  1. + ${this.hass.localize( + "ui.dialogs.matter-add-device.apple_home.step_1", + { + accessory_details: html`${this.hass.localize( + "ui.dialogs.matter-add-device.apple_home.accessory_details" + )}`, + } + )} +
  2. +
  3. + ${this.hass.localize( + "ui.dialogs.matter-add-device.apple_home.step_2", + { + turn_on_pairing_mode: html`${this.hass.localize( + "ui.dialogs.matter-add-device.apple_home.turn_on_pairing_mode" + )}`, + } + )} +
  4. +
  5. + ${this.hass.localize( + "ui.dialogs.matter-add-device.apple_home.step_3" + )} +
  6. +
+
+

+ ${this.hass.localize( + "ui.dialogs.matter-add-device.apple_home.code_instructions" + )} +

+ +
+ `; + } + + private _onCodeChanged(ev: any) { + const value = ev.currentTarget.value; + this._code = value; + fireEvent(this, "pairing-code-changed", { code: value }); + } + + static styles = [sharedStyles]; +} + +declare global { + interface HTMLElementTagNameMap { + "matter-add-device-apple-home": MatterAddDeviceAppleHome; + } +} diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-commissioning.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-commissioning.ts new file mode 100644 index 0000000000..b7825e1174 --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-commissioning.ts @@ -0,0 +1,47 @@ +import { LitElement, css, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import { HomeAssistant } from "../../../../../../types"; +import { sharedStyles } from "./matter-add-device-shared-styles"; +import "../../../../../../components/ha-circular-progress"; + +@customElement("matter-add-device-commissioning") +class MatterAddDeviceCommissioning extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + render() { + return html` +
+ +

+ ${this.hass.localize( + "ui.dialogs.matter-add-device.commissioning.note" + )} +

+
+ `; + } + + static styles = [ + sharedStyles, + css` + .content { + display: flex; + align-items: center; + flex-direction: column; + text-align: center; + } + ha-circular-progress { + margin-bottom: 24px; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "matter-add-device-commissioning": MatterAddDeviceCommissioning; + } +} diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-existing.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-existing.ts new file mode 100644 index 0000000000..bbef0c0e94 --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-existing.ts @@ -0,0 +1,123 @@ +import { mdiHomeAutomation } from "@mdi/js"; +import { LitElement, css, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import { fireEvent } from "../../../../../../common/dom/fire_event"; +import "../../../../../../components/ha-icon-next"; +import "../../../../../../components/ha-list-item-new"; +import "../../../../../../components/ha-list-new"; +import { HomeAssistant } from "../../../../../../types"; +import { MatterAddDeviceStep } from "../dialog-matter-add-device"; +import { sharedStyles } from "./matter-add-device-shared-styles"; + +@customElement("matter-add-device-existing") +class MatterAddDeviceExisting extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + render() { + return html` +
+

+ ${this.hass.localize( + `ui.dialogs.matter-add-device.existing.question` + )} +

+
+ + + + + + ${this.hass.localize( + `ui.dialogs.matter-add-device.existing.answer_google_home` + )} + + + + + + + ${this.hass.localize( + `ui.dialogs.matter-add-device.existing.answer_apple_home` + )} + + + + + + + ${this.hass.localize( + `ui.dialogs.matter-add-device.existing.answer_generic` + )} + + + + + `; + } + + private _onItemClick(ev) { + if (ev.type === "keydown" && ev.key !== "Enter" && ev.key !== " ") { + return; + } + const item = ev.currentTarget as any; + const step = item.step as MatterAddDeviceStep; + fireEvent(this, "step-selected", { step }); + } + + static styles = [ + sharedStyles, + css` + .logo { + width: 48px; + height: 48px; + border-radius: 12px; + border: 1px solid var(--divider-color); + padding: 10px; + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: center; + object-fit: contain; + } + .logo ha-svg-icon { + --mdc-icon-size: 36px; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "matter-add-device-existing": MatterAddDeviceExisting; + } +} diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-generic.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-generic.ts new file mode 100644 index 0000000000..c48c149823 --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-generic.ts @@ -0,0 +1,48 @@ +import { LitElement, html } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../../../../../common/dom/fire_event"; +import "../../../../../../components/ha-icon-next"; +import "../../../../../../components/ha-list-item-new"; +import "../../../../../../components/ha-list-new"; +import { HomeAssistant } from "../../../../../../types"; +import { sharedStyles } from "./matter-add-device-shared-styles"; + +@customElement("matter-add-device-generic") +class MatterAddDeviceGeneric extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @state() private _code: string = ""; + + render() { + return html` +
+

+ ${this.hass.localize( + "ui.dialogs.matter-add-device.generic.code_instructions" + )} +

+ +
+ `; + } + + private _onCodeChanged(ev: any) { + const value = ev.currentTarget.value; + this._code = value; + fireEvent(this, "pairing-code-changed", { code: value }); + } + + static styles = [sharedStyles]; +} + +declare global { + interface HTMLElementTagNameMap { + "matter-add-device-generic": MatterAddDeviceGeneric; + } +} diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home-fallback.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home-fallback.ts new file mode 100644 index 0000000000..4009f30da3 --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home-fallback.ts @@ -0,0 +1,85 @@ +import { LitElement, html } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../../../../../common/dom/fire_event"; +import "../../../../../../components/ha-icon-next"; +import "../../../../../../components/ha-list-item-new"; +import "../../../../../../components/ha-list-new"; +import { HomeAssistant } from "../../../../../../types"; +import { sharedStyles } from "./matter-add-device-shared-styles"; + +@customElement("matter-add-device-google-home-fallback") +class MatterAddDeviceGoogleHomeFallback extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @state() private _code: string = ""; + + render() { + return html` +
+
    +
  1. + ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home_fallback.step_1` + )} +
  2. +
  3. + ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home_fallback.step_2`, + { + linked_matter_apps_services: html`${this.hass.localize( + `ui.dialogs.matter-add-device.google_home_fallback.linked_matter_apps_services` + )}`, + } + )} +
  4. +
  5. + ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home_fallback.step_3`, + { + link_apps_services: html`${this.hass.localize( + `ui.dialogs.matter-add-device.google_home_fallback.link_apps_services` + )}`, + use_pairing_code: html`${this.hass.localize( + `ui.dialogs.matter-add-device.google_home_fallback.use_pairing_code` + )}`, + } + )} +
  6. +
+
+

+ ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home_fallback.code_instructions` + )} +

+ +
+ `; + } + + private _onCodeChanged(ev: any) { + const value = ev.currentTarget.value; + this._code = value; + fireEvent(this, "pairing-code-changed", { code: value }); + } + + static styles = [sharedStyles]; +} + +declare global { + interface HTMLElementTagNameMap { + "matter-add-device-google-home-fallback": MatterAddDeviceGoogleHomeFallback; + } +} diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home.ts new file mode 100644 index 0000000000..1c528cf524 --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home.ts @@ -0,0 +1,82 @@ +import { LitElement, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import { fireEvent } from "../../../../../../common/dom/fire_event"; +import "../../../../../../components/ha-icon-next"; +import "../../../../../../components/ha-list-item-new"; +import "../../../../../../components/ha-list-new"; +import { HomeAssistant } from "../../../../../../types"; +import { sharedStyles } from "./matter-add-device-shared-styles"; + +@customElement("matter-add-device-google-home") +class MatterAddDeviceGoogleHome extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + render() { + return html` +
+
    +
  1. + ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home.step_1` + )} +
  2. +
  3. + ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home.step_2`, + { + linked_matter_apps_services: html`${this.hass.localize( + `ui.dialogs.matter-add-device.google_home.linked_matter_apps_services` + )}`, + } + )} +
  4. +
  5. + ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home.step_3`, + { + link_apps_services: html`${this.hass.localize( + `ui.dialogs.matter-add-device.google_home.link_apps_services` + )}`, + home_assistant: html`Home Assistant`, + } + )} +
    + + ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home.no_home_assistant` + )} + +
  6. +
+
+

+ ${this.hass.localize( + `ui.dialogs.matter-add-device.google_home.redirect` + )} +

+
+ `; + } + + private _nextStep() { + fireEvent(this, "step-selected", { step: "google_home_fallback" }); + } + + static styles = [sharedStyles]; +} + +declare global { + interface HTMLElementTagNameMap { + "matter-add-device-google-home": MatterAddDeviceGoogleHome; + } +} diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-main.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-main.ts new file mode 100644 index 0000000000..dc5b699034 --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-main.ts @@ -0,0 +1,80 @@ +import { LitElement, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import { fireEvent } from "../../../../../../common/dom/fire_event"; +import "../../../../../../components/ha-icon-next"; +import "../../../../../../components/ha-list-item-new"; +import "../../../../../../components/ha-list-new"; +import { HomeAssistant } from "../../../../../../types"; +import { sharedStyles } from "./matter-add-device-shared-styles"; + +@customElement("matter-add-device-main") +class MatterAddDeviceMain extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + render() { + return html` +
+

+ ${this.hass.localize(`ui.dialogs.matter-add-device.main.question`)} +

+
+ + + + ${this.hass.localize( + `ui.dialogs.matter-add-device.main.answer_new` + )} + + + ${this.hass.localize( + `ui.dialogs.matter-add-device.main.answer_new_description` + )} + + + + + + ${this.hass.localize( + `ui.dialogs.matter-add-device.main.answer_existing` + )} + + + ${this.hass.localize( + `ui.dialogs.matter-add-device.main.answer_existing_description` + )} + + + + + `; + } + + private _onItemClick(ev) { + if (ev.type === "keydown" && ev.key !== "Enter" && ev.key !== " ") { + return; + } + const item = ev.currentTarget as any; + const step = item.step as "new" | "existing"; + fireEvent(this, "step-selected", { step }); + } + + static styles = [sharedStyles]; +} + +declare global { + interface HTMLElementTagNameMap { + "matter-add-device-main": MatterAddDeviceMain; + } +} diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-new.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-new.ts new file mode 100644 index 0000000000..f273c4f685 --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-new.ts @@ -0,0 +1,113 @@ +import { LitElement, css, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import "../../../../../../components/ha-circular-progress"; +import { + canCommissionMatterExternal, + startExternalCommissioning, +} from "../../../../../../data/matter"; +import { HomeAssistant } from "../../../../../../types"; +import { sharedStyles } from "./matter-add-device-shared-styles"; + +@customElement("matter-add-device-new") +class MatterAddDeviceNew extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + protected firstUpdated(): void { + if (!canCommissionMatterExternal(this.hass)) { + return; + } + startExternalCommissioning(this.hass); + } + + render() { + if (canCommissionMatterExternal(this.hass)) { + return html` +
+ +
+ `; + } + + return html` +
+

${this.hass.localize("ui.dialogs.matter-add-device.new.note")}

+

+ ${this.hass.localize("ui.dialogs.matter-add-device.new.download_app")} +

+ +
+ `; + } + + static styles = [ + sharedStyles, + css` + .app-qr { + margin: 24px auto 0 auto; + display: flex; + justify-content: space-between; + padding: 0 24px; + box-sizing: border-box; + gap: 16px; + width: 100%; + max-width: 400px; + } + .app-qr a, + .app-qr img { + flex: 1; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "matter-add-device-new": MatterAddDeviceNew; + } +} diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-shared-styles.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-shared-styles.ts new file mode 100644 index 0000000000..ca36a5f36b --- /dev/null +++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-shared-styles.ts @@ -0,0 +1,35 @@ +import { css } from "lit"; + +export const sharedStyles = css` + .content { + padding: 16px var(--horizontal-padding, 16px); + } + p { + margin: 0; + } + p:not(:last-child) { + margin-bottom: 8px; + } + ol { + padding-inline-start: 20px; + margin-block-start: 0; + margin-block-end: 8px; + } + li { + margin-bottom: 8px; + } + .link { + color: var(--primary-color); + cursor: pointer; + text-decoration: underline; + } + ha-list-new { + padding: 0; + --md-list-item-leading-space: var(--horizontal-padding, 16px); + --md-list-item-trailing-space: var(--horizontal-padding, 16px); + margin-bottom: 16px; + } + ha-textfield { + width: 100%; + } +`; diff --git a/src/translations/en.json b/src/translations/en.json index 68edd0d0f3..cd82c08792 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1657,6 +1657,72 @@ "title": "Create backup?", "text": "This will create a backup before installing.", "create": "Create" + }, + "matter-add-device": { + "add_device": "Add device", + "add_device_failed": "Failed to add the device", + "commissioning": { + "header": "Add Matter device", + "note": "Adding the device, this may take a minute or two." + }, + "main": { + "header": "Add Matter device", + "question": "Is your device already added to another Matter controller?", + "answer_new": "No. It’s new.", + "answer_new_description": "My device is brand new or factory reset.", + "answer_existing": "Yes. It’s already in use.", + "answer_existing_description": "My device is connected to another controller." + }, + "new": { + "header": "[%key:ui::dialogs::matter-add-device::main::header%]", + "note": "You need to use the Home Assistant Companion app on your mobile phone to add Matter devices.", + "download_app": "Install it from the Google Play Store or the App Store if you don't have it.", + "playstore": "[%key:ui::panel::page-onboarding::welcome::playstore%]", + "appstore": "[%key:ui::panel::page-onboarding::welcome::appstore%]" + }, + "existing": { + "header": "[%key:ui::dialogs::matter-add-device::main::header%]", + "question": "Which controller is it connected to?", + "answer_google_home": "Google Home", + "answer_apple_home": "Apple Home", + "answer_generic": "Other controllers" + }, + "google_home": { + "header": "Link Matter app", + "step_1": "Find your device in Google Home. Tap the gear icon to open the device settings.", + "step_2": "Tap {linked_matter_apps_services}.", + "step_3": "Tap {link_apps_services} and choose {home_assistant} from the list.", + "linked_matter_apps_services": "Linked Matter apps & services", + "link_apps_services": "Link apps & services", + "no_home_assistant": "I can’t find Home Assistant on the list", + "redirect": "You are redirected to the Home Assistant app. Please follow the instructions." + }, + "google_home_fallback": { + "header": "Copy pairing code", + "step_1": "[%key:ui::dialogs::matter-add-device::google_home::step_1%]", + "step_2": "[%key:ui::dialogs::matter-add-device::google_home::step_2%]", + "step_3": "Tap {link_apps_services} and choose {use_pairing_code} form the list", + "linked_matter_apps_services": "[%key:ui::dialogs::matter-add-device::google_home::linked_matter_apps_services%]", + "link_apps_services": "[%key:ui::dialogs::matter-add-device::google_home::link_apps_services%]", + "use_pairing_code": "Use Pairing Code", + "pairing_code": "Pairing code", + "code_instructions": "Paste the code you just received from the other controller." + }, + "apple_home": { + "header": "Copy setup code", + "step_1": "Find your device in Apple Home and open {accessory_details}.", + "step_2": "Scroll all the way down and tap {turn_on_pairing_mode}.", + "step_3": "You now see the setup code.", + "accessory_details": "Accessory Details", + "turn_on_pairing_mode": "Turn On Pairing Mode", + "setup_code": "Setup code", + "code_instructions": "Paste the code you just received from the other controller." + }, + "generic": { + "header": "Copy setup code", + "code_instructions": "Search for the sharing mode in the app of your controller, and activate it. You will get a sharing code, enter that below.", + "setup_code": "Setup code" + } } }, "weekdays": { @@ -4182,7 +4248,6 @@ "missing_zwave_zigbee_title": "{integration} is not setup", "missing_zwave_zigbee": "To add a {brand} device, you first need {supported_hardware_link} and the {integration} integration set up. If you already have the hardware then you can proceed with the setup of {integration}.", "missing_matter": "To add a {brand} device, you first need the {integration} integration and {supported_hardware_link}. Do you want to proceed with the setup of {integration}?", - "matter_mobile_app": "You need to use the Home Assistant Companion app on your mobile phone to commission Matter devices.", "supported_hardware": "supported hardware", "proceed": "Proceed", "single_config_entry_title": "This integration allows only one configuration", @@ -6623,7 +6688,9 @@ "forums": "Home Assistant forums", "open_home_newsletter": "Building the Open Home newsletter", "discord": "Discord chat", - "twitter": "Twitter" + "twitter": "Twitter", + "playstore": "Get it on Google Play", + "appstore": "Download on the App Store" }, "user": { "header": "Create user",