diff --git a/CHANGELOG.md b/CHANGELOG.md index f08969bf..ee1fd02b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,33 @@ ## [Unreleased] +## [2.0.0] - 2022-12-20 + ### Added - Added Windows DFU USB driver installation instructions ([support#858]). ### Changed - Clicking empty area of file list focuses the list ([support#856]). +- Various text, style and accessibility fixes and improvements. +- Updated dependencies. +- Updated firmware to v3.2.0: + + #### Changed + - Buffered stdout is flushed before ending user program. + + #### Fixed + - Fixed SPIKE/MINDSTORMS hubs advertising after disconnect while user program + is still running ([support#849]). + - Fixed Essential hub hanging on boot when bootloader entered but USB cable + not connected ([support#821]). + - Fixed button needs debouncing on City/Technic/Essential hubs ([support#716]). + - Fixed motor hold drifting away under external input movement ([support#863]). + + [support#716]: https://github.com/pybricks/support/issues/716 + [support#821]: https://github.com/pybricks/support/issues/821 + [support#849]: https://github.com/pybricks/support/issues/849 + [support#863]: https://github.com/pybricks/support/issues/863 + [support#856]: https://github.com/pybricks/support/issues/856 [support#858]: https://github.com/pybricks/support/issues/858 @@ -598,7 +620,8 @@ Prerelease changes are documented at [support#48]. -[Unreleased]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-rc.1...HEAD +[Unreleased]: https://github.com/pybricks/pybricks-code/compare/v2.0.0...HEAD +[2.0.0]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-rc.1...v2.0.0 [2.0.0-rc.1]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-beta.12...v2.0.0-rc.1 [2.0.0-beta.12]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-beta.11...v2.0.0-beta.12 [2.0.0-beta.11]: https://github.com/pybricks/pybricks-code/compare/v2.0.0-beta.10...v2.0.0-beta.11 diff --git a/package.json b/package.json index 746e0717..9483dacc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pybricks/pybricks-code", - "version": "2.0.0-rc.1", + "version": "2.0.0", "license": "MIT", "author": "The Pybricks Authors", "repository": { @@ -13,7 +13,7 @@ "@blueprintjs/popover2": "^1.10.2", "@blueprintjs/select": "^4.8.12", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", - "@pybricks/firmware": "6.4.0", + "@pybricks/firmware": "6.5.0", "@pybricks/ide-docs": "2.7.0", "@pybricks/images": "^1.3.0", "@pybricks/jedi": "1.6.0", diff --git a/src/ble/sagas.ts b/src/ble/sagas.ts index b22c3363..e5aa87e8 100644 --- a/src/ble/sagas.ts +++ b/src/ble/sagas.ts @@ -8,7 +8,7 @@ import { firmwareVersion } from '@pybricks/firmware'; import { Task, buffers, eventChannel } from 'redux-saga'; -import { satisfies } from 'semver'; +import { lt, satisfies } from 'semver'; import { call, cancel, @@ -223,9 +223,9 @@ function* handleBleConnectPybricks(): Generator { // notify user if old firmware if ( - satisfies( + lt( pythonVersionToSemver(firmwareRevision), - `<${pythonVersionToSemver(firmwareVersion)}`, + pythonVersionToSemver(firmwareVersion), ) ) { yield* put(alertsShowAlert('ble', 'oldFirmware')); diff --git a/src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.tsx b/src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.tsx index 9552f737..ab9c0886 100644 --- a/src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.tsx +++ b/src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.tsx @@ -358,57 +358,23 @@ const DfuWindowsDriverInstallDialog: React.VoidFunctionComponent = () => { className="pb-dfu-windows-driver-install-dialog" isOpen={isOpen} onClose={() => dispatch(firmwareDfuWindowsDriverInstallDialogDialogHide())} + backButtonProps={{ text: i18n.translate('backButton.label') }} + nextButtonProps={{ text: i18n.translate('nextButton.label') }} finalButtonProps={{ text: i18n.translate('doneButton.label'), onClick: () => dispatch(firmwareDfuWindowsDriverInstallDialogDialogHide()), }} > - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> - } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} - /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> ); }; diff --git a/src/firmware/dfuWindowsDriverInstallDialog/translations/en.json b/src/firmware/dfuWindowsDriverInstallDialog/translations/en.json index 5e358435..7eb4e111 100644 --- a/src/firmware/dfuWindowsDriverInstallDialog/translations/en.json +++ b/src/firmware/dfuWindowsDriverInstallDialog/translations/en.json @@ -1,5 +1,8 @@ { "title": "Windows DFU USB driver installation instructions", + "backButton": { + "label": "Back" + }, "nextButton": { "label": "Next" }, @@ -18,7 +21,7 @@ "properties": "Properties", "listedWithWarning": "If it is listed with a warning sign, right-click it and select {properties}.", "listedWithoutWarning": "If it is listed somewhere else without a warning sign, then the driver is already installed. You may close this window.", - "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." + "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." }, "3": { "message": "In the {properties} dialog, click the {updateDriver} button.", diff --git a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx index 27f124ad..3f0cec69 100644 --- a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx +++ b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx @@ -461,6 +461,8 @@ export const InstallPybricksDialog: React.VoidFunctionComponent = () => { title={i18n.translate('title')} isOpen={isOpen} onClose={() => dispatch(firmwareInstallPybricksDialogCancel())} + backButtonProps={{ text: i18n.translate('backButton.label') }} + nextButtonProps={{ text: i18n.translate('nextButton.label') }} finalButtonProps={{ text: i18n.translate('flashFirmwareButton.label'), onClick: () => @@ -482,7 +484,6 @@ export const InstallPybricksDialog: React.VoidFunctionComponent = () => { onCustomFirmwareZip={setCustomFirmwareZip} /> } - nextButtonProps={{ text: i18n.translate('nextButton.label') }} /> { onLicenseAcceptedChanged={setLicenseAccepted} /> } - backButtonProps={{ text: i18n.translate('backButton.label') }} nextButtonProps={{ disabled: !licenseAccepted, text: i18n.translate('nextButton.label'), @@ -510,14 +510,11 @@ export const InstallPybricksDialog: React.VoidFunctionComponent = () => { onChangeHubName={setHubName} /> } - backButtonProps={{ text: i18n.translate('backButton.label') }} - nextButtonProps={{ text: i18n.translate('nextButton.label') }} /> } - backButtonProps={{ text: i18n.translate('backButton.label') }} /> ); diff --git a/src/firmware/restoreOfficialDialog/RestoreOfficialDialog.tsx b/src/firmware/restoreOfficialDialog/RestoreOfficialDialog.tsx index 7f9c5bce..98f2bdc4 100644 --- a/src/firmware/restoreOfficialDialog/RestoreOfficialDialog.tsx +++ b/src/firmware/restoreOfficialDialog/RestoreOfficialDialog.tsx @@ -33,9 +33,7 @@ const SelectHubPanel: React.VoidFunctionComponent = () => {

