diff --git a/src/components/svg.ts b/src/components/svg.ts new file mode 100644 index 00000000..a9cb1451 --- /dev/null +++ b/src/components/svg.ts @@ -0,0 +1,27 @@ +import { svg } from "lit"; + +export const closeIcon = svg` + + + +`; + +export const firmwareIcon = svg` + + + +`; + +export const chipIcon = svg` + + + +`; diff --git a/src/install-dialog.ts b/src/install-dialog.ts index 97ebc583..4f294c88 100644 --- a/src/install-dialog.ts +++ b/src/install-dialog.ts @@ -1,12 +1,15 @@ import { LitElement, html, PropertyValues, css, TemplateResult } from "lit"; import { state } from "lit/decorators.js"; -import "./components/ewt-dialog"; -import "./components/ewt-textfield"; import "./components/ewt-button"; -import "./components/ewt-icon-button"; import "./components/ewt-checkbox"; +import "./components/ewt-console"; +import "./components/ewt-dialog"; import "./components/ewt-formfield"; -import "./components/ewt-circular-progress"; +import "./components/ewt-icon-button"; +import "./components/ewt-textfield"; +import "./pages/ewt-page-progress"; +import "./pages/ewt-page-message"; +import { chipIcon, closeIcon, firmwareIcon } from "./components/svg"; import type { EwtTextfield } from "./components/ewt-textfield"; import { Logger, Manifest, FlashStateType, FlashState } from "./const.js"; import { ImprovSerial } from "improv-wifi-serial-sdk/dist/serial"; @@ -15,21 +18,14 @@ import { ImprovSerialErrorState, PortNotReady, } from "improv-wifi-serial-sdk/dist/const"; -import { fireEvent } from "./util/fire-event"; import { flash } from "./flash"; -import "./components/ewt-console"; +import { fireEvent } from "./util/fire-event"; import { sleep } from "./util/sleep"; +import { downloadManifest } from "./util/manifest"; const ERROR_ICON = "⚠️"; const OK_ICON = "🎉"; -const messageTemplate = (icon: string, label: string) => html` -
-
${icon}
- ${label} -
-`; - class EwtInstallDialog extends LitElement { public port!: SerialPort; @@ -79,7 +75,7 @@ class EwtInstallDialog extends LitElement { this._state !== "LOGS" ) { if (this._error) { - content = this._renderMessage(ERROR_ICON, this._error, true); + [heading, content, hideActions] = this._renderError(this._error); } else { content = this._renderProgress("Connecting"); hideActions = true; @@ -89,8 +85,7 @@ class EwtInstallDialog extends LitElement { } else if (this._state === "ASK_ERASE") { [heading, content] = this._renderAskErase(); } else if (this._state === "ERROR") { - heading = "Error"; - content = this._renderMessage(ERROR_ICON, this._error!, true); + [heading, content, hideActions] = this._renderError(this._error!); } else if (this._state === "DASHBOARD") { [heading, content, hideActions, allowClosing] = this._client ? this._renderDashboard() @@ -112,11 +107,7 @@ class EwtInstallDialog extends LitElement { ${heading && allowClosing ? html` - - - + ${closeIcon} ` : ""} @@ -127,34 +118,25 @@ class EwtInstallDialog extends LitElement { _renderProgress(label: string | TemplateResult, progress?: number) { return html` -
-
- - ${progress !== undefined - ? html`
${progress}%
` - : ""} -
- ${label} -
+ `; } - _renderMessage(icon: string, label: string, showClose: boolean) { - return html` - ${messageTemplate(icon, label)} - ${showClose && - html` - - `} + + _renderError(label: string): [string, TemplateResult, boolean] { + const heading = "Error"; + const content = html` + + `; + const hideActions = false; + return [heading, content, hideActions]; } _renderDashboard(): [string, TemplateResult, boolean, boolean] { @@ -166,25 +148,11 @@ class EwtInstallDialog extends LitElement { content = html` - + - +
- - - - ${firmwareIcon} ${this._info!.firmware} ${this._info!.version}
- - - - ${chipIcon} ${this._info!.chipFamily}
@@ -340,7 +308,10 @@ class EwtInstallDialog extends LitElement { "home_assistant_domain" in this._manifest); hideActions = showSetupLinks; content = html` - ${messageTemplate(OK_ICON, "Device connected to the network!")} + ${showSetupLinks ? html`
@@ -567,7 +538,10 @@ class EwtInstallDialog extends LitElement { heading = undefined; const supportsImprov = this._client !== null; content = html` - ${messageTemplate(OK_ICON, "Installation complete!")} + => resp.json() - ); + this._manifest = await downloadManifest(this.manifestPath); } catch (err: any) { this._state = "ERROR"; this._error = "Failed to download manifest"; } - if ("new_install_skip_erase" in this._manifest) { - console.warn( - 'Manifest option "new_install_skip_erase" is deprecated. Use "new_install_prompt_erase" instead.' - ); - if (this._manifest.new_install_skip_erase) { - this._manifest.new_install_prompt_erase = true; - } - } if (this._manifest.new_install_improv_wait_time === 0) { this._client = null; @@ -840,18 +803,6 @@ class EwtInstallDialog extends LitElement { display: block; margin-top: 16px; } - .center { - text-align: center; - } - .flash { - font-weight: bold; - margin-bottom: 1em; - background-color: var(--mdc-theme-primary); - padding: 8px 4px; - color: var(--mdc-theme-on-primary); - border-radius: 4px; - text-align: center; - } .dashboard-buttons { margin: 0 0 -16px -8px; } @@ -859,17 +810,9 @@ class EwtInstallDialog extends LitElement { display: block; margin: 4px 0; } - ewt-circular-progress { - margin-bottom: 16px; - } a.has-button { text-decoration: none; } - .icon { - font-size: 50px; - line-height: 80px; - color: black; - } .error { color: var(--improv-danger-color); } diff --git a/src/pages/ewt-page-message.ts b/src/pages/ewt-page-message.ts new file mode 100644 index 00000000..5a99721e --- /dev/null +++ b/src/pages/ewt-page-message.ts @@ -0,0 +1,39 @@ +import { LitElement, html, css, TemplateResult } from "lit"; +import { property } from "lit/decorators.js"; +import "../components/ewt-circular-progress"; + +class EwtPageMessage extends LitElement { + @property() icon!: string; + + @property() label!: string | TemplateResult; + + render() { + return html` +
${this.icon}
+ ${this.label} + `; + } + + static styles = css` + :host { + display: flex; + flex-direction: column; + text-align: center; + } + .icon { + font-size: 50px; + line-height: 80px; + color: black; + } + ewt-circular-progress { + margin-bottom: 16px; + } + `; +} +customElements.define("ewt-page-message", EwtPageMessage); + +declare global { + interface HTMLElementTagNameMap { + "ewt-page-message": EwtPageMessage; + } +} diff --git a/src/pages/ewt-page-progress.ts b/src/pages/ewt-page-progress.ts new file mode 100644 index 00000000..fa282fe5 --- /dev/null +++ b/src/pages/ewt-page-progress.ts @@ -0,0 +1,44 @@ +import { LitElement, html, css, TemplateResult } from "lit"; +import { property } from "lit/decorators.js"; +import "../components/ewt-circular-progress"; + +class EwtPageProgress extends LitElement { + @property() label!: string | TemplateResult; + + @property() progress: number | undefined; + + render() { + return html` +
+ + ${this.progress !== undefined ? html`
${this.progress}%
` : ""} +
+ ${this.label} + `; + } + + static styles = css` + :host { + display: flex; + flex-direction: column; + text-align: center; + } + ewt-circular-progress { + margin-bottom: 16px; + } + `; +} +customElements.define("ewt-page-progress", EwtPageProgress); + +declare global { + interface HTMLElementTagNameMap { + "ewt-page-progress": EwtPageProgress; + } +} diff --git a/src/util/manifest.ts b/src/util/manifest.ts new file mode 100644 index 00000000..0b343463 --- /dev/null +++ b/src/util/manifest.ts @@ -0,0 +1,18 @@ +import { Manifest } from "../const"; + +export const downloadManifest = async (manifestPath: string) => { + const manifestURL = new URL(manifestPath, location.toString()).toString(); + const resp = await fetch(manifestURL); + const manifest: Manifest = await resp.json(); + + if ("new_install_skip_erase" in manifest) { + console.warn( + 'Manifest option "new_install_skip_erase" is deprecated. Use "new_install_prompt_erase" instead.' + ); + if (manifest.new_install_skip_erase) { + manifest.new_install_prompt_erase = true; + } + } + + return manifest; +};