Skip to content

Commit 2f4811e

Browse files
authored
Merge pull request #1396 from pybricks/dlech
v2.0.0
2 parents dd322b5 + 49e9606 commit 2f4811e

File tree

11 files changed

+74
-75
lines changed

11 files changed

+74
-75
lines changed

CHANGELOG.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,33 @@
44

55
## [Unreleased]
66

7+
## [2.0.0] - 2022-12-20
8+
79
### Added
810
- Added Windows DFU USB driver installation instructions ([support#858]).
911

1012
### Changed
1113
- Clicking empty area of file list focuses the list ([support#856]).
14+
- Various text, style and accessibility fixes and improvements.
15+
- Updated dependencies.
16+
- Updated firmware to v3.2.0:
17+
18+
#### Changed
19+
- Buffered stdout is flushed before ending user program.
20+
21+
#### Fixed
22+
- Fixed SPIKE/MINDSTORMS hubs advertising after disconnect while user program
23+
is still running ([support#849]).
24+
- Fixed Essential hub hanging on boot when bootloader entered but USB cable
25+
not connected ([support#821]).
26+
- Fixed button needs debouncing on City/Technic/Essential hubs ([support#716]).
27+
- Fixed motor hold drifting away under external input movement ([support#863]).
28+
29+
[support#716]: https://github.com/pybricks/support/issues/716
30+
[support#821]: https://github.com/pybricks/support/issues/821
31+
[support#849]: https://github.com/pybricks/support/issues/849
32+
[support#863]: https://github.com/pybricks/support/issues/863
33+
1234

1335
[support#856]: https://github.com/pybricks/support/issues/856
1436
[support#858]: https://github.com/pybricks/support/issues/858
@@ -598,7 +620,8 @@ Prerelease changes are documented at [support#48].
598620

599621
<!-- links for version headings -->
600622

601-
[Unreleased]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-rc.1...HEAD
623+
[Unreleased]: https://github.com/pybricks/pybricks-code/compare/v2.0.0...HEAD
624+
[2.0.0]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-rc.1...v2.0.0
602625
[2.0.0-rc.1]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-beta.12...v2.0.0-rc.1
603626
[2.0.0-beta.12]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-beta.11...v2.0.0-beta.12
604627
[2.0.0-beta.11]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-beta.10...v2.0.0-beta.11

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pybricks/pybricks-code",
3-
"version": "2.0.0-rc.1",
3+
"version": "2.0.0",
44
"license": "MIT",
55
"author": "The Pybricks Authors",
66
"repository": {
@@ -13,7 +13,7 @@
1313
"@blueprintjs/popover2": "^1.10.2",
1414
"@blueprintjs/select": "^4.8.12",
1515
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
16-
"@pybricks/firmware": "6.4.0",
16+
"@pybricks/firmware": "6.5.0",
1717
"@pybricks/ide-docs": "2.7.0",
1818
"@pybricks/images": "^1.3.0",
1919
"@pybricks/jedi": "1.6.0",

src/ble/sagas.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import { firmwareVersion } from '@pybricks/firmware';
1010
import { Task, buffers, eventChannel } from 'redux-saga';
11-
import { satisfies } from 'semver';
11+
import { lt, satisfies } from 'semver';
1212
import {
1313
call,
1414
cancel,
@@ -223,9 +223,9 @@ function* handleBleConnectPybricks(): Generator {
223223

224224
// notify user if old firmware
225225
if (
226-
satisfies(
226+
lt(
227227
pythonVersionToSemver(firmwareRevision),
228-
`<${pythonVersionToSemver(firmwareVersion)}`,
228+
pythonVersionToSemver(firmwareVersion),
229229
)
230230
) {
231231
yield* put(alertsShowAlert('ble', 'oldFirmware'));

src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.tsx

Lines changed: 11 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -358,57 +358,23 @@ const DfuWindowsDriverInstallDialog: React.VoidFunctionComponent = () => {
358358
className="pb-dfu-windows-driver-install-dialog"
359359
isOpen={isOpen}
360360
onClose={() => dispatch(firmwareDfuWindowsDriverInstallDialogDialogHide())}
361+
backButtonProps={{ text: i18n.translate('backButton.label') }}
362+
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
361363
finalButtonProps={{
362364
text: i18n.translate('doneButton.label'),
363365
onClick: () =>
364366
dispatch(firmwareDfuWindowsDriverInstallDialogDialogHide()),
365367
}}
366368
>
367-
<DialogStep
368-
id="1"
369-
panel={<Step1 />}
370-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
371-
/>
372-
<DialogStep
373-
id="2"
374-
panel={<Step2 hub={hub} />}
375-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
376-
/>
377-
<DialogStep
378-
id="3"
379-
panel={<Step3 hub={hub} />}
380-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
381-
/>
382-
<DialogStep
383-
id="4"
384-
panel={<Step4 hub={hub} />}
385-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
386-
/>
387-
<DialogStep
388-
id="5"
389-
panel={<Step5 hub={hub} />}
390-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
391-
/>
392-
<DialogStep
393-
id="6"
394-
panel={<Step6 hub={hub} />}
395-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
396-
/>
397-
<DialogStep
398-
id="7"
399-
panel={<Step7 hub={hub} />}
400-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
401-
/>
402-
<DialogStep
403-
id="8"
404-
panel={<Step8 />}
405-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
406-
/>
407-
<DialogStep
408-
id="9"
409-
panel={<Step9 hub={hub} />}
410-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
411-
/>
369+
<DialogStep id="1" panel={<Step1 />} />
370+
<DialogStep id="2" panel={<Step2 hub={hub} />} />
371+
<DialogStep id="3" panel={<Step3 hub={hub} />} />
372+
<DialogStep id="4" panel={<Step4 hub={hub} />} />
373+
<DialogStep id="5" panel={<Step5 hub={hub} />} />
374+
<DialogStep id="6" panel={<Step6 hub={hub} />} />
375+
<DialogStep id="7" panel={<Step7 hub={hub} />} />
376+
<DialogStep id="8" panel={<Step8 />} />
377+
<DialogStep id="9" panel={<Step9 hub={hub} />} />
412378
</MultistepDialog>
413379
);
414380
};

src/firmware/dfuWindowsDriverInstallDialog/translations/en.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"title": "Windows DFU USB driver installation instructions",
3+
"backButton": {
4+
"label": "Back"
5+
},
36
"nextButton": {
47
"label": "Next"
58
},
@@ -18,7 +21,7 @@
1821
"properties": "Properties",
1922
"listedWithWarning": "If it is listed with a warning sign, right-click it and select {properties}.",
2023
"listedWithoutWarning": "If it is listed somewhere else without a warning sign, then the driver is already installed. You may close this window.",
21-
"notListed": "If you don't see it at all, make sure the hub is in DFU update mode (see video on the previous page) and try again."
24+
"notListed": "If you don't see it at all, make sure that the hub is in DFU update mode and try again. Close this window to watch the video instructions."
2225
},
2326
"3": {
2427
"message": "In the {properties} dialog, click the {updateDriver} button.",

src/firmware/installPybricksDialog/InstallPybricksDialog.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,8 @@ export const InstallPybricksDialog: React.VoidFunctionComponent = () => {
461461
title={i18n.translate('title')}
462462
isOpen={isOpen}
463463
onClose={() => dispatch(firmwareInstallPybricksDialogCancel())}
464+
backButtonProps={{ text: i18n.translate('backButton.label') }}
465+
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
464466
finalButtonProps={{
465467
text: i18n.translate('flashFirmwareButton.label'),
466468
onClick: () =>
@@ -482,7 +484,6 @@ export const InstallPybricksDialog: React.VoidFunctionComponent = () => {
482484
onCustomFirmwareZip={setCustomFirmwareZip}
483485
/>
484486
}
485-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
486487
/>
487488
<DialogStep
488489
id="license"
@@ -495,7 +496,6 @@ export const InstallPybricksDialog: React.VoidFunctionComponent = () => {
495496
onLicenseAcceptedChanged={setLicenseAccepted}
496497
/>
497498
}
498-
backButtonProps={{ text: i18n.translate('backButton.label') }}
499499
nextButtonProps={{
500500
disabled: !licenseAccepted,
501501
text: i18n.translate('nextButton.label'),
@@ -510,14 +510,11 @@ export const InstallPybricksDialog: React.VoidFunctionComponent = () => {
510510
onChangeHubName={setHubName}
511511
/>
512512
}
513-
backButtonProps={{ text: i18n.translate('backButton.label') }}
514-
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
515513
/>
516514
<DialogStep
517515
id="bootloader"
518516
title={i18n.translate('bootloaderPanel.title')}
519517
panel={<BootloaderModePanel hubType={selectedHubType} />}
520-
backButtonProps={{ text: i18n.translate('backButton.label') }}
521518
/>
522519
</MultistepDialog>
523520
);

src/firmware/restoreOfficialDialog/RestoreOfficialDialog.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ const SelectHubPanel: React.VoidFunctionComponent = () => {
3333
<p>
3434
{i18n.translate('selectHubPanel.message', {
3535
lego: legoRegisteredTrademark,
36-
next: (
37-
<strong>{i18n.translate('selectHubPanel.nextButton')}</strong>
38-
),
36+
next: <strong>{i18n.translate('nextButton.label')}</strong>,
3937
})}
4038
</p>
4139
<div className="pb-spacer" />
@@ -96,6 +94,8 @@ const RestoreOfficialDialog: React.VoidFunctionComponent = () => {
9694
isOpen={isOpen}
9795
title={i18n.translate('title', { lego: legoRegisteredTrademark })}
9896
onClose={() => dispatch(firmwareRestoreOfficialDialogHide())}
97+
backButtonProps={{ text: i18n.translate('backButton.label') }}
98+
nextButtonProps={{ text: i18n.translate('nextButton.label') }}
9999
finalButtonProps={{
100100
text: i18n.translate('doneButton.label'),
101101
onClick: () => dispatch(firmwareRestoreOfficialDialogHide()),
@@ -105,7 +105,6 @@ const RestoreOfficialDialog: React.VoidFunctionComponent = () => {
105105
id="hub"
106106
title={i18n.translate('selectHubPanel.title')}
107107
panel={<SelectHubPanel />}
108-
nextButtonProps={{ text: i18n.translate('selectHubPanel.nextButton') }}
109108
/>
110109
<DialogStep
111110
id="restore"

src/firmware/restoreOfficialDialog/translations/en.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
{
22
"title": "Restore official {lego} Firmware",
3+
"backButton": {
4+
"label": "Back"
5+
},
6+
"nextButton": {
7+
"label": "Next"
8+
},
39
"doneButton": {
410
"label": "Done"
511
},
612
"selectHubPanel": {
713
"title": "Select hub",
8-
"message": "Select the hub to restore the official {lego} firmware on, then click {next}.",
9-
"nextButton": "Next"
14+
"message": "Select the hub to restore the official {lego} firmware on, then click {next}."
1015
},
1116
"restoreFirmwarePanel": {
1217
"title": "Restore firmware",

src/hub/reducers.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,7 @@ const preferredFileFormat: Reducer<FileFormat | null> = (state = null, action) =
193193
if (blePybricksServiceDidNotReceiveHubCapabilities.matches(action)) {
194194
// HACK: there is not a good way to get the supported MPY ABI version
195195
// from a running hub, so we use heuristics on the firmware version.
196-
if (
197-
semver.satisfies(
198-
pythonVersionToSemver(action.firmwareVersion),
199-
'>=3.2.0-beta.2',
200-
)
201-
) {
196+
if (semver.lte(pythonVersionToSemver(action.firmwareVersion), '3.2.0-beta.2')) {
202197
return FileFormat.Mpy6;
203198
}
204199

src/utils/version.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2021 The Pybricks Authors
2+
// Copyright (c) 2021-2022 The Pybricks Authors
33

4+
import { lt } from 'semver';
45
import { pythonVersionToSemver } from './version';
56

67
describe('pythonVersionToSemver', () => {
@@ -14,6 +15,16 @@ describe('pythonVersionToSemver', () => {
1415
expect(pythonVersionToSemver(version)).toBe(expected);
1516
});
1617

18+
test.each([
19+
['v1.0.0a1', 'v1.0.0b1'],
20+
['v1.0.0b1', 'v1.0.0c1'],
21+
['v1.0.0c1', 'v1.0.0'],
22+
])('%s < %s', (first, second) => {
23+
expect(
24+
lt(pythonVersionToSemver(first), pythonVersionToSemver(second)),
25+
).toBeTruthy();
26+
});
27+
1728
test('invalid version', () => {
1829
expect(() => pythonVersionToSemver('not a version')).toThrow();
1930
});

0 commit comments

Comments
 (0)