{i18n.translate('selectHubPanel.message', { lego: legoRegisteredTrademark, - next: ( - {i18n.translate('selectHubPanel.nextButton')} - ), + next: {i18n.translate('nextButton.label')}, })}

@@ -96,6 +94,8 @@ const RestoreOfficialDialog: React.VoidFunctionComponent = () => { isOpen={isOpen} title={i18n.translate('title', { lego: legoRegisteredTrademark })} onClose={() => dispatch(firmwareRestoreOfficialDialogHide())} + backButtonProps={{ text: i18n.translate('backButton.label') }} + nextButtonProps={{ text: i18n.translate('nextButton.label') }} finalButtonProps={{ text: i18n.translate('doneButton.label'), onClick: () => dispatch(firmwareRestoreOfficialDialogHide()), @@ -105,7 +105,6 @@ const RestoreOfficialDialog: React.VoidFunctionComponent = () => { id="hub" title={i18n.translate('selectHubPanel.title')} panel={} - nextButtonProps={{ text: i18n.translate('selectHubPanel.nextButton') }} /> = (state = null, action) = if (blePybricksServiceDidNotReceiveHubCapabilities.matches(action)) { // HACK: there is not a good way to get the supported MPY ABI version // from a running hub, so we use heuristics on the firmware version. - if ( - semver.satisfies( - pythonVersionToSemver(action.firmwareVersion), - '>=3.2.0-beta.2', - ) - ) { + if (semver.lte(pythonVersionToSemver(action.firmwareVersion), '3.2.0-beta.2')) { return FileFormat.Mpy6; } diff --git a/src/utils/version.test.ts b/src/utils/version.test.ts index 1757f301..f5f62bef 100644 --- a/src/utils/version.test.ts +++ b/src/utils/version.test.ts @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2021 The Pybricks Authors +// Copyright (c) 2021-2022 The Pybricks Authors +import { lt } from 'semver'; import { pythonVersionToSemver } from './version'; describe('pythonVersionToSemver', () => { @@ -14,6 +15,16 @@ describe('pythonVersionToSemver', () => { expect(pythonVersionToSemver(version)).toBe(expected); }); + test.each([ + ['v1.0.0a1', 'v1.0.0b1'], + ['v1.0.0b1', 'v1.0.0c1'], + ['v1.0.0c1', 'v1.0.0'], + ])('%s < %s', (first, second) => { + expect( + lt(pythonVersionToSemver(first), pythonVersionToSemver(second)), + ).toBeTruthy(); + }); + test('invalid version', () => { expect(() => pythonVersionToSemver('not a version')).toThrow(); }); diff --git a/yarn.lock b/yarn.lock index 3ac88835..7e4fbbe7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2359,12 +2359,12 @@ __metadata: languageName: node linkType: hard -"@pybricks/firmware@npm:6.4.0": - version: 6.4.0 - resolution: "@pybricks/firmware@npm:6.4.0" +"@pybricks/firmware@npm:6.5.0": + version: 6.5.0 + resolution: "@pybricks/firmware@npm:6.5.0" dependencies: jszip: ^3.7.1 - checksum: 47034fc21755840c0740f7c960aead07d5e4f3a020be42456ec3c0eb59af63fdfd5b39cf52155830fd1ea630c4d1adb6d7130978050c12f9d19da5771c9931d0 + checksum: 1c2518d4e9f8ef2a76be60a30af734b441dbb336b398d7759481f20392e3378e0dbd5927b0f6754f7c29b26e03d3adf78ff2fbb687779fad2f492a3117ce3efa languageName: node linkType: hard @@ -2412,7 +2412,7 @@ __metadata: "@blueprintjs/popover2": ^1.10.2 "@blueprintjs/select": ^4.8.12 "@pmmmwh/react-refresh-webpack-plugin": ^0.5.10 - "@pybricks/firmware": 6.4.0 + "@pybricks/firmware": 6.5.0 "@pybricks/ide-docs": 2.7.0 "@pybricks/images": ^1.3.0 "@pybricks/jedi": 1.6.0