Skip to content

Commit 882f956

Browse files
authored
Merge pull request #225 from makermelissa/beta
Show more info for all workflows
2 parents a1d705f + e6b6652 commit 882f956

File tree

14 files changed

+184
-1059
lines changed

14 files changed

+184
-1059
lines changed

.github/workflows/build.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ jobs:
1212
- uses: actions/checkout@v4
1313
- uses: actions/setup-node@v4
1414
with:
15-
node-version: 16
15+
node-version: 22
1616
cache: 'npm'
17+
- run: rm -rf node_modules
18+
- run: rm package-lock.json
19+
- run: npm install
1720
- run: npm ci
1821
- run: npm run build

index.html

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,22 @@ <h1>Select USB Host Folder</h1>
325325
<td>IP Address:</td>
326326
<td><a id="ip"></a></td>
327327
</tr>
328+
<tr>
329+
<td>Build Date:</td>
330+
<td><span id="builddate"></span></td>
331+
</tr>
332+
<tr>
333+
<td>MCU Name:</td>
334+
<td><span id="mcuname"></span></td>
335+
</tr>
336+
<tr>
337+
<td>Board ID:</td>
338+
<td><span id="boardid"></span></td>
339+
</tr>
340+
<tr>
341+
<td>UID:</td>
342+
<td><span id="uid"></span></td>
343+
</tr>
328344
</tbody>
329345
</table>
330346
<h3>More network devices<i class="refresh fa-solid fa-sync-alt" title="Refresh Device List"></i></h3>
@@ -333,6 +349,45 @@ <h3>More network devices<i class="refresh fa-solid fa-sync-alt" title="Refresh D
333349
<button class="purple-button ok-button">Close</button>
334350
</div>
335351
</div>
352+
<div class="popup-modal shadow closable" data-popup-modal="device-info">
353+
<i class="fa-solid fa-2x fa-xmark text-white bg-primary p-3 popup-modal__close"></i>
354+
<table class="device-info">
355+
<thead>
356+
<tr>
357+
<th colspan="2">Current Device Info</th>
358+
</tr>
359+
</thead>
360+
<tbody>
361+
<tr>
362+
<td>Board:</td>
363+
<td><a id="board" target="_blank"></a></td>
364+
</tr>
365+
<tr>
366+
<td>Version:</td>
367+
<td><span id="version"></span></td>
368+
</tr>
369+
<tr>
370+
<td>Build Date:</td>
371+
<td><span id="builddate"></span></td>
372+
</tr>
373+
<tr>
374+
<td>MCU Name:</td>
375+
<td><span id="mcuname"></span></td>
376+
</tr>
377+
<tr>
378+
<td>Board ID:</td>
379+
<td><span id="boardid"></span></td>
380+
</tr>
381+
<tr>
382+
<td>UID:</td>
383+
<td><span id="uid"></span></td>
384+
</tr>
385+
</tbody>
386+
</table>
387+
<div class="buttons centered">
388+
<button class="purple-button ok-button">Close</button>
389+
</div>
390+
</div>
336391

337392
<script type="module" src="/js/script.js"></script>
338393
</body>

js/common/ble-file-transfer.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {FileTransferClient as BLEFileTransferClient} from '@adafruit/ble-file-transfer-js';
2+
3+
// Wrapper for BLEFileTransferClient to add additional functionality
4+
class FileTransferClient extends BLEFileTransferClient {
5+
constructor(bleDevice, bufferSize) {
6+
super(bleDevice, bufferSize);
7+
}
8+
9+
async versionInfo() {
10+
// Possibly open /boot_out.txt and read the version info
11+
let versionInfo = {};
12+
console.log("Reading version info");
13+
let bootout = await this.readFile('/boot_out.txt', false);
14+
console.log(bootout);
15+
if (!bootout) {
16+
console.error("Unable to read boot_out.txt");
17+
return null;
18+
}
19+
bootout += "\n";
20+
21+
// Add these items as they are found
22+
const searchItems = {
23+
version: /Adafruit CircuitPython (.*?) on/,
24+
build_date: /on ([0-9]{4}-[0-9]{2}-[0-9]{2});/,
25+
board_name: /; (.*?) with/,
26+
mcu_name: /with (.*?)\r?\n/,
27+
board_id: /Board ID:(.*?)\r?\n/,
28+
uid: /UID:([0-9A-F]{12,16})\r?\n/,
29+
}
30+
31+
for (const [key, regex] of Object.entries(searchItems)) {
32+
const match = bootout.match(regex);
33+
34+
if (match) {
35+
versionInfo[key] = match[1];
36+
}
37+
}
38+
39+
return versionInfo;
40+
}
41+
}
42+
43+
export {FileTransferClient};

