mirror of
https://github.com/esphome/esp-web-tools.git
synced 2025-07-28 14:16:41 +00:00
Cleanups (#145)
This commit is contained in:
parent
4f6724a74f
commit
d8e10ff8c9
27
src/components/svg.ts
Normal file
27
src/components/svg.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { svg } from "lit";
|
||||||
|
|
||||||
|
export const closeIcon = svg`
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const firmwareIcon = svg`
|
||||||
|
<svg viewBox="0 0 24 24" title="Software">
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M9.5,8.5L11,10L8,13L11,16L9.5,17.5L5,13L9.5,8.5M14.5,17.5L13,16L16,13L13,10L14.5,8.5L19,13L14.5,17.5M21,2H3A2,2 0 0,0 1,4V20A2,2 0 0,0 3,22H21A2,2 0 0,0 23,20V4A2,2 0 0,0 21,2M21,20H3V6H21V20Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const chipIcon = svg`
|
||||||
|
<svg viewBox="0 0 24 24" title="Chipset">
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M6,4H18V5H21V7H18V9H21V11H18V13H21V15H18V17H21V19H18V20H6V19H3V17H6V15H3V13H6V11H3V9H6V7H3V5H6V4M11,15V18H12V15H11M13,15V18H14V15H13M15,15V18H16V15H15Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
`;
|
@ -1,12 +1,15 @@
|
|||||||
import { LitElement, html, PropertyValues, css, TemplateResult } from "lit";
|
import { LitElement, html, PropertyValues, css, TemplateResult } from "lit";
|
||||||
import { state } from "lit/decorators.js";
|
import { state } from "lit/decorators.js";
|
||||||
import "./components/ewt-dialog";
|
|
||||||
import "./components/ewt-textfield";
|
|
||||||
import "./components/ewt-button";
|
import "./components/ewt-button";
|
||||||
import "./components/ewt-icon-button";
|
|
||||||
import "./components/ewt-checkbox";
|
import "./components/ewt-checkbox";
|
||||||
|
import "./components/ewt-console";
|
||||||
|
import "./components/ewt-dialog";
|
||||||
import "./components/ewt-formfield";
|
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 type { EwtTextfield } from "./components/ewt-textfield";
|
||||||
import { Logger, Manifest, FlashStateType, FlashState } from "./const.js";
|
import { Logger, Manifest, FlashStateType, FlashState } from "./const.js";
|
||||||
import { ImprovSerial } from "improv-wifi-serial-sdk/dist/serial";
|
import { ImprovSerial } from "improv-wifi-serial-sdk/dist/serial";
|
||||||
@ -15,21 +18,14 @@ import {
|
|||||||
ImprovSerialErrorState,
|
ImprovSerialErrorState,
|
||||||
PortNotReady,
|
PortNotReady,
|
||||||
} from "improv-wifi-serial-sdk/dist/const";
|
} from "improv-wifi-serial-sdk/dist/const";
|
||||||
import { fireEvent } from "./util/fire-event";
|
|
||||||
import { flash } from "./flash";
|
import { flash } from "./flash";
|
||||||
import "./components/ewt-console";
|
import { fireEvent } from "./util/fire-event";
|
||||||
import { sleep } from "./util/sleep";
|
import { sleep } from "./util/sleep";
|
||||||
|
import { downloadManifest } from "./util/manifest";
|
||||||
|
|
||||||
const ERROR_ICON = "⚠️";
|
const ERROR_ICON = "⚠️";
|
||||||
const OK_ICON = "🎉";
|
const OK_ICON = "🎉";
|
||||||
|
|
||||||
const messageTemplate = (icon: string, label: string) => html`
|
|
||||||
<div class="center">
|
|
||||||
<div class="icon">${icon}</div>
|
|
||||||
${label}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
class EwtInstallDialog extends LitElement {
|
class EwtInstallDialog extends LitElement {
|
||||||
public port!: SerialPort;
|
public port!: SerialPort;
|
||||||
|
|
||||||
@ -79,7 +75,7 @@ class EwtInstallDialog extends LitElement {
|
|||||||
this._state !== "LOGS"
|
this._state !== "LOGS"
|
||||||
) {
|
) {
|
||||||
if (this._error) {
|
if (this._error) {
|
||||||
content = this._renderMessage(ERROR_ICON, this._error, true);
|
[heading, content, hideActions] = this._renderError(this._error);
|
||||||
} else {
|
} else {
|
||||||
content = this._renderProgress("Connecting");
|
content = this._renderProgress("Connecting");
|
||||||
hideActions = true;
|
hideActions = true;
|
||||||
@ -89,8 +85,7 @@ class EwtInstallDialog extends LitElement {
|
|||||||
} else if (this._state === "ASK_ERASE") {
|
} else if (this._state === "ASK_ERASE") {
|
||||||
[heading, content] = this._renderAskErase();
|
[heading, content] = this._renderAskErase();
|
||||||
} else if (this._state === "ERROR") {
|
} else if (this._state === "ERROR") {
|
||||||
heading = "Error";
|
[heading, content, hideActions] = this._renderError(this._error!);
|
||||||
content = this._renderMessage(ERROR_ICON, this._error!, true);
|
|
||||||
} else if (this._state === "DASHBOARD") {
|
} else if (this._state === "DASHBOARD") {
|
||||||
[heading, content, hideActions, allowClosing] = this._client
|
[heading, content, hideActions, allowClosing] = this._client
|
||||||
? this._renderDashboard()
|
? this._renderDashboard()
|
||||||
@ -112,11 +107,7 @@ class EwtInstallDialog extends LitElement {
|
|||||||
${heading && allowClosing
|
${heading && allowClosing
|
||||||
? html`
|
? html`
|
||||||
<ewt-icon-button dialogAction="close">
|
<ewt-icon-button dialogAction="close">
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
${closeIcon}
|
||||||
<path
|
|
||||||
d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</ewt-icon-button>
|
</ewt-icon-button>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@ -127,34 +118,25 @@ class EwtInstallDialog extends LitElement {
|
|||||||
|
|
||||||
_renderProgress(label: string | TemplateResult, progress?: number) {
|
_renderProgress(label: string | TemplateResult, progress?: number) {
|
||||||
return html`
|
return html`
|
||||||
<div class="center">
|
<ewt-page-progress
|
||||||
<div>
|
.label=${label}
|
||||||
<ewt-circular-progress
|
.progress=${progress}
|
||||||
active
|
></ewt-page-progress>
|
||||||
?indeterminate=${progress === undefined}
|
|
||||||
.progress=${progress !== undefined ? progress / 100 : undefined}
|
|
||||||
density="8"
|
|
||||||
></ewt-circular-progress>
|
|
||||||
${progress !== undefined
|
|
||||||
? html`<div class="progress-pct">${progress}%</div>`
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
${label}
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
_renderMessage(icon: string, label: string, showClose: boolean) {
|
|
||||||
return html`
|
_renderError(label: string): [string, TemplateResult, boolean] {
|
||||||
${messageTemplate(icon, label)}
|
const heading = "Error";
|
||||||
${showClose &&
|
const content = html`
|
||||||
html`
|
<ewt-page-message .icon=${ERROR_ICON} .label=${label}></ewt-page-message>
|
||||||
<ewt-button
|
<ewt-button
|
||||||
slot="primaryAction"
|
slot="primaryAction"
|
||||||
dialogAction="ok"
|
dialogAction="ok"
|
||||||
label="Close"
|
label="Close"
|
||||||
></ewt-button>
|
></ewt-button>
|
||||||
`}
|
|
||||||
`;
|
`;
|
||||||
|
const hideActions = false;
|
||||||
|
return [heading, content, hideActions];
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderDashboard(): [string, TemplateResult, boolean, boolean] {
|
_renderDashboard(): [string, TemplateResult, boolean, boolean] {
|
||||||
@ -166,25 +148,11 @@ class EwtInstallDialog extends LitElement {
|
|||||||
content = html`
|
content = html`
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>${firmwareIcon}</td>
|
||||||
<svg viewBox="0 0 24 24" title="Software">
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M9.5,8.5L11,10L8,13L11,16L9.5,17.5L5,13L9.5,8.5M14.5,17.5L13,16L16,13L13,10L14.5,8.5L19,13L14.5,17.5M21,2H3A2,2 0 0,0 1,4V20A2,2 0 0,0 3,22H21A2,2 0 0,0 23,20V4A2,2 0 0,0 21,2M21,20H3V6H21V20Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</td>
|
|
||||||
<td>${this._info!.firmware} ${this._info!.version}</td>
|
<td>${this._info!.firmware} ${this._info!.version}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>${chipIcon}</td>
|
||||||
<svg viewBox="0 0 24 24" title="Chipset">
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M6,4H18V5H21V7H18V9H21V11H18V13H21V15H18V17H21V19H18V20H6V19H3V17H6V15H3V13H6V11H3V9H6V7H3V5H6V4M11,15V18H12V15H11M13,15V18H14V15H13M15,15V18H16V15H15Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</td>
|
|
||||||
<td>${this._info!.chipFamily}</td>
|
<td>${this._info!.chipFamily}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -340,7 +308,10 @@ class EwtInstallDialog extends LitElement {
|
|||||||
"home_assistant_domain" in this._manifest);
|
"home_assistant_domain" in this._manifest);
|
||||||
hideActions = showSetupLinks;
|
hideActions = showSetupLinks;
|
||||||
content = html`
|
content = html`
|
||||||
${messageTemplate(OK_ICON, "Device connected to the network!")}
|
<ewt-page-message
|
||||||
|
.icon=${OK_ICON}
|
||||||
|
label="Device connected to the network!"
|
||||||
|
></ewt-page-message>
|
||||||
${showSetupLinks
|
${showSetupLinks
|
||||||
? html`
|
? html`
|
||||||
<div class="dashboard-buttons">
|
<div class="dashboard-buttons">
|
||||||
@ -567,7 +538,10 @@ class EwtInstallDialog extends LitElement {
|
|||||||
heading = undefined;
|
heading = undefined;
|
||||||
const supportsImprov = this._client !== null;
|
const supportsImprov = this._client !== null;
|
||||||
content = html`
|
content = html`
|
||||||
${messageTemplate(OK_ICON, "Installation complete!")}
|
<ewt-page-message
|
||||||
|
.icon=${OK_ICON}
|
||||||
|
label="Installation complete!"
|
||||||
|
></ewt-page-message>
|
||||||
<ewt-button
|
<ewt-button
|
||||||
slot="primaryAction"
|
slot="primaryAction"
|
||||||
label="Next"
|
label="Next"
|
||||||
@ -579,7 +553,10 @@ class EwtInstallDialog extends LitElement {
|
|||||||
`;
|
`;
|
||||||
} else if (this._installState.state === FlashStateType.ERROR) {
|
} else if (this._installState.state === FlashStateType.ERROR) {
|
||||||
content = html`
|
content = html`
|
||||||
${messageTemplate(ERROR_ICON, this._installState.message)}
|
<ewt-page-message
|
||||||
|
.icon=${OK_ICON}
|
||||||
|
.label=${this._installState.message}
|
||||||
|
></ewt-page-message>
|
||||||
<ewt-button
|
<ewt-button
|
||||||
slot="primaryAction"
|
slot="primaryAction"
|
||||||
label="Back"
|
label="Back"
|
||||||
@ -668,26 +645,12 @@ class EwtInstallDialog extends LitElement {
|
|||||||
"Serial port is not readable/writable. Close any other application using it and try again.";
|
"Serial port is not readable/writable. Close any other application using it and try again.";
|
||||||
}
|
}
|
||||||
|
|
||||||
const manifestURL = new URL(
|
|
||||||
this.manifestPath,
|
|
||||||
location.toString()
|
|
||||||
).toString();
|
|
||||||
try {
|
try {
|
||||||
this._manifest = await fetch(manifestURL).then(
|
this._manifest = await downloadManifest(this.manifestPath);
|
||||||
(resp): Promise<Manifest> => resp.json()
|
|
||||||
);
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
this._state = "ERROR";
|
this._state = "ERROR";
|
||||||
this._error = "Failed to download manifest";
|
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) {
|
if (this._manifest.new_install_improv_wait_time === 0) {
|
||||||
this._client = null;
|
this._client = null;
|
||||||
@ -840,18 +803,6 @@ class EwtInstallDialog extends LitElement {
|
|||||||
display: block;
|
display: block;
|
||||||
margin-top: 16px;
|
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 {
|
.dashboard-buttons {
|
||||||
margin: 0 0 -16px -8px;
|
margin: 0 0 -16px -8px;
|
||||||
}
|
}
|
||||||
@ -859,17 +810,9 @@ class EwtInstallDialog extends LitElement {
|
|||||||
display: block;
|
display: block;
|
||||||
margin: 4px 0;
|
margin: 4px 0;
|
||||||
}
|
}
|
||||||
ewt-circular-progress {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
a.has-button {
|
a.has-button {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.icon {
|
|
||||||
font-size: 50px;
|
|
||||||
line-height: 80px;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
.error {
|
.error {
|
||||||
color: var(--improv-danger-color);
|
color: var(--improv-danger-color);
|
||||||
}
|
}
|
||||||
|
39
src/pages/ewt-page-message.ts
Normal file
39
src/pages/ewt-page-message.ts
Normal file
@ -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`
|
||||||
|
<div class="icon">${this.icon}</div>
|
||||||
|
${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;
|
||||||
|
}
|
||||||
|
}
|
44
src/pages/ewt-page-progress.ts
Normal file
44
src/pages/ewt-page-progress.ts
Normal file
@ -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`
|
||||||
|
<div>
|
||||||
|
<ewt-circular-progress
|
||||||
|
active
|
||||||
|
?indeterminate=${this.progress === undefined}
|
||||||
|
.progress=${this.progress !== undefined
|
||||||
|
? this.progress / 100
|
||||||
|
: undefined}
|
||||||
|
density="8"
|
||||||
|
></ewt-circular-progress>
|
||||||
|
${this.progress !== undefined ? html`<div>${this.progress}%</div>` : ""}
|
||||||
|
</div>
|
||||||
|
${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;
|
||||||
|
}
|
||||||
|
}
|
18
src/util/manifest.ts
Normal file
18
src/util/manifest.ts
Normal file
@ -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;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user