From 6a74a6a515f5ac15809d7ff9754c275fd88f340b Mon Sep 17 00:00:00 2001 From: Attila Farago Date: Wed, 17 Jul 2024 19:49:41 +0200 Subject: [PATCH 1/3] keep the connected hub name if any for flashing firmware dialog --- src/firmware/installPybricksDialog/InstallPybricksDialog.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx index b5643ab6e..ce45ce8c0 100644 --- a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx +++ b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022-2023 The Pybricks Authors +// Copyright (c) 2022-2024 The Pybricks Authors import './installPybricksDialog.scss'; import { @@ -450,6 +450,7 @@ const BootloaderModePanel: React.FunctionComponent = ( export const InstallPybricksDialog: React.FunctionComponent = () => { const { isOpen } = useSelector((s) => s.firmware.installPybricksDialog); + const deviceName = useSelector((s) => s.ble.deviceName); const inProgress = useSelector( (s) => s.firmware.isFirmwareFlashUsbDfuInProgress || @@ -527,7 +528,7 @@ export const InstallPybricksDialog: React.FunctionComponent = () => { title={i18n.translate('optionsPanel.title')} panel={ Date: Wed, 17 Jul 2024 19:56:05 +0200 Subject: [PATCH 2/3] keep the last connected device name in memory --- src/ble/reducers.ts | 11 ++++++++++- .../installPybricksDialog/InstallPybricksDialog.tsx | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ble/reducers.ts b/src/ble/reducers.ts index 808a42fa6..8c526c391 100644 --- a/src/ble/reducers.ts +++ b/src/ble/reducers.ts @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2020-2022 The Pybricks Authors +// Copyright (c) 2020-2024 The Pybricks Authors // // Manages state for the Bluetooth Low Energy connection. // This assumes that there is only one global connection to a single device. @@ -84,6 +84,14 @@ const deviceName: Reducer = (state = '', action) => { return state; }; +const deviceNameLastConnected: Reducer = (state = '', action) => { + if (bleDidConnectPybricks.matches(action)) { + return action.name; + } + + return state; +}; + const deviceType: Reducer = (state = '', action) => { if (bleDidDisconnectPybricks.matches(action)) { return ''; @@ -136,6 +144,7 @@ export default combineReducers({ connection, deviceName, deviceType, + deviceNameLastConnected, deviceFirmwareVersion, deviceLowBatteryWarning, deviceBatteryCharging, diff --git a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx index ce45ce8c0..4ef854429 100644 --- a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx +++ b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx @@ -450,7 +450,7 @@ const BootloaderModePanel: React.FunctionComponent = ( export const InstallPybricksDialog: React.FunctionComponent = () => { const { isOpen } = useSelector((s) => s.firmware.installPybricksDialog); - const deviceName = useSelector((s) => s.ble.deviceName); + const deviceNameLastConnected = useSelector((s) => s.ble.deviceNameLastConnected); const inProgress = useSelector( (s) => s.firmware.isFirmwareFlashUsbDfuInProgress || @@ -528,7 +528,7 @@ export const InstallPybricksDialog: React.FunctionComponent = () => { title={i18n.translate('optionsPanel.title')} panel={ Date: Thu, 18 Jul 2024 18:38:16 +0200 Subject: [PATCH 3/3] change to useLocalStorage and fix the dialog flow to use this as a default only --- src/ble/reducers.ts | 9 -------- .../InstallPybricksDialog.tsx | 23 +++++++++++++++---- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/ble/reducers.ts b/src/ble/reducers.ts index 8c526c391..13d03950f 100644 --- a/src/ble/reducers.ts +++ b/src/ble/reducers.ts @@ -84,14 +84,6 @@ const deviceName: Reducer = (state = '', action) => { return state; }; -const deviceNameLastConnected: Reducer = (state = '', action) => { - if (bleDidConnectPybricks.matches(action)) { - return action.name; - } - - return state; -}; - const deviceType: Reducer = (state = '', action) => { if (bleDidDisconnectPybricks.matches(action)) { return ''; @@ -144,7 +136,6 @@ export default combineReducers({ connection, deviceName, deviceType, - deviceNameLastConnected, deviceFirmwareVersion, deviceLowBatteryWarning, deviceBatteryCharging, diff --git a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx index 4ef854429..39cc3d5e6 100644 --- a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx +++ b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx @@ -23,7 +23,7 @@ import { ChevronDown, ChevronRight, Error, Heart } from '@blueprintjs/icons'; import { FirmwareMetadata, HubType } from '@pybricks/firmware'; import { fileOpen } from 'browser-fs-access'; import classNames from 'classnames'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { VisuallyHidden } from 'react-aria'; import { useDropzone } from 'react-dropzone'; import { useDispatch } from 'react-redux'; @@ -383,12 +383,14 @@ const AcceptLicensePanel: React.FunctionComponent = ({ type SelectOptionsPanelProps = { hubName: string; + hubDefaultName: string; metadata: FirmwareMetadata | undefined; onChangeHubName(hubName: string): void; }; const ConfigureOptionsPanel: React.FunctionComponent = ({ hubName, + hubDefaultName, metadata, onChangeHubName, }) => { @@ -408,7 +410,7 @@ const ConfigureOptionsPanel: React.FunctionComponent = onMouseOver={(e) => e.preventDefault()} onMouseDown={(e) => e.stopPropagation()} intent={isHubNameValid ? Intent.NONE : Intent.DANGER} - placeholder="Pybricks Hub" + placeholder={hubDefaultName || 'Pybricks Hub'} rightElement={ isHubNameValid ? undefined : ( = ( export const InstallPybricksDialog: React.FunctionComponent = () => { const { isOpen } = useSelector((s) => s.firmware.installPybricksDialog); - const deviceNameLastConnected = useSelector((s) => s.ble.deviceNameLastConnected); + const deviceName = useSelector((s) => s.ble.deviceName); const inProgress = useSelector( (s) => s.firmware.isFirmwareFlashUsbDfuInProgress || s.firmware.isFirmwareRestoreOfficialDfuInProgress, ); const dispatch = useDispatch(); + const [deviceNameLastConnected, setDeviceNameLastConnected] = useLocalStorage( + 'setting.lastConnectedDeviceName', + '', + ); const [hubName, setHubName] = useState(''); const [licenseAccepted, setLicenseAccepted] = useState(false); const [hubType] = useHubPickerSelectedHub(); @@ -473,6 +479,12 @@ export const InstallPybricksDialog: React.FunctionComponent = () => { ? getHubTypeFromMetadata(customFirmwareData?.metadata, hubType) : hubType; + useEffect(() => { + if (deviceName) { + setDeviceNameLastConnected(deviceName); + } + }, [deviceName, setDeviceNameLastConnected]); + return ( { firmwareInstallPybricksDialogAccept( hubBootloaderType(selectedHubType), selectedFirmwareData?.firmwareZip ?? new ArrayBuffer(0), - hubName, + hubName || deviceNameLastConnected, ), ), }} @@ -528,7 +540,8 @@ export const InstallPybricksDialog: React.FunctionComponent = () => { title={i18n.translate('optionsPanel.title')} panel={