js/common/dialogs.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ class DiscoveryModal extends GenericModal {
329329
let ip = this._currentModal.querySelector("#ip");
330330
ip.href = `http://${deviceInfo.ip + port}/code/`;
331331
ip.textContent = deviceInfo.ip;
332+
this._currentModal.querySelector("#builddate").textContent = deviceInfo.build_date;
333+
this._currentModal.querySelector("#mcuname").textContent = deviceInfo.mcu_name;
334+
this._currentModal.querySelector("#boardid").textContent = deviceInfo.board_id;
335+
this._currentModal.querySelector("#uid").textContent = deviceInfo.uid;
332336
}
333337

334338
async _refreshDevices() {
@@ -378,11 +382,43 @@ class DiscoveryModal extends GenericModal {
378382
}
379383
}
380384

385+
class DeviceInfoModal extends GenericModal {
386+
async _getDeviceInfo() {
387+
const deviceInfo = await this._showBusy(this._fileHelper.versionInfo());
388+
this._currentModal.querySelector("#version").textContent = deviceInfo.version;
389+
const boardLink = this._currentModal.querySelector("#board");
390+
boardLink.href = `https://circuitpython.org/board/${deviceInfo.board_id}/`;
391+
boardLink.textContent = deviceInfo.board_name;
392+
this._currentModal.querySelector("#builddate").textContent = deviceInfo.build_date;
393+
this._currentModal.querySelector("#mcuname").textContent = deviceInfo.mcu_name;
394+
this._currentModal.querySelector("#boardid").textContent = deviceInfo.board_id;
395+
this._currentModal.querySelector("#uid").textContent = deviceInfo.uid;
396+
}
397+
398+
async open(workflow, documentState) {
399+
this._workflow = workflow;
400+
this._fileHelper = workflow.fileHelper;
401+
this._showBusy = workflow.showBusy.bind(workflow);
402+
this._docState = documentState;
403+
404+
let p = super.open();
405+
const okButton = this._currentModal.querySelector("button.ok-button");
406+
this._addDialogElement('okButton', okButton, 'click', this._closeModal);
407+
408+
const refreshIcon = this._currentModal.querySelector("i.refresh");
409+
this._addDialogElement('refreshIcon', refreshIcon, 'click', this._refreshDevices);
410+
411+
await this._getDeviceInfo();
412+
return p;
413+
}
414+
}
415+
381416
export {
382417
GenericModal,
383418
MessageModal,
384419
ButtonValueDialog,
385420
UnsavedDialog,
386421
DiscoveryModal,
387-
ProgressDialog
422+
ProgressDialog,
423+
DeviceInfoModal
388424
};

