Skip to content

Commit

Permalink
Refactor dialog to choose firmware download type (esphome#469)
Browse files Browse the repository at this point in the history
  • Loading branch information
kuba2k2 authored Sep 3, 2023
1 parent 30e7631 commit aa7c9c9
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 105 deletions.
11 changes: 0 additions & 11 deletions src/api/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,6 @@ export const compileConfigurationMetadata = (
abortController
);

export const getDownloadUrl = (
configuration: string,
factoryFirmware: boolean
) => {
let url = `./download.bin?configuration=${encodeURIComponent(configuration)}`;
if (factoryFirmware) {
url += "&type=firmware-factory.bin";
}
return url;
};

// null if file not found.
// status 404 = file not found
// status 422 = invalid config
Expand Down
25 changes: 25 additions & 0 deletions src/api/download.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { fetchApiJson } from ".";

export type DownloadType = {
title: string;
description: string;
file: string;
download: string;
};

export const getDownloadTypes = (configuration: string) =>
fetchApiJson<DownloadType[]>(
`./downloads?configuration=${encodeURIComponent(configuration)}`
);

export const getDownloadUrl = (configuration: string, type: DownloadType) =>
`./download.bin?configuration=${encodeURIComponent(
configuration
)}&file=${encodeURIComponent(type.file)}&download=${encodeURIComponent(
type.download
)}`;

export const getFactoryDownloadUrl = (configuration: string) =>
`./download.bin?configuration=${encodeURIComponent(
configuration
)}&file=firmware-factory.bin`;
31 changes: 12 additions & 19 deletions src/compile/compile-dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import "@material/mwc-button";
import "../components/remote-process";
import "../components/process-dialog";
import { openCompileDialog } from ".";
import { getDownloadUrl } from "../api/configuration";
import { openDownloadTypeDialog } from "../download-type";
import { esphomeDialogStyles } from "../styles";

@customElement("esphome-compile-dialog")
class ESPHomeCompileDialog extends LitElement {
@property() public configuration!: string;
@property() public platformSupportsWebSerial!: boolean;

@property() public downloadFactoryFirmware = true;

Expand All @@ -28,15 +29,11 @@ class ESPHomeCompileDialog extends LitElement {
? ""
: this._result === 0
? html`
<a
<mwc-button
slot="secondaryAction"
href="${getDownloadUrl(
this.configuration,
this.downloadFactoryFirmware
)}"
>
<mwc-button label="Download"></mwc-button>
</a>
label="Download"
@click=${this._handleDownload}
></mwc-button>
`
: html`
<mwc-button
Expand All @@ -57,19 +54,15 @@ class ESPHomeCompileDialog extends LitElement {
return;
}

const link = document.createElement("a");
link.download = this.configuration + ".bin";
link.href = getDownloadUrl(
this.configuration,
this.downloadFactoryFirmware
);
document.body.appendChild(link);
link.click();
link.remove();
openDownloadTypeDialog(this.configuration, this.platformSupportsWebSerial);
}

private _handleDownload() {
openDownloadTypeDialog(this.configuration, this.platformSupportsWebSerial);
}

private _handleRetry() {
openCompileDialog(this.configuration, this.downloadFactoryFirmware);
openCompileDialog(this.configuration, this.platformSupportsWebSerial);
}

private _handleClose() {
Expand Down
4 changes: 2 additions & 2 deletions src/compile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ const preload = () => import("./compile-dialog");

export const openCompileDialog = (
configuration: string,
downloadFactoryFirmware: boolean
platformSupportsWebSerial: boolean
) => {
preload();
const dialog = document.createElement("esphome-compile-dialog");
dialog.configuration = configuration;
dialog.downloadFactoryFirmware = downloadFactoryFirmware;
dialog.platformSupportsWebSerial = platformSupportsWebSerial;
document.body.append(dialog);
};
120 changes: 120 additions & 0 deletions src/download-type/download-type-dialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { LitElement, html, PropertyValues, css } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import "@material/mwc-dialog";
import "@material/mwc-list/mwc-list-item.js";
import "@material/mwc-circular-progress";
import "@material/mwc-button";
import { metaChevronRight } from "../const";
import { esphomeDialogStyles, esphomeSvgStyles } from "../styles";
import "../components/esphome-alert";
import {
DownloadType,
getDownloadTypes,
getDownloadUrl,
} from "../api/download";

@customElement("esphome-download-type-dialog")
class ESPHomeDownloadTypeDialog extends LitElement {
@property() public configuration!: string;
@property() public platformSupportsWebSerial!: boolean;

@state() private _error?: string;
@state() private _downloadTypes?: DownloadType[];

protected render() {
let heading;
let content;

heading = "What version do you want to download?";
content = html`
${this._error ? html`<div class="error">${this._error}</div>` : ""}
${!this._downloadTypes
? html`<div>Checking files to download...</div>`
: html`
${this._downloadTypes.map(
(type) => html`
<mwc-list-item
twoline
hasMeta
dialogAction="close"
@click=${() => this._handleDownload(type)}
>
<span>${type.title}</span>
<span slot="secondary">${type.description}</span>
${metaChevronRight}
</mwc-list-item>
`
)}
`}
`;

return html`
<mwc-dialog open heading=${heading} scrimClickAction>
${content}
${this.platformSupportsWebSerial
? html`
<a
href="https://web.esphome.io"
target="_blank"
rel="noopener noreferrer"
class="bottom-left"
>Open ESPHome Web</a
>
`
: ""}
<mwc-button
no-attention
slot="primaryAction"
dialogAction="close"
label="Cancel"
></mwc-button>
</mwc-dialog>
`;
}

protected firstUpdated(changedProps: PropertyValues) {
super.firstUpdated(changedProps);
getDownloadTypes(this.configuration)
.then((types) => {
if (types.length == 1) {
this._handleDownload(types[0]);
this._close();
return;
}
this._downloadTypes = types;
})
.catch((err: any) => {
this._error = err.message || err;
});
}

private _handleDownload(type: DownloadType) {
const link = document.createElement("a");
link.download = type.download;
link.href = getDownloadUrl(this.configuration, type);
document.body.appendChild(link);
link.click();
link.remove();
}

private _close() {
this.shadowRoot!.querySelector("mwc-dialog")!.close();
}

static styles = [
esphomeDialogStyles,
esphomeSvgStyles,
css`
mwc-list-item {
margin: 0 -20px;
}
`,
];
}

declare global {
interface HTMLElementTagNameMap {
"esphome-download-type-dialog": ESPHomeDownloadTypeDialog;
}
}
12 changes: 12 additions & 0 deletions src/download-type/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const preload = () => import("./download-type-dialog");

export const openDownloadTypeDialog = (
configuration: string,
platformSupportsWebSerial: boolean
) => {
preload();
const dialog = document.createElement("esphome-download-type-dialog");
dialog.configuration = configuration;
dialog.platformSupportsWebSerial = platformSupportsWebSerial;
document.body.append(dialog);
};
Loading

0 comments on commit aa7c9c9

Please sign in to comment.