Skip to content

Commit b4fed9c

Browse files
authored
board id in title (#160)
1 parent 6e0a5ef commit b4fed9c

File tree

10 files changed

+457
-302
lines changed

10 files changed

+457
-302
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ REPL (Read-Evaluate-Print Loop) is a coding mode where you can interact with the
6262

6363
## About
6464

65-
Version: 2.2.1
65+
Version: 2.2.2
6666

6767
[CircuitPython](https://circuitpython.org/) is a version of Python that runs on microcontrollers and single-board computers. Its development is sponsored by [Adafruit](https://www.adafruit.com/).
6868

docs/index.html

Lines changed: 284 additions & 273 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "circuitpython-online-ide",
33
"private": true,
4-
"version": "2.2.0",
4+
"version": "2.2.2",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src/App.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ function App() {
9797
return;
9898
}
9999
const boot_out_txt = await getFromPath(rootDirHandle, "boot_out.txt");
100-
setBoardInfo(parseCircuitPythonInfo(boot_out_txt));
100+
const board_info = parseCircuitPythonInfo(boot_out_txt);
101+
console.log("board_info:", board_info);
102+
setBoardInfo(board_info);
101103
}
102104
getBoardInfo();
103105
}, [rootFolderDirectoryReady, rootDirHandle]);
@@ -107,6 +109,10 @@ function App() {
107109
return;
108110
}
109111

112+
if (appConfig.config.general.show_board_id && boardInfo) {
113+
document.title = "CPy: " + boardInfo.board_id.split("_").join(" ");
114+
}
115+
110116
// theme config
111117
let dark = null;
112118
let highContrast = false;

src/components/Navigation.jsx

Lines changed: 129 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
// React
2-
import { useContext } from "react";
2+
import { useContext, useEffect, useState } from "react";
33
import Typography from "@mui/material/Typography";
44
//context
55
import AppContext from "../AppContext";
66
// mui
77
import Button from "@mui/material/Button";
8+
// add table imports
9+
import Table from "@mui/material/Table";
10+
import TableBody from "@mui/material/TableBody";
11+
import TableCell from "@mui/material/TableCell";
12+
import TableContainer from "@mui/material/TableContainer";
13+
import TableHead from "@mui/material/TableHead";
14+
import TableRow from "@mui/material/TableRow";
15+
import Paper from "@mui/material/Paper";
816
// theme
917
import { NoTheme } from "react-lazy-dark-theme";
18+
// board info
19+
import { fetchLatestCircuitPythonInfo } from "../utilFunctions/baordInfoUtils";
20+
import { compareVersions, versionToString, parseVersion } from "../utilFunctions/installedLibUtils";
1021

