From f8fa83b64f4d28c495634a375560eef6ca162dba Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 29 Jul 2025 19:42:41 -0400 Subject: [PATCH] Revamp of messages --- cpinstaller.js | 191 +++++++++++++++++++++++++++++++------------------ 1 file changed, 122 insertions(+), 69 deletions(-) diff --git a/cpinstaller.js b/cpinstaller.js index a09d391..cfa993f 100644 --- a/cpinstaller.js +++ b/cpinstaller.js @@ -260,39 +260,61 @@ export class CPInstallButton extends InstallButton { welcome: { closeable: true, template: (data) => html` +

Web Firmware Installer

- Welcome to the CircuitPython Installer. This tool will install CircuitPython on your ${data.boardName}. + Welcome! + This tool will install a UF2 bootloader and/or CircuitPython on your ${data.boardName}.

- This tool is new and experimental. If you experience any issues, feel free to check out + This tool is experimental. + If you experience any issues, feel free to check out https://github.com/adafruit/circuitpython-org/issues - to see if somebody has already submitted the same issue you are experiencing. If not, feel free to open a new issue. If - you do see the same issue and are able to contribute additional information, that would be appreciated. + to see if the issue you are experiencing has already been reported. + If not, feel free to open a new issue. + If you do see the same issue and are able to contribute additional information, + that would be appreciated.

- If you are unable to use this tool, then the manual installation methods should still work. + If you are unable to use this tool, + then the manual installation methods like the + Adafruit WebSerial Tool + and esptool.py should still work.

` }, espSerialConnect: { closeable: true, template: (data) => html` -

- Make sure your board is plugged into this computer via a Serial connection using a USB Cable. -

- -

- - Click this button to open the Web Serial connection menu. -

- -

There may be many devices listed, such as your remembered Bluetooth peripherals, anything else plugged into USB, etc.

- -

- If you aren't sure which to choose, look for words like "USB", "UART", "JTAG", and "Bridge Controller". There may be more than one right option depending on your system configuration. Experiment if needed. -

`, buttons: [this.previousButton, { label: "Next", @@ -303,7 +325,8 @@ export class CPInstallButton extends InstallButton { }, confirm: { template: (data) => html` -

This will overwrite everything on the ${data.boardName}.

+

Erase Flash

+

Now, optionally, erase everything on the ${data.boardName}.

`, buttons: [ this.previousButton, @@ -320,41 +343,53 @@ export class CPInstallButton extends InstallButton { bootDriveSelect: { closeable: true, template: (data) => html` -

- Please select the ${data.drivename} Drive where the UF2 file will be copied. -

-

- If you just installed the bootloader, you may need to reset your board. If you already had the bootloader installed, - you may need to double press the reset button. -

-

- -

+

Select the ${data.drivename} Drive

+
    +
  1. +

    + Reset your board if you just installed the UF2 bootloader, + by pressing the RESET button. + If you already had the UF2 bootloader installed, + you may need to double-click the RESET button to start up the UF2 bootloader. +

    +
  2. +
  3. +

    + + Select the ${data.drivename} drive where the UF2 file will be copied. +

    +
  4. + `, buttons: [], }, circuitpyDriveSelect: { closeable: true, template: (data) => html` -

    - Please select the CIRCUITPY Drive. If you don't see your CIRCUITPY drive, it may be disabled in boot.py or you may have renamed it at some point. -

    -

    - -

    +

    Select the CIRCUITPY Drive

    + `, buttons: [], }, actionWaiting: { template: (data) => html` -

    ${data.action}...

    +

    ${data.action}

    `, buttons: [], }, actionProgress: { template: (data) => html` -

    ${data.action}...

    +

    ${data.action}

    ${data.percentage}% `, buttons: [], @@ -362,14 +397,15 @@ export class CPInstallButton extends InstallButton { cpSerial: { closeable: true, template: (data) => html` -

    - The next step is to write your credentials to settings.toml. Make sure your board is running CircuitPython. If you just installed CircuitPython, you may to reset the board first. +

    Reconnect to serial

    +

    -

    - - Click this button to open the Web Serial connection menu. If it is already connected, pressing again will allow you to select a different port. -

    -

    ${data.serialPortInstructions}

    `, buttons: [this.previousButton, { @@ -383,6 +419,15 @@ export class CPInstallButton extends InstallButton { credentials: { closeable: true, template: (data) => html` +

    Fill in settings.toml

    +

    + This step will write your network credentials to the settings.toml file on CIRCUITPY. + Make sure your board is running CircuitPython. +

    +

    + If you want to skip this step and fill in settings.toml later, + just close this dialog. +

    @@ -401,9 +446,9 @@ export class CPInstallButton extends InstallButton {
    ${data.mass_storage_disabled === true || data.mass_storage_disabled === false ? - html`
    - -
    ` : ''} + html`
    + +
    ` : ''}
    `, buttons: [this.previousButton, { @@ -478,7 +523,7 @@ export class CPInstallButton extends InstallButton { async stepEraseAll() { // Display Erase Dialog this.showDialog(this.dialogs.actionWaiting, { - action: "Erasing Flash", + action: "Erasing Flash ...", }); try { await this.esploader.eraseFlash(); @@ -538,7 +583,7 @@ export class CPInstallButton extends InstallButton { } // Display Progress Dialog this.showDialog(this.dialogs.actionProgress, { - action: `Copying ${this.uf2FileUrl}`, + action: `Copying ${this.uf2FileUrl} ...`, }); // Do a copy and update progress along the way @@ -671,7 +716,7 @@ export class CPInstallButton extends InstallButton { } catch (err) { // It's possible the dialog was also canceled here this.updateEspConnected(this.connectionStates.DISCONNECTED); - this.errorMsg("Unable to open Serial connection to board. Make sure the port is not already in use by another application or in another browser tab."); + this.errorMsg("Unable to open Serial connection to board. Make sure the port is not already in use by another application or in another browser tab. If installing the bootloader, make sure you are in ROM bootloader mode."); return; } @@ -848,7 +893,8 @@ export class CPInstallButton extends InstallButton { } // Download the bootloader zip file - let [filename, fileBlob] = await this.downloadAndExtract(this.bootloaderUrl, 'tinyuf2.bin'); + let [filename, extracted_filename, fileBlob] = + await this.downloadAndExtract(this.bootloaderUrl, 'tinyuf2.bin'); const fileContents = await fileBlob.text(); const bootDriveRegex = /B\x00B\x00([A-Z0-9\x00]{11})FAT16/; @@ -981,7 +1027,7 @@ export class CPInstallButton extends InstallButton { if (!fileBlob) { this.showDialog(this.dialogs.actionProgress, { - action: `Downloading ${filename}` + action: `Downloading ${filename} ...` }); const progressElement = this.currentDialogElement.querySelector("#stepProgress"); @@ -995,11 +1041,12 @@ export class CPInstallButton extends InstallButton { } // If the file is a zip file, unzip and find the file to extract + let extracted_filename = null; if (filename.endsWith(".zip") && fileToExtract) { let foundFile; // Update the Progress dialog this.showDialog(this.dialogs.actionProgress, { - action: `Extracting ${fileToExtract}` + action: html`

    Downloaded ${filename}

    Extracting ${fileToExtract} ...

    ` }); // Set that to the current file to flash @@ -1008,14 +1055,14 @@ export class CPInstallButton extends InstallButton { this.errorMsg(`Unable to find ${fileToExtract} in ${filename}`); return; } - filename = foundFile; + extracted_filename = foundFile; } - return [filename, fileBlob]; + return [filename, extracted_filename, fileBlob]; } async downloadAndInstall(url, fileToExtract = null, cacheFile = false) { - let [filename, fileBlob] = await this.downloadAndExtract(url, fileToExtract, cacheFile); + let [filename, extracted_filename, fileBlob] = await this.downloadAndExtract(url, fileToExtract, cacheFile); const fileArray = []; const readBlobAsBinaryString = (inputFile) => { @@ -1024,7 +1071,7 @@ export class CPInstallButton extends InstallButton { return new Promise((resolve, reject) => { reader.onerror = () => { reader.abort(); - reject(new DOMException("Problem parsing input file.")); + reject(new DOMException("Problem parsing input file")); }; reader.onload = () => { @@ -1040,7 +1087,9 @@ export class CPInstallButton extends InstallButton { let lastPercent = 0; this.showDialog(this.dialogs.actionProgress, { - action: `Flashing ${filename}` + action: fileToExtract + ? html`

    Downloaded ${filename}

    Extracted ${fileToExtract}

    Flashing (be patient; you will see pauses) ...

    ` + : html`

    Downloaded ${filename}

    Flashing (be patient; you will see pauses) ...

    ` }); const progressElement = this.currentDialogElement.querySelector("#stepProgress"); @@ -1056,7 +1105,7 @@ export class CPInstallButton extends InstallButton { let percentage = Math.round((written / total) * 100); if (percentage > lastPercent) { progressElement.value = percentage; - this.logMsg(`${percentage}% (${written}/${total})...`); + this.logMsg(`${percentage}% (${written}/${total}) ...`); lastPercent = percentage; } }, @@ -1064,7 +1113,7 @@ export class CPInstallButton extends InstallButton { }; await this.esploader.writeFlash(flashOptions); } catch (err) { - this.errorMsg(`Unable to flash file: ${filename}. Error Message: ${err}`); + this.errorMsg(`Unable to flash file: ${fileToExtract}. Error Message: ${err}`); } } } @@ -1078,10 +1127,14 @@ export class CPInstallButton extends InstallButton { return; } + let [filename, extracted_filename, fileBlob] = await this.downloadAndExtract(url); + this.showDialog(this.dialogs.actionProgress, { + action: html`

    Downloaded: ${filename}

    Flashing ...

    ` + }); + const progressElement = this.currentDialogElement.querySelector("#stepProgress"); progressElement.value = 0; - let [filename, fileBlob] = await this.downloadAndExtract(url); const fileHandle = await dirHandle.getFileHandle(filename, {create: true}); const writableStream = await fileHandle.createWritable(); const totalSize = fileBlob.size; @@ -1093,7 +1146,7 @@ export class CPInstallButton extends InstallButton { bytesWritten += chunk.size; progressElement.value = Math.round(bytesWritten / totalSize * 100); - this.logMsg(`${Math.round(bytesWritten / totalSize * 100)}% (${bytesWritten} / ${totalSize}) written...`); + this.logMsg(`${Math.round(bytesWritten / totalSize * 100)}% (${bytesWritten} / ${totalSize}) written ...`); } this.logMsg("File successfully written"); try { @@ -1101,7 +1154,7 @@ export class CPInstallButton extends InstallButton { await writableStream.close(); this.logMsg("File successfully closed"); } catch (err) { - this.logMsg("Error closing file, probably due to board reset. Continuing..."); + this.logMsg("Error closing file, probably due to board reset. Continuing ..."); } } @@ -1163,7 +1216,7 @@ export class CPInstallButton extends InstallButton { if (fileContents) { return toml.parse(fileContents); } - this.logMsg("Unable to read settings.toml from CircuitPython. It may not exist. Continuing..."); + this.logMsg("Unable to read settings.toml from CircuitPython. It may not exist. Continuing ..."); return {}; } @@ -1230,7 +1283,7 @@ export class CPInstallButton extends InstallButton { // Perform a soft restart to avoid losing the connection and get an IP address this.showDialog(this.dialogs.actionWaiting, { - action: "Waiting for IP Address...", + action: "Waiting for IP Address ...", }); await this.repl.softRestart(); try { @@ -1270,7 +1323,7 @@ export class CPInstallButton extends InstallButton { if (fileContents) { return toml.parse(fileContents); } - this.logMsg("Unable to read settings.toml from CircuitPython. It may not exist. Continuing..."); + this.logMsg("Unable to read settings.toml from CircuitPython. It may not exist. Continuing ..."); return {}; } @@ -1353,4 +1406,4 @@ export class CPInstallButton extends InstallButton { } } -customElements.define('cp-install-button', CPInstallButton, {extends: "button"}); \ No newline at end of file +customElements.define('cp-install-button', CPInstallButton, {extends: "button"});