diff --git a/src/components/hubPicker/HubPicker.tsx b/src/components/hubPicker/HubPicker.tsx index 13889395..b44aaa77 100644 --- a/src/components/hubPicker/HubPicker.tsx +++ b/src/components/hubPicker/HubPicker.tsx @@ -3,21 +3,16 @@ import { Radio, RadioGroup } from '@blueprintjs/core'; import React from 'react'; +import { useHubPickerSelectedHub } from './hooks'; import { Hub } from '.'; -type HubPickerProps = { - hubType: Hub; - onChange: (hubType: Hub) => void; -}; +export const HubPicker: React.VoidFunctionComponent = () => { + const [selectedHub, setSelectedHub] = useHubPickerSelectedHub(); -export const HubPicker: React.VoidFunctionComponent = ({ - hubType, - onChange, -}) => { return ( onChange(e.currentTarget.value as Hub)} + selectedValue={selectedHub} + onChange={(e) => setSelectedHub(e.currentTarget.value as Hub)} > BOOST Move Hub City Hub diff --git a/src/components/hubPicker/hooks.ts b/src/components/hubPicker/hooks.ts new file mode 100644 index 00000000..a2da107c --- /dev/null +++ b/src/components/hubPicker/hooks.ts @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2022 The Pybricks Authors + +import { useLocalStorage } from 'usehooks-ts'; +import { Hub } from '.'; + +/** + * Hook for {@link HubPicker} state backed by local storage. + * @returns Tuple of the current state and setter (like useState()). + */ +export function useHubPickerSelectedHub() { + return useLocalStorage('hubPicker.selectedHub', Hub.Move); +} diff --git a/src/explorer/newFileWizard/NewFileWizard.test.tsx b/src/explorer/newFileWizard/NewFileWizard.test.tsx index 5b1ba4ac..909a8b1b 100644 --- a/src/explorer/newFileWizard/NewFileWizard.test.tsx +++ b/src/explorer/newFileWizard/NewFileWizard.test.tsx @@ -27,7 +27,7 @@ describe('accept', () => { await user.click(button); expect(dispatch).toHaveBeenCalledWith( - newFileWizardDidAccept('test', '.py', Hub.Technic), + newFileWizardDidAccept('test', '.py', Hub.Move), ); }); @@ -42,7 +42,7 @@ describe('accept', () => { ); expect(dispatch).toHaveBeenCalledWith( - newFileWizardDidAccept('test', '.py', Hub.Technic), + newFileWizardDidAccept('test', '.py', Hub.Move), ); }); }); diff --git a/src/explorer/newFileWizard/NewFileWizard.tsx b/src/explorer/newFileWizard/NewFileWizard.tsx index 09d54a82..ec4dc635 100644 --- a/src/explorer/newFileWizard/NewFileWizard.tsx +++ b/src/explorer/newFileWizard/NewFileWizard.tsx @@ -5,8 +5,8 @@ import { Button, Classes, Dialog, FormGroup } from '@blueprintjs/core'; import React, { useCallback, useRef, useState } from 'react'; import { useId } from 'react-aria'; import { useDispatch } from 'react-redux'; -import { Hub } from '../../components/hubPicker'; import { HubPicker } from '../../components/hubPicker/HubPicker'; +import { useHubPickerSelectedHub } from '../../components/hubPicker/hooks'; import { useFileStorageMetadata } from '../../fileStorage/hooks'; import { FileNameValidationResult, @@ -18,9 +18,6 @@ import FileNameFormGroup from '../fileNameFormGroup/FileNameFormGroup'; import { newFileWizardDidAccept, newFileWizardDidCancel } from './actions'; import { useI18n } from './i18n'; -// This should be set to the most commonly used hub. -const defaultHub = Hub.Technic; - const NewFileWizard: React.VoidFunctionComponent = () => { const i18n = useI18n(); const dispatch = useDispatch(); @@ -33,8 +30,8 @@ const NewFileWizard: React.VoidFunctionComponent = () => { pythonFileExtension, files.map((f) => f.path), ); - const [hubType, setHubType] = useState(defaultHub); + const [hubType] = useHubPickerSelectedHub(); const fileNameInputRef = useRef(null); const handleSubmit = useCallback( @@ -70,7 +67,7 @@ const NewFileWizard: React.VoidFunctionComponent = () => { onChange={setFileName} /> - +
diff --git a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx index ec29e1ec..d707c7e0 100644 --- a/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx +++ b/src/firmware/installPybricksDialog/InstallPybricksDialog.tsx @@ -39,6 +39,7 @@ import { hubHasUSB, } from '../../components/hubPicker'; import { HubPicker } from '../../components/hubPicker/HubPicker'; +import { useHubPickerSelectedHub } from '../../components/hubPicker/hooks'; import { FileMetadata } from '../../fileStorage'; import { useFileStorageMetadata } from '../../fileStorage/hooks'; import { useSelector } from '../../reducers'; @@ -57,21 +58,13 @@ const dialogBody = classNames( 'pb-firmware-installPybricksDialog-body', ); -type SelectHubPanelProps = { - hubType: Hub; - onChange: (hubType: Hub) => void; -}; - -const SelectHubPanel: React.VoidFunctionComponent = ({ - hubType, - onChange, -}) => { +const SelectHubPanel: React.VoidFunctionComponent = () => { const i18n = useI18n(); return (

{i18n.translate('selectHubPanel.message')}

- + ); }; -const defaultHubType = Hub.Technic; - export const InstallPybricksDialog: React.VoidFunctionComponent = () => { const { isOpen } = useSelector((s) => s.firmware.installPybricksDialog); const dispatch = useDispatch(); - const [hubType, setHubType] = useState(defaultHubType); const [hubName, setHubName] = useState(''); const [includeProgram, setIncludeProgram] = useState(false); const [selectedIncludeFile, setSelectedIncludeFile] = useState(); const [licenseAccepted, setLicenseAccepted] = useState(false); + const [hubType] = useHubPickerSelectedHub(); const { data } = useFirmware(hubType); const i18n = useI18n(); @@ -470,7 +461,7 @@ export const InstallPybricksDialog: React.VoidFunctionComponent = () => { } + panel={} nextButtonProps={{ text: i18n.translate('nextButton.label') }} />