1122
const video_parent_css = {
1223
position: "relative",
@@ -25,28 +36,77 @@ const video_css = {
2536
height: "100%",
2637
};
2738

39+
function InstallCpy() {
40+
const { boardInfo } = useContext(AppContext);
41+
const [cpyInfo, setCpyInfo] = useState(null);
42+
useEffect(() => {
43+
const fetchCpyInfo = async () => {
44+
const cpy_info = await fetchLatestCircuitPythonInfo();
45+
setCpyInfo(cpy_info);
46+
};
47+
fetchCpyInfo();
48+
}, []);
49+
50+
if (boardInfo && cpyInfo && compareVersions(cpyInfo.version, boardInfo.cpy_version) > 0) {
51+
return (
52+
<>
53+
Step 0.
54+
<Button
55+
onClick={() => {
56+
window.open(`https://circuitpython.org/board/${boardInfo.board_id}/`, "_blank");
57+
}}
58+
>
59+
Update to {cpyInfo.name}
60+
</Button>
61+
(Optional)
62+
</>
63+
);
64+
}
65+
66+
return (
67+
<>
68+
Step 0.
69+
<Button
70+
onClick={() => {
71+
window.open(
72+
"https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython",
73+
"_blank"
74+
);
75+
}}
76+
>
77+
Install CircuitPython
78+
</Button>
79+
(Skip if installed recently)
80+
</>
81+
);
82+
}
83+
2884
export default function Navigation() {
29-
const { openDirectory, rootFolderDirectoryReady, serialReady, connectToSerialPort, appConfig } =
85+
const { openDirectory, rootFolderDirectoryReady, serialReady, connectToSerialPort, appConfig, boardInfo } =
3086
useContext(AppContext);
87+
const [cpyInfo, setCpyInfo] = useState(null);
88+
useEffect(() => {
89+
const fetchCpyInfo = async () => {
90+
const cpy_info = await fetchLatestCircuitPythonInfo();
91+
setCpyInfo(cpy_info);
92+
};
93+
fetchCpyInfo();
94+
}, []);
3195

3296
return (
3397
<Typography component="div" sx={{ margin: "20pt" }}>
34-
<p> Please connect your microcontroller to this computer by a usb data cable before following the steps.</p>
98+
<p>
99+
Please connect your microcontroller to this computer by a <b>USB data cable</b> before following the
100+
steps.
101+
</p>
102+
<p>
103+
If you have not installed CircuitPython on your microcontroller, please check{" "}
104+
<a href="https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython">
105+
<b>this tutorial</b>
106+
</a>{" "}
107+
first.
108+
</p>
35109
<ul>
36-
<li>
37-
Step 0.
38-
<Button
39-
onClick={() => {
40-
window.open(
41-
"https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython",
42-
"_blank"
43-
);
44-
}}
45-
>
46-
Install CircuitPython
47-
</Button>
48-
(Skip if installed recently)
49-
</li>
50110
<li>
51111
Step 1. <Button onClick={openDirectory}>Open CircuitPy Drive</Button>
52112
{rootFolderDirectoryReady ? "✅" : ""}
@@ -62,18 +122,16 @@ export default function Navigation() {
62122
</Button>
63123
{serialReady ? "✅" : ""}
64124
</li>
65-
{serialReady && rootFolderDirectoryReady ? (
66-
<li>🎉 Setup complete! Open your files and let's start coding!</li>
67-
) : (
68-
""
69-
)}
70125
</ul>
71126

127+
{serialReady && rootFolderDirectoryReady && (
128+
<p>🎉 Setup complete! Open your files and let's start coding!</p>
129+
)}
130+
72131
<NoTheme style={{ width: "100%" }}>
73132
<div style={video_parent_css}>
74133
<iframe
75134
style={video_css}
76-
frameBorder={0}
77135
src="https://www.youtube.com/embed/kq554m21G4A?si=xLRUJNfd6tvAqGuH&cc_load_policy=1&cc_lang_pref=en"
78136
title="Quick Start Guide"
79137
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
@@ -82,6 +140,54 @@ export default function Navigation() {
82140
></iframe>
83141
</div>
84142
</NoTheme>
143+
144+
{boardInfo && cpyInfo && compareVersions(cpyInfo.version, boardInfo.cpy_version) > 0 && (
145+
<Typography component="div">
146+
<p>
147+
⬆️ New CircuitPython version {versionToString(cpyInfo.version)} is available!{" "}
148+
<a href={`https://circuitpython.org/board/${boardInfo.board_id}/`}>
149+
<b>Click here to upgrade.</b>
150+
</a>
151+
</p>
152+
<TableContainer component={Paper} sx={{ marginTop: 2 }}>
153+
<Table size="small" aria-label="board info">
154+
<TableHead>
155+
<TableRow>
156+
<TableCell></TableCell>
157+
<TableCell>
158+
<strong>Version</strong>
159+
</TableCell>
160+
<TableCell>
161+
<strong>Update Date</strong>
162+
</TableCell>
163+
</TableRow>
164+
</TableHead>
165+
<TableBody>
166+
<TableRow>
167+
<TableCell component="th" scope="row">
168+
Currently installed
169+
</TableCell>
170+
<TableCell component="th" scope="row">
171+
{versionToString(boardInfo.cpy_version)}
172+
</TableCell>
173+
<TableCell>{boardInfo.cpy_datetime}</TableCell>
174+
</TableRow>
175+
</TableBody>
176+
<TableBody>
177+
<TableRow>
178+
<TableCell component="th" scope="row">
179+
Latest available
180+
</TableCell>
181+
<TableCell component="th" scope="row">
182+
{versionToString(cpyInfo.version)}
183+
</TableCell>
184+
<TableCell>{cpyInfo.datetime}</TableCell>
185+
</TableRow>
186+
</TableBody>
187+
</Table>
188+
</TableContainer>
189+
</Typography>
190+
)}
85191
</Typography>
86192
);
87193
}

src/configs/general.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
"title": "Show time in menu bar",
1515
"type": "boolean",
1616
"default": true
17+
},
18+
"show_board_id": {
19+
"title": "Use board id as title",
20+
"type": "boolean",
21+
"default": false
1722
}
1823
}
1924
}

src/docs/About.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## CircuitPython Online IDE
22

3-
Version: 2.2.1
3+
Version: 2.2.2
44

55
[CircuitPython](https://circuitpython.org/) is a version of Python that runs on microcontrollers and single-board computers. Its development is sponsored by [Adafruit](https://www.adafruit.com/).
66

src/docs/Version history.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## Version 2.2.2
2+
Released on October 30th, 2025
3+
4+
Significant updates from version 2.2.1 include:
5+
- Board Information related enhancement
6+
- Added an option to use device ID as title
7+
- Added CircuitPython upgrade information in the Navigation page.
8+
- Re-organized Navigation page
9+
10+
111
## Version 2.2.1
212
Released on October 30th, 2025
313

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { minor } from "@mui/material";
2+
import { version } from "jszip";
3+
4+
export async function fetchLatestCircuitPythonInfo(repo) {
5+
const response = await fetch(`https://api.github.com/repos/adafruit/CircuitPython/releases/latest`);
6+
const data = await response.json();
7+
console.log(data);
8+
return {
9+
datetime: data.published_at.split("T").at(0),
10+
version: {
11+
major: parseInt(data.tag_name.split(".").at(0)),
12+
minor: parseInt(data.tag_name.split(".").at(1)),
13+
patch: parseInt(data.tag_name.split(".").at(2)),
14+
},
15+
name: data.name,
16+
};
17+
}

src/utilFunctions/installedLibUtils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,8 @@ export function compareVersions(a, b) {
409409
const [aMaj, aMin, aPat] = toNums(a);
410410
const [bMaj, bMin, bPat] = toNums(b);
411411

412-
if (aMaj !== bMaj) return aMaj < bMaj ? -1 : 1;
413-
if (aMin !== bMin) return aMin < bMin ? -1 : 1;
412+
if (aMaj !== bMaj) return aMaj < bMaj ? -100 : 100;
413+
if (aMin !== bMin) return aMin < bMin ? -10 : 10;
414414
if (aPat !== bPat) return aPat < bPat ? -1 : 1;
415415
return 0;
416416
}

0 commit comments

Comments
 (0)