From c485e8d03e5cdbe7e5bb2971b545c81a4f67d730 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 30 Aug 2023 13:24:25 +0200 Subject: [PATCH] Update onboarding (#17734) Co-authored-by: Paul Bottein --- .../dialogs/backup/dialog-hassio-backup.ts | 5 +- .../backup/show-dialog-hassio-backup.ts | 1 + public/static/images/logo_discord.png | Bin 0 -> 1298 bytes public/static/images/logo_twitter.png | Bin 0 -> 1201 bytes src/auth/ha-authorize.ts | 4 +- src/components/ha-dialog.ts | 4 +- src/components/ha-language-picker.ts | 40 +- src/components/ha-select.ts | 3 + src/components/language-datalist.ts | 15 - src/html/onboarding.html.template | 50 +- src/mixins/lit-localize-lite-mixin.ts | 27 +- src/onboarding/action-badge.ts | 85 - src/onboarding/dialogs/app-dialog.ts | 6759 +++++++++++++++++ src/onboarding/dialogs/community-dialog.ts | 106 + src/onboarding/dialogs/show-app-dialog.ts | 15 + .../dialogs/show-community-dialog.ts | 15 + src/onboarding/ha-onboarding.ts | 205 +- src/onboarding/integration-badge.ts | 24 - src/onboarding/onboarding-analytics.ts | 60 +- src/onboarding/onboarding-core-config.ts | 314 +- src/onboarding/onboarding-create-user.ts | 70 +- src/onboarding/onboarding-integrations.ts | 185 +- src/onboarding/onboarding-loading.ts | 2 +- src/onboarding/onboarding-location.ts | 308 +- src/onboarding/onboarding-name.ts | 111 - src/onboarding/onboarding-restore-backup.ts | 69 +- src/onboarding/onboarding-welcome-link.ts | 103 + src/onboarding/onboarding-welcome-links.ts | 84 + src/onboarding/onboarding-welcome.ts | 79 + src/onboarding/particles.ts | 15 +- src/onboarding/styles.ts | 19 + src/translations/en.json | 36 +- 32 files changed, 7866 insertions(+), 947 deletions(-) create mode 100644 public/static/images/logo_discord.png create mode 100644 public/static/images/logo_twitter.png delete mode 100644 src/components/language-datalist.ts delete mode 100644 src/onboarding/action-badge.ts create mode 100644 src/onboarding/dialogs/app-dialog.ts create mode 100644 src/onboarding/dialogs/community-dialog.ts create mode 100644 src/onboarding/dialogs/show-app-dialog.ts create mode 100644 src/onboarding/dialogs/show-community-dialog.ts delete mode 100644 src/onboarding/onboarding-name.ts create mode 100644 src/onboarding/onboarding-welcome-link.ts create mode 100644 src/onboarding/onboarding-welcome-links.ts create mode 100644 src/onboarding/onboarding-welcome.ts create mode 100644 src/onboarding/styles.ts diff --git a/hassio/src/dialogs/backup/dialog-hassio-backup.ts b/hassio/src/dialogs/backup/dialog-hassio-backup.ts index 230ecc1f22..fbf1edc46f 100644 --- a/hassio/src/dialogs/backup/dialog-hassio-backup.ts +++ b/hassio/src/dialogs/backup/dialog-hassio-backup.ts @@ -173,6 +173,7 @@ class HassioBackupDialog private async _restoreClicked() { const backupDetails = this._backupContent.backupDetails(); this._restoringBackup = true; + this._dialogParams?.onRestoring?.(); if (this._backupContent.backupType === "full") { await this._fullRestoreClicked(backupDetails); } else { @@ -219,7 +220,7 @@ class HassioBackupDialog this._error = error.body.message; } } else { - fireEvent(this, "restoring"); + this._dialogParams?.onRestoring?.(); await fetch(`/api/hassio/backups/${this._backup!.slug}/restore/partial`, { method: "POST", body: JSON.stringify(backupDetails), @@ -268,7 +269,7 @@ class HassioBackupDialog } ); } else { - fireEvent(this, "restoring"); + this._dialogParams?.onRestoring?.(); fetch(`/api/hassio/backups/${this._backup!.slug}/restore/full`, { method: "POST", body: JSON.stringify(backupDetails), diff --git a/hassio/src/dialogs/backup/show-dialog-hassio-backup.ts b/hassio/src/dialogs/backup/show-dialog-hassio-backup.ts index 39c438e217..42f00da445 100644 --- a/hassio/src/dialogs/backup/show-dialog-hassio-backup.ts +++ b/hassio/src/dialogs/backup/show-dialog-hassio-backup.ts @@ -5,6 +5,7 @@ import { Supervisor } from "../../../../src/data/supervisor/supervisor"; export interface HassioBackupDialogParams { slug: string; onDelete?: () => void; + onRestoring?: () => void; onboarding?: boolean; supervisor?: Supervisor; localize?: LocalizeFunc; diff --git a/public/static/images/logo_discord.png b/public/static/images/logo_discord.png new file mode 100644 index 0000000000000000000000000000000000000000..24e567e1eba2331f522e0494f17b027b41a9b8af GIT binary patch literal 1298 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 N5I`XM)%#G={{!ySZnppc literal 0 HcmV?d00001 diff --git a/src/auth/ha-authorize.ts b/src/auth/ha-authorize.ts index 67313d4ffa..9778edfc0a 100644 --- a/src/auth/ha-authorize.ts +++ b/src/auth/ha-authorize.ts @@ -35,6 +35,8 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) { @property() public oauth2State?: string; + @property() public translationFragment = "page-authorize"; + @state() private _authProvider?: AuthProvider; @state() private _authProviders?: AuthProvider[]; @@ -45,7 +47,6 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) { constructor() { super(); - this.translationFragment = "page-authorize"; const query = extractSearchParamsObject() as AuthUrlSearchParams; if (query.client_id) { this.clientId = query.client_id; @@ -102,7 +103,6 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) { : nothing} html`
${title}
option.value === this.value @@ -78,11 +79,11 @@ export class HaLanguagePicker extends LitElement { } private _getLanguagesOptions = memoizeOne( - (languages: string[], locale: FrontendLocaleData, nativeName: boolean) => { + (languages: string[], nativeName: boolean, locale?: FrontendLocaleData) => { let options: { label: string; value: string }[] = []; if (nativeName) { - const translations = this.hass.translationMetadata.translations; + const translations = translationMetadata.translations; options = languages.map((lang) => { let label = translations[lang]?.nativeName; if (!label) { @@ -101,14 +102,14 @@ export class HaLanguagePicker extends LitElement { label, }; }); - } else { + } else if (locale) { options = languages.map((lang) => ({ value: lang, label: formatLanguageCode(lang, locale), })); } - if (!this.noSort) { + if (!this.noSort && locale) { options.sort((a, b) => caseInsensitiveStringCompare(a.label, b.label, locale.language) ); @@ -118,20 +119,14 @@ export class HaLanguagePicker extends LitElement { ); private _computeDefaultLanguageOptions() { - if (!this.hass.translationMetadata?.translations) { - return; - } - - this._defaultLanguages = Object.keys( - this.hass.translationMetadata.translations - ); + this._defaultLanguages = Object.keys(translationMetadata.translations); } protected render() { const languageOptions = this._getLanguagesOptions( this.languages ?? this._defaultLanguages, - this.hass.locale, - this.nativeName + this.nativeName, + this.hass?.locale ); const value = @@ -139,9 +134,10 @@ export class HaLanguagePicker extends LitElement { return html` ${languageOptions.length === 0 ? html`${this.hass.localize( + >${this.hass?.localize( "ui.components.language-picker.no_languages" - )}` : languageOptions.map( (option) => html` @@ -176,7 +172,7 @@ export class HaLanguagePicker extends LitElement { private _changed(ev): void { const target = ev.target as HaSelect; - if (!this.hass || target.value === "" || target.value === this.value) { + if (target.value === "" || target.value === this.value) { return; } this.value = target.value; diff --git a/src/components/ha-select.ts b/src/components/ha-select.ts index 7471149051..bb3cfb4ae7 100644 --- a/src/components/ha-select.ts +++ b/src/components/ha-select.ts @@ -47,6 +47,9 @@ export class HaSelect extends SelectBase { .mdc-select__anchor { width: var(--ha-select-min-width, 200px); } + .mdc-select--filled .mdc-select__anchor { + height: var(--ha-select-height, 56px); + } .mdc-select--filled .mdc-floating-label { inset-inline-start: 12px; inset-inline-end: initial; diff --git a/src/components/language-datalist.ts b/src/components/language-datalist.ts deleted file mode 100644 index bac8b44c9c..0000000000 --- a/src/components/language-datalist.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { HomeAssistant } from "../types"; - -export const createLanguageListEl = (hass: HomeAssistant) => { - const list = document.createElement("datalist"); - list.id = "languages"; - for (const [language, metadata] of Object.entries( - hass.translationMetadata.translations - )) { - const option = document.createElement("option"); - option.value = language; - option.innerText = metadata.nativeName; - list.appendChild(option); - } - return list; -}; diff --git a/src/html/onboarding.html.template b/src/html/onboarding.html.template index 1824f4727b..9f89da79f0 100644 --- a/src/html/onboarding.html.template +++ b/src/html/onboarding.html.template @@ -6,57 +6,40 @@ <%= renderTemplate("_style_base.html.template") %> @@ -64,8 +47,7 @@
- - Home Assistant + Home Assistant
diff --git a/src/mixins/lit-localize-lite-mixin.ts b/src/mixins/lit-localize-lite-mixin.ts index ecfd84957d..2259a23dff 100644 --- a/src/mixins/lit-localize-lite-mixin.ts +++ b/src/mixins/lit-localize-lite-mixin.ts @@ -1,5 +1,5 @@ import { LitElement, PropertyValues } from "lit"; -import { property } from "lit/decorators"; +import { property, state } from "lit/decorators"; import { computeLocalize, LocalizeFunc } from "../common/translations/localize"; import { Constructor, Resources } from "../types"; import { getLocalLanguage, getTranslation } from "../util/common-translation"; @@ -15,13 +15,13 @@ export const litLocalizeLiteMixin = >( // Initialized to empty will prevent undefined errors if called before connected to DOM. @property() public localize: LocalizeFunc = empty; - @property() public resources?: Resources; - // Use browser language setup before login. @property() public language?: string = getLocalLanguage(); @property() public translationFragment?: string; + @state() private _resources?: Resources; + public connectedCallback(): void { super.connectedCallback(); this._initializeLocalizeLite(); @@ -35,22 +35,27 @@ export const litLocalizeLiteMixin = >( ); } - protected updated(changedProperties: PropertyValues) { - super.updated(changedProperties); + protected willUpdate(changedProperties: PropertyValues) { + super.willUpdate(changedProperties); + if (changedProperties.get("language")) { + this._resources = undefined; + this._initializeLocalizeLite(); + } + if (changedProperties.get("translationFragment")) { this._initializeLocalizeLite(); } if ( this.language && - this.resources && + this._resources && (changedProperties.has("language") || - changedProperties.has("resources")) + changedProperties.has("_resources")) ) { computeLocalize( this.constructor.prototype, this.language, - this.resources + this._resources ).then((localize) => { this.localize = localize; }); @@ -58,7 +63,7 @@ export const litLocalizeLiteMixin = >( } protected async _initializeLocalizeLite() { - if (this.resources) { + if (this._resources) { return; } @@ -68,7 +73,7 @@ export const litLocalizeLiteMixin = >( if (__DEV__) { setTimeout( () => - !this.resources && + !this._resources && // eslint-disable-next-line console.error( "Forgot to pass in resources or set translationFragment for", @@ -84,7 +89,7 @@ export const litLocalizeLiteMixin = >( this.translationFragment!, this.language! ); - this.resources = { + this._resources = { [this.language!]: data, }; } diff --git a/src/onboarding/action-badge.ts b/src/onboarding/action-badge.ts deleted file mode 100644 index c53f57ca52..0000000000 --- a/src/onboarding/action-badge.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property } from "lit/decorators"; -import "../components/ha-svg-icon"; - -@customElement("action-badge") -class ActionBadge extends LitElement { - @property() public icon!: string; - - @property() public title!: string; - - @property() public badgeIcon?: string; - - @property({ type: Boolean, reflect: true }) public clickable = false; - - protected render(): TemplateResult { - return html` -
- - ${this.badgeIcon - ? html`` - : ""} -
-
${this.title}
- `; - } - - static get styles(): CSSResultGroup { - return css` - :host { - display: inline-flex; - flex-direction: column; - text-align: center; - color: var(--primary-text-color); - } - - :host([clickable]) { - color: var(--primary-text-color); - } - - .icon { - position: relative; - box-sizing: border-box; - margin: 0 auto 8px; - height: 40px; - width: 40px; - border-radius: 50%; - border: 1px solid var(--secondary-text-color); - display: flex; - align-items: center; - justify-content: center; - } - - :host([clickable]) .icon { - border-color: var(--primary-color); - border-width: 2px; - } - - .badge { - position: absolute; - color: var(--primary-color); - bottom: -5px; - right: -5px; - background-color: white; - border-radius: 50%; - width: 18px; - display: block; - height: 18px; - } - - .title { - min-height: 2.3em; - word-break: break-word; - } - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - "action-badge": ActionBadge; - } -} diff --git a/src/onboarding/dialogs/app-dialog.ts b/src/onboarding/dialogs/app-dialog.ts new file mode 100644 index 0000000000..087adfc3a7 --- /dev/null +++ b/src/onboarding/dialogs/app-dialog.ts @@ -0,0 +1,6759 @@ +import { LitElement, css, html, nothing } from "lit"; +import { customElement, property } from "lit/decorators"; +import { LocalizeFunc } from "../../common/translations/localize"; +import { fireEvent } from "../../common/dom/fire_event"; +import { createCloseHeading } from "../../components/ha-dialog"; + +@customElement("app-dialog") +class DialogApp extends LitElement { + @property({ attribute: false }) public localize?: LocalizeFunc; + + public async showDialog(params): Promise { + this.localize = params.localize; + } + + public async closeDialog(): Promise { + this.localize = undefined; + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + + protected render() { + if (!this.localize) { + return nothing; + } + return html` +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
`; + } + + static styles = css` + ha-dialog { + --mdc-dialog-min-width: min(500px, 90vw); + } + div { + display: flex; + justify-content: space-between; + } + a:first-child { + margin-right: 16px; + } + svg { + width: 100%; + } + .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%); + } + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "app-dialog": DialogApp; + } +} diff --git a/src/onboarding/dialogs/community-dialog.ts b/src/onboarding/dialogs/community-dialog.ts new file mode 100644 index 0000000000..f2bffcb3cc --- /dev/null +++ b/src/onboarding/dialogs/community-dialog.ts @@ -0,0 +1,106 @@ +import "@material/mwc-list/mwc-list"; +import { mdiOpenInNew } from "@mdi/js"; +import { LitElement, css, html, nothing } from "lit"; +import { customElement, property } from "lit/decorators"; +import { fireEvent } from "../../common/dom/fire_event"; +import { LocalizeFunc } from "../../common/translations/localize"; +import { createCloseHeading } from "../../components/ha-dialog"; +import "../../components/ha-list-item"; + +@customElement("community-dialog") +class DialogCommunity extends LitElement { + @property({ attribute: false }) public localize?: LocalizeFunc; + + public async showDialog(params): Promise { + this.localize = params.localize; + } + + public async closeDialog(): Promise { + this.localize = undefined; + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + + protected render() { + if (!this.localize) { + return nothing; + } + return html` + + + + + ${this.localize("ui.panel.page-onboarding.welcome.forums")} + + + + + + + ${this.localize( + "ui.panel.page-onboarding.welcome.open_home_newsletter" + )} + + + + + + + ${this.localize("ui.panel.page-onboarding.welcome.discord")} + + + + + + + ${this.localize("ui.panel.page-onboarding.welcome.twitter")} + + + + + `; + } + + static styles = css` + ha-dialog { + --mdc-dialog-min-width: min(400px, 90vw); + --dialog-content-padding: 0; + } + ha-list-item { + height: 56px; + --mdc-list-item-meta-size: 20px; + } + a { + text-decoration: none; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "community-dialog": DialogCommunity; + } +} diff --git a/src/onboarding/dialogs/show-app-dialog.ts b/src/onboarding/dialogs/show-app-dialog.ts new file mode 100644 index 0000000000..49dbac5205 --- /dev/null +++ b/src/onboarding/dialogs/show-app-dialog.ts @@ -0,0 +1,15 @@ +import { fireEvent } from "../../common/dom/fire_event"; +import { LocalizeFunc } from "../../common/translations/localize"; + +export const loadAppDialog = () => import("./app-dialog"); + +export const showAppDialog = ( + element: HTMLElement, + params: { localize: LocalizeFunc } +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "app-dialog", + dialogImport: loadAppDialog, + dialogParams: params, + }); +}; diff --git a/src/onboarding/dialogs/show-community-dialog.ts b/src/onboarding/dialogs/show-community-dialog.ts new file mode 100644 index 0000000000..236df5cc70 --- /dev/null +++ b/src/onboarding/dialogs/show-community-dialog.ts @@ -0,0 +1,15 @@ +import { fireEvent } from "../../common/dom/fire_event"; +import { LocalizeFunc } from "../../common/translations/localize"; + +export const loadCommunityDialog = () => import("./community-dialog"); + +export const showCommunityDialog = ( + element: HTMLElement, + params: { localize: LocalizeFunc } +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "community-dialog", + dialogImport: loadCommunityDialog, + dialogParams: params, + }); +}; diff --git a/src/onboarding/ha-onboarding.ts b/src/onboarding/ha-onboarding.ts index f08917aaa4..7a06c0e3cf 100644 --- a/src/onboarding/ha-onboarding.ts +++ b/src/onboarding/ha-onboarding.ts @@ -1,3 +1,4 @@ +import "@material/mwc-linear-progress/mwc-linear-progress"; import { Auth, createConnection, @@ -5,35 +6,45 @@ import { getAuth, subscribeConfig, } from "home-assistant-js-websocket"; -import { html, PropertyValues, nothing } from "lit"; +import { PropertyValues, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { + enableWrite, + loadTokens, + saveTokens, +} from "../common/auth/token_storage"; import { applyThemesOnElement } from "../common/dom/apply_themes_on_element"; import { HASSDomEvent } from "../common/dom/fire_event"; import { extractSearchParamsObject } from "../common/url/search-params"; import { subscribeOne } from "../common/util/subscribe-one"; +import "../components/ha-card"; +import "../components/ha-language-picker"; import { AuthUrlSearchParams, hassUrl } from "../data/auth"; import { - fetchInstallationType, - fetchOnboardingOverview, OnboardingResponses, OnboardingStep, + fetchInstallationType, + fetchOnboardingOverview, onboardIntegrationStep, } from "../data/onboarding"; import { subscribeUser } from "../data/ws-user"; import { litLocalizeLiteMixin } from "../mixins/lit-localize-lite-mixin"; import { HassElement } from "../state/hass-element"; import { HomeAssistant } from "../types"; +import { storeState } from "../util/ha-pref-storage"; import { registerServiceWorker } from "../util/register-service-worker"; import "./onboarding-analytics"; import "./onboarding-create-user"; import "./onboarding-loading"; -import { - enableWrite, - loadTokens, - saveTokens, -} from "../common/auth/token_storage"; +import "./onboarding-welcome"; +import "./onboarding-welcome-links"; +import { makeDialogManager } from "../dialogs/make-dialog-manager"; type OnboardingEvent = + | { + type: "init"; + result: { restore: boolean }; + } | { type: "user"; result: OnboardingResponses["user"]; @@ -49,13 +60,21 @@ type OnboardingEvent = type: "analytics"; }; +interface OnboardingProgressEvent { + increase?: number; + decrease?: number; + progress?: number; +} + declare global { interface HASSDomEvents { "onboarding-step": OnboardingEvent; + "onboarding-progress": OnboardingProgressEvent; } interface GlobalEventHandlersEventMap { "onboarding-step": HASSDomEvent; + "onboarding-progress": HASSDomEvent; } } @@ -65,8 +84,12 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { @property() public translationFragment = "page-onboarding"; + @state() private _progress = 0; + @state() private _loading = false; + @state() private _init = false; + @state() private _restoring = false; @state() private _supervisor?: boolean; @@ -74,29 +97,58 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { @state() private _steps?: OnboardingStep[]; protected render() { + return html` + +
${this._renderStep()}
+
+ ${this._init + ? html`` + : nothing} + `; + } + + private _renderStep() { + if (this._init) { + return html``; + } + + if (this._restoring) { + return html` + `; + } + const step = this._curStep()!; if (this._loading || !step) { return html` `; } if (step.step === "user") { - return html` - ${!this._restoring - ? html` - ` - : ""} - ${this._supervisor - ? html` - ` - : ""} - `; + return html` + `; } if (step.step === "core_config") { return html` @@ -114,7 +166,6 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { > `; } - if (step.step === "integration") { return html` this._handleStepDone(ev)); + this.addEventListener("onboarding-progress", (ev) => + this._handleProgress(ev) + ); if (window.innerWidth > 450) { import("./particles"); } + makeDialogManager(this, this.shadowRoot!); } protected updated(changedProps: PropertyValues) { @@ -170,10 +225,6 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { return this._steps ? this._steps.find((stp) => !stp.done) : undefined; } - private _restoringBackup() { - this._restoring = true; - } - private async _fetchInstallationType(): Promise { try { const response = await fetchInstallationType(); @@ -222,8 +273,12 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { }); history.replaceState(null, "", location.pathname); await this._connectHass(auth); + const currentStep = steps.findIndex((stp) => !stp.done); + const singelStepProgress = 1 / steps.length; + this._progress = currentStep * singelStepProgress + singelStepProgress; } else { - // User creating screen needs to know the installation type. + this._init = true; + // Init screen needs to know the installation type. this._fetchInstallationType(); } @@ -233,15 +288,35 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { } } + private _handleProgress(ev: HASSDomEvent) { + const stepSize = 1 / this._steps!.length; + if (ev.detail.increase) { + this._progress += ev.detail.increase * stepSize; + } + if (ev.detail.decrease) { + this._progress -= ev.detail.decrease * stepSize; + } + if (ev.detail.progress) { + this._progress = ev.detail.progress; + } + } + private async _handleStepDone(ev: HASSDomEvent) { const stepResult = ev.detail; this._steps = this._steps!.map((step) => step.step === stepResult.type ? { ...step, done: true } : step ); - if (stepResult.type === "user") { + if (stepResult.type === "init") { + this._init = false; + this._restoring = stepResult.result.restore; + if (!this._restoring) { + this._progress = 0.25; + } + } else if (stepResult.type === "user") { const result = stepResult.result as OnboardingResponses["user"]; this._loading = true; + this._progress = 0.5; enableWrite(); try { const auth = await getAuth({ @@ -258,6 +333,10 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { this._loading = false; } } else if (stepResult.type === "core_config") { + this._progress = 0.75; + // We do nothing + } else if (stepResult.type === "analytics") { + this._progress = 1; // We do nothing } else if (stepResult.type === "integration") { this._loading = true; @@ -331,6 +410,14 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { subscribeOne(conn, subscribeUser), ]); this.initializeHass(auth, conn); + if (this.language && this.language !== this.hass!.language) { + this._updateHass({ + locale: { ...this.hass!.locale, language: this.language }, + language: this.language, + selectedLanguage: this.language, + }); + storeState(this.hass!); + } // Load config strings for integrations (this as any)._loadFragmentTranslations(this.hass!.language, "config"); // Make sure hass is initialized + the config/user callbacks have called. @@ -338,6 +425,60 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { setTimeout(resolve, 0); }); } + + private _languageChanged(ev: CustomEvent) { + const language = ev.detail.value; + this.language = language; + if (this.hass) { + this._updateHass({ + locale: { ...this.hass!.locale, language }, + language, + selectedLanguage: language, + }); + storeState(this.hass!); + } else { + try { + localStorage.setItem("selectedLanguage", JSON.stringify(language)); + } catch (err: any) { + // Ignore + } + } + } + + static styles = css` + mwc-linear-progress { + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 10; + } + .footer { + display: flex; + justify-content: space-between; + align-items: center; + } + ha-language-picker { + display: block; + width: 200px; + margin-top: 8px; + border-radius: 4px; + overflow: hidden; + --ha-select-height: 40px; + --mdc-select-fill-color: none; + --mdc-select-label-ink-color: var(--primary-text-color, #212121); + --mdc-select-ink-color: var(--primary-text-color, #212121); + --mdc-select-idle-line-color: transparent; + --mdc-select-hover-line-color: transparent; + --mdc-select-dropdown-icon-color: var(--primary-text-color, #212121); + --mdc-shape-small: 0; + } + a { + text-decoration: none; + color: var(--primary-text-color); + margin-right: 16px; + } + `; } declare global { diff --git a/src/onboarding/integration-badge.ts b/src/onboarding/integration-badge.ts index fc440b1589..e888460046 100644 --- a/src/onboarding/integration-badge.ts +++ b/src/onboarding/integration-badge.ts @@ -9,8 +9,6 @@ class IntegrationBadge extends LitElement { @property() public title!: string; - @property() public badgeIcon?: string; - @property({ type: Boolean }) public darkOptimizedIcon?: boolean; @property({ type: Boolean, reflect: true }) public clickable = false; @@ -27,12 +25,6 @@ class IntegrationBadge extends LitElement { })} referrerpolicy="no-referrer" /> - ${this.badgeIcon - ? html`` - : ""}
${this.title}
`; @@ -47,10 +39,6 @@ class IntegrationBadge extends LitElement { color: var(--primary-text-color); } - :host([clickable]) { - color: var(--primary-text-color); - } - img { max-width: 100%; max-height: 100%; @@ -66,18 +54,6 @@ class IntegrationBadge extends LitElement { justify-content: center; } - .badge { - position: absolute; - color: white; - bottom: -7px; - right: -10px; - background-color: var(--label-badge-green); - border-radius: 50%; - display: block; - --mdc-icon-size: 18px; - border: 2px solid white; - } - .title { min-height: 2.3em; word-break: break-word; diff --git a/src/onboarding/onboarding-analytics.ts b/src/onboarding/onboarding-analytics.ts index aeddcb4cc7..0bf36b8159 100644 --- a/src/onboarding/onboarding-analytics.ts +++ b/src/onboarding/onboarding-analytics.ts @@ -1,4 +1,5 @@ import "@material/mwc-button/mwc-button"; +import { mdiOpenInNew } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; @@ -8,6 +9,7 @@ import { Analytics, setAnalyticsPreferences } from "../data/analytics"; import { onboardAnalyticsStep } from "../data/onboarding"; import type { HomeAssistant } from "../types"; import { documentationUrl } from "../util/documentation-url"; +import { onBoardingStyles } from "./styles"; @customElement("onboarding-analytics") class OnboardingAnalytics extends LitElement { @@ -23,7 +25,18 @@ class OnboardingAnalytics extends LitElement { protected render(): TemplateResult { return html` +

${this.localize("ui.panel.page-onboarding.analytics.header")}

${this.localize("ui.panel.page-onboarding.analytics.intro")}

+

+ + ${this.localize("ui.panel.page-onboarding.analytics.learn_more")} + + +

${this._error ? html`
${this._error}
` : ""} `; } @@ -81,27 +91,19 @@ class OnboardingAnalytics extends LitElement { } static get styles(): CSSResultGroup { - return css` - p { - font-size: 14px; - line-height: 20px; - } - .error { - color: var(--error-color); - } - .footer { - margin-top: 16px; - display: flex; - justify-content: space-between; - align-items: center; - flex-direction: row-reverse; - } - a { - color: var(--primary-color); - } - `; - - // footer is direction reverse to tab to "NEXT" first + return [ + onBoardingStyles, + css` + .error { + color: var(--error-color); + } + a { + color: var(--primary-color); + text-decoration: none; + --mdc-icon-size: 14px; + } + `, + ]; } } diff --git a/src/onboarding/onboarding-core-config.ts b/src/onboarding/onboarding-core-config.ts index 3ea32cd556..6306e8ba64 100644 --- a/src/onboarding/onboarding-core-config.ts +++ b/src/onboarding/onboarding-core-config.ts @@ -13,22 +13,12 @@ import { fireEvent } from "../common/dom/fire_event"; import type { LocalizeFunc } from "../common/translations/localize"; import "../components/ha-alert"; import "../components/ha-country-picker"; -import "../components/ha-currency-picker"; -import "../components/ha-formfield"; -import "../components/ha-language-picker"; -import "../components/ha-radio"; -import type { HaRadio } from "../components/ha-radio"; -import "../components/ha-textfield"; -import type { HaTextField } from "../components/ha-textfield"; -import "../components/ha-timezone-picker"; -import "../components/map/ha-locations-editor"; import { ConfigUpdateValues, saveCoreConfig } from "../data/core"; import { countryCurrency } from "../data/currency"; import { onboardCoreConfigStep } from "../data/onboarding"; import type { HomeAssistant, ValueChangedEvent } from "../types"; import { getLocalLanguage } from "../util/common-translation"; import "./onboarding-location"; -import "./onboarding-name"; @customElement("onboarding-core-config") class OnboardingCoreConfig extends LitElement { @@ -38,32 +28,26 @@ class OnboardingCoreConfig extends LitElement { @state() private _working = false; - @state() private _name?: ConfigUpdateValues["location_name"]; - @state() private _location?: [number, number]; - @state() private _elevation?: string; + private _elevation = "0"; - @state() private _unitSystem?: ConfigUpdateValues["unit_system"]; + private _unitSystem: ConfigUpdateValues["unit_system"] = "metric"; - @state() private _currency?: ConfigUpdateValues["currency"]; + private _currency: ConfigUpdateValues["currency"] = "EUR"; - @state() private _timeZone?: ConfigUpdateValues["time_zone"]; + private _timeZone: ConfigUpdateValues["time_zone"] = + Intl.DateTimeFormat?.().resolvedOptions?.().timeZone; - @state() private _language: ConfigUpdateValues["language"]; + private _language: ConfigUpdateValues["language"] = getLocalLanguage(); @state() private _country?: ConfigUpdateValues["country"]; @state() private _error?: string; + @state() private _skipCore = false; + protected render(): TemplateResult { - if (!this._name) { - return html``; - } if (!this._location) { return html``; } + if (this._skipCore) { + return html`
+ +
`; + } return html` - ${ - this._error - ? html`${this._error}` - : nothing - } + ${this._error + ? html`${this._error}` + : nothing}

- ${this.onboardingLocalize( - "ui.panel.page-onboarding.core-config.intro_core_config" - )} + ${this.onboardingLocalize( + "ui.panel.page-onboarding.core-config.country_intro" + )}

-
- - - - -
- -
- - - - - -
- -
-
- ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.unit_system" - )} -
-
- - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.metric_example" - )} -
`} - > - - - - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.us_customary_example" - )} -
`} - > - - - - - -
-
- ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.currency" - )}
- ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.find_currency_value" - )} -
- - -
- + +