js/common/file_dialog.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const extensionMap = {
4242
"mp4": {style: FA_STYLE_REGULAR, icon: "file-video", type: "bin"},
4343
"mpy": {style: FA_STYLE_REGULAR, icon: "file", type: "bin"},
4444
"pdf": {style: FA_STYLE_REGULAR, icon: "file-pdf", type: "bin"},
45-
"py": {style: FA_STYLE_REGULAR, icon: "file-lines", type: "text"},
45+
"py": {style: FA_STYLE_REGULAR, icon: "file-code", type: "text"},
4646
"toml": {style: FA_STYLE_REGULAR, icon: "file-lines", type: "text"},
4747
"txt": {style: FA_STYLE_REGULAR, icon: "file-lines", type: "text"},
4848
"wav": {style: FA_STYLE_REGULAR, icon: "file-audio", type: "bin"},
@@ -57,6 +57,9 @@ const FILESIZE_UNITS = ["bytes", "KB", "MB", "GB", "TB"];
5757
const COMPACT_UNITS = ["", "K", "M", "G", "T"];
5858

5959
function getFileExtension(filename) {
60+
if (filename === null) {
61+
return null;
62+
}
6063
let extension = filename.split('.').pop();
6164
if (extension !== null) {
6265
return String(extension).toLowerCase();
@@ -189,7 +192,7 @@ class FileDialog extends GenericModal {
189192
this._currentPath = path;
190193
}
191194
const currentPathLabel = this._getElement('currentPathLabel');
192-
currentPathLabel.innerHTML = this._currentPath;
195+
currentPathLabel.innerHTML = `<i class="${FA_STYLE_REGULAR} fa-folder-open"></i> ` + this._currentPath;
193196

194197
if (this._currentPath != "/") {
195198
this._addFile({path: "..", isDir: true}, "fa-folder-open");

js/common/fsapi-file-transfer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,10 @@ class FileTransferClient {
325325
let bootout = await this.readFile('/boot_out.txt', false);
326326
console.log(bootout);
327327
if (!bootout) {
328+
console.error("Unable to read boot_out.txt");
328329
return null;
329330
}
331+
bootout += "\n";
330332

331333
// Add these items as they are found
332334
const searchItems = {
@@ -335,7 +337,7 @@ class FileTransferClient {
335337
board_name: /; (.*?) with/,
336338
mcu_name: /with (.*?)\r?\n/,
337339
board_id: /Board ID:(.*?)\r?\n/,
338-
uid: /UID:([0-9A-F]{12})\r?\n/,
340+
uid: /UID:([0-9A-F]{12,16})\r?\n/,
339341
}
340342

341343
for (const [key, regex] of Object.entries(searchItems)) {

js/common/repl-file-transfer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ class FileTransferClient {
9191
let bootout = await this.readFile('/boot_out.txt', false);
9292
console.log(bootout);
9393
if (!bootout) {
94+
console.error("Unable to read boot_out.txt");
9495
return null;
9596
}
97+
bootout += "\n";
9698

9799
// Add these items as they are found
98100
const searchItems = {
@@ -101,7 +103,7 @@ class FileTransferClient {
101103
board_name: /; (.*?) with/,
102104
mcu_name: /with (.*?)\r?\n/,
103105
board_id: /Board ID:(.*?)\r?\n/,
104-
uid: /UID:([0-9A-F]{12})\r?\n/,
106+
uid: /UID:([0-9A-F]{12,16})\r?\n/,
105107
}
106108

107109
for (const [key, regex] of Object.entries(searchItems)) {

js/script.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {indentWithTab} from "@codemirror/commands"
55
import { python } from "@codemirror/lang-python";
66
import { syntaxHighlighting, indentUnit } from "@codemirror/language";
77
import { classHighlighter } from "@lezer/highlight";
8+
import { getFileIcon } from "./common/file_dialog.js";
89

910
import { Terminal } from '@xterm/xterm';
1011
import { FitAddon } from '@xterm/addon-fit';
@@ -237,7 +238,13 @@ async function checkReadOnly() {
237238

238239
/* Update the filename and update the UI */
239240
function setFilename(path) {
241+
// Use the extension_map to figure out the file icon
240242
let filename = path;
243+
244+
// Prepend an icon to the path
245+
const [style, icon] = getFileIcon(path);
246+
filename = `<i class="${style} ${icon}"></i> ` + filename;
247+
241248
if (path === null) {
242249
filename = "[New Document]";
243250
btnSave.forEach((b) => b.style.display = 'none');

js/workflows/ble.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
* This class will encapsulate all of the workflow functions specific to BLE
33
*/
44

5-
import {FileTransferClient} from '@adafruit/ble-file-transfer-js';
6-
5+
import {FileTransferClient} from '../common/ble-file-transfer.js';
76
import {CONNTYPE, CONNSTATE} from '../constants.js';
87
import {Workflow} from './workflow.js';
9-
import {GenericModal} from '../common/dialogs.js';
8+
import {GenericModal, DeviceInfoModal} from '../common/dialogs.js';
109
import {sleep, getUrlParam} from '../common/utilities.js';
1110

1211
const bleNusServiceUUID = 'adaf0001-4369-7263-7569-74507974686e';
@@ -27,6 +26,7 @@ class BLEWorkflow extends Workflow {
2726
this.bleDevice = null;
2827
this.decoder = new TextDecoder();
2928
this.connectDialog = new GenericModal("ble-connect");
29+
this.infoDialog = new DeviceInfoModal("device-info");
3030
this.partialWrites = true;
3131
this.type = CONNTYPE.Ble;
3232
}
@@ -270,6 +270,10 @@ class BLEWorkflow extends Workflow {
270270
return true;
271271
}
272272

273+
async showInfo(documentState) {
274+
return await this.infoDialog.open(this, documentState);
275+
}
276+
273277
// Handle the different button states for various connection steps
274278
connectionStep(step) {
275279
const buttonStates = [

0 commit comments

Comments
 (0)