import { nls } from '@theia/core/lib/common'; import React from '@theia/core/shared/react'; import { boardIdentifierEquals, Port, portIdentifierEquals, } from '../../../common/protocol'; import { ArduinoFirmwareUploader, FirmwareInfo, } from '../../../common/protocol/arduino-firmware-uploader'; import type { BoardList, BoardListItemWithBoard, } from '../../../common/protocol/board-list'; import { ArduinoSelect } from '../../widgets/arduino-select'; import { SelectBoardComponent } from '../certificate-uploader/select-board-components'; type FirmwareOption = { value: string; label: string }; export const FirmwareUploaderComponent = ({ boardList, firmwareUploader, updatableFqbns, flashFirmware, isOpen, }: { boardList: BoardList; firmwareUploader: ArduinoFirmwareUploader; updatableFqbns: string[]; flashFirmware: (firmware: FirmwareInfo, port: Port) => Promise; isOpen: any; }): React.ReactElement => { // boolean states for buttons const [firmwaresFetching, setFirmwaresFetching] = React.useState(false); const [installFeedback, setInstallFeedback] = React.useState< 'ok' | 'fail' | 'installing' | null >(null); const [selectedItem, setSelectedItem] = React.useState(null); const [availableFirmwares, setAvailableFirmwares] = React.useState< FirmwareInfo[] >([]); React.useEffect(() => { setAvailableFirmwares([]); }, [isOpen]); const [selectedFirmware, setSelectedFirmware] = React.useState(null); const [firmwareOptions, setFirmwareOptions] = React.useState< FirmwareOption[] >([]); const fetchFirmwares = React.useCallback(async () => { setInstallFeedback(null); setFirmwaresFetching(true); if (!selectedItem) { return; } // fetch the firmwares for the selected board const board = selectedItem.board; const firmwaresForFqbn = await firmwareUploader.availableFirmwares( board.fqbn || '' ); setAvailableFirmwares(firmwaresForFqbn); const firmwaresOpts = firmwaresForFqbn.map((f) => ({ label: f.firmware_version, value: f.firmware_version, })); setFirmwareOptions(firmwaresOpts); if (firmwaresForFqbn.length > 0) setSelectedFirmware(firmwaresOpts[0]); setFirmwaresFetching(false); }, [firmwareUploader, selectedItem]); const installFirmware = React.useCallback(async () => { setInstallFeedback('installing'); const firmwareToFlash = availableFirmwares.find( (firmware) => firmware.firmware_version === selectedFirmware?.value ); const selectedBoard = selectedItem?.board; const selectedPort = selectedItem?.port; try { const installStatus = firmwareToFlash && selectedBoard && selectedPort && (await flashFirmware(firmwareToFlash, selectedPort)); setInstallFeedback((installStatus && 'ok') || 'fail'); } catch { setInstallFeedback('fail'); } }, [selectedItem, selectedFirmware, availableFirmwares, flashFirmware]); const onItemSelect = React.useCallback( (item: BoardListItemWithBoard | null) => { if (!item) { setSelectedItem(null); return; } const board = item.board; const port = item.port; const selectedBoard = selectedItem?.board; const selectedPort = selectedItem?.port; if ( !boardIdentifierEquals(board, selectedBoard) || !portIdentifierEquals(port, selectedPort) ) { setInstallFeedback(null); setAvailableFirmwares([]); setSelectedItem(item); } }, [selectedItem] ); return ( <>
{availableFirmwares.length > 0 && ( <>
{ if (value) { setInstallFeedback(null); setSelectedFirmware(value); } }} />
{installFeedback === null && (
{nls.localize( 'arduino/firmware/overwriteSketch', 'Installation will overwrite the Sketch on the board.' )}
)} {installFeedback === 'installing' && (
{nls.localize( 'arduino/firmware/installingFirmware', 'Installing firmware.' )}
)} {installFeedback === 'ok' && (
{nls.localize( 'arduino/firmware/successfullyInstalled', 'Firmware successfully installed.' )}
)} {installFeedback === 'fail' && (
{nls.localize( 'arduino/firmware/failedInstall', 'Installation failed. Please try again.' )}
)}
)} ); };