mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-10-15 14:28:33 +00:00

* backend structure WIP * Scaffold interfaces and classes for pluggable monitors * Implement MonitorService to handle pluggable monitor lifetime * Rename WebSocketService to WebSocketProvider and uninjected it * Moved some interfaces * Changed upload settings * Enhance MonitorManager APIs * Fixed WebSocketChange event signature * Add monitor proxy functions for the frontend * Moved settings to MonitorService * Remove several unnecessary serial monitor classes * Changed how connection is handled on upload * Proxied more monitor methods to frontend * WebSocketProvider is not injectable anymore * Add generic monitor settings storaging * More serial classes removal * Remove unused file * Changed plotter contribution to use new manager proxy * Changed MonitorWidget and children to use new monitor proxy * Updated MonitorWidget to use new monitor proxy * Fix backend logger bindings * Delete unnecessary Symbol * coreClientProvider is now set when constructing MonitorService * Add missing binding * Fix `MonitorManagerProxy` DI issue * fix monitor connection * delete duplex when connection is closed * update arduino-cli to 0.22.0 * fix upload when monitor is open * add MonitorSettingsProvider interface * monitor settings provider stub * updated pseudo code * refactor monitor settings interfaces * monitor service provider singleton * add unit tests * change MonitorService providers to injectable deps * fix monitor settings client communication * refactor monitor commands protocol * use monitor settings provider properly * add settings to monitor model * add settings to monitor model * reset serial monitor when port changes * fix serial plotter opening * refine monitor connection settings * fix hanging web socket connections * add serial plotter reset command * send port to web socket clients * monitor service wait for success serial port open * fix reset loop * update serial plotter version * update arduino-cli version to 0.23.0-rc1 and regenerate grpc protocol * remove useless plotter protocol file * localize web socket errors * clean-up code * update translation file * Fix duplicated editor tabs (#1012) * Save dialog for closing temporary sketch and unsaved files (#893) * Use normal `OnWillStop` event * Align `CLOSE` command to rest of app * Fixed FS path vs encoded URL comparision when handling stop request. Ref: https://github.com/eclipse-theia/theia/issues/11226 Signed-off-by: Akos Kitta <a.kitta@arduino.cc> * Fixed the translations. Signed-off-by: Akos Kitta <a.kitta@arduino.cc> * Fixed the translations again. Removed `electron` from the `nls-extract`. It does not contain app code. Signed-off-by: Akos Kitta <a.kitta@arduino.cc> * Aligned the stop handler code to Theia. Signed-off-by: Akos Kitta <a.kitta@arduino.cc> Co-authored-by: Akos Kitta <a.kitta@arduino.cc> * fix serial monitor send line ending * refactor monitor-service poll for test/readability * localize web socket errors * update translation file * Fix duplicated editor tabs (#1012) * i18n:check rerun * Speed up IDE startup time. Signed-off-by: Akos Kitta <a.kitta@arduino.cc> * override coreClientProvider in monitor-service * cleanup merged code Co-authored-by: Francesco Stasi <f.stasi@me.com> Co-authored-by: Silvano Cerza <silvanocerza@gmail.com> Co-authored-by: Mark Sujew <mark.sujew@typefox.io> Co-authored-by: David Simpson <45690499+davegarthsimpson@users.noreply.github.com> Co-authored-by: Akos Kitta <a.kitta@arduino.cc>
224 lines
7.1 KiB
TypeScript
224 lines
7.1 KiB
TypeScript
import { nls } from '@theia/core/lib/common';
|
|
import * as React from '@theia/core/shared/react';
|
|
import { Port } from '../../../common/protocol';
|
|
import {
|
|
ArduinoFirmwareUploader,
|
|
FirmwareInfo,
|
|
} from '../../../common/protocol/arduino-firmware-uploader';
|
|
import { AvailableBoard } from '../../boards/boards-service-provider';
|
|
import { ArduinoSelect } from '../../widgets/arduino-select';
|
|
import { SelectBoardComponent } from '../certificate-uploader/select-board-components';
|
|
|
|
type FirmwareOption = { value: string; label: string };
|
|
|
|
export const FirmwareUploaderComponent = ({
|
|
availableBoards,
|
|
firmwareUploader,
|
|
updatableFqbns,
|
|
flashFirmware,
|
|
isOpen,
|
|
}: {
|
|
availableBoards: AvailableBoard[];
|
|
firmwareUploader: ArduinoFirmwareUploader;
|
|
updatableFqbns: string[];
|
|
flashFirmware: (firmware: FirmwareInfo, port: Port) => Promise<any>;
|
|
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 [selectedBoard, setSelectedBoard] =
|
|
React.useState<AvailableBoard | null>(null);
|
|
|
|
const [availableFirmwares, setAvailableFirmwares] = React.useState<
|
|
FirmwareInfo[]
|
|
>([]);
|
|
React.useEffect(() => {
|
|
setAvailableFirmwares([]);
|
|
}, [isOpen]);
|
|
const [selectedFirmware, setSelectedFirmware] =
|
|
React.useState<FirmwareOption | null>(null);
|
|
|
|
const [firmwareOptions, setFirmwareOptions] = React.useState<
|
|
FirmwareOption[]
|
|
>([]);
|
|
|
|
const fetchFirmwares = React.useCallback(async () => {
|
|
setInstallFeedback(null);
|
|
setFirmwaresFetching(true);
|
|
if (!selectedBoard) {
|
|
return;
|
|
}
|
|
|
|
// fetch the firmwares for the selected board
|
|
const firmwaresForFqbn = await firmwareUploader.availableFirmwares(
|
|
selectedBoard.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, selectedBoard]);
|
|
|
|
const installFirmware = React.useCallback(async () => {
|
|
setInstallFeedback('installing');
|
|
|
|
const firmwareToFlash = availableFirmwares.find(
|
|
(firmware) => firmware.firmware_version === selectedFirmware?.value
|
|
);
|
|
|
|
try {
|
|
const installStatus =
|
|
!!firmwareToFlash &&
|
|
!!selectedBoard?.port &&
|
|
(await flashFirmware(firmwareToFlash, selectedBoard?.port));
|
|
|
|
setInstallFeedback((installStatus && 'ok') || 'fail');
|
|
} catch {
|
|
setInstallFeedback('fail');
|
|
}
|
|
}, [firmwareUploader, selectedBoard, selectedFirmware, availableFirmwares]);
|
|
|
|
const onBoardSelect = React.useCallback(
|
|
(board: AvailableBoard) => {
|
|
const newFqbn = (board && board.fqbn) || null;
|
|
const prevFqbn = (selectedBoard && selectedBoard.fqbn) || null;
|
|
|
|
if (newFqbn !== prevFqbn) {
|
|
setInstallFeedback(null);
|
|
setAvailableFirmwares([]);
|
|
setSelectedBoard(board);
|
|
}
|
|
},
|
|
[selectedBoard]
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<div className="dialogSection">
|
|
<div className="dialogRow">
|
|
<label htmlFor="board-select">
|
|
{nls.localize('arduino/firmware/selectBoard', 'Select Board')}
|
|
</label>
|
|
</div>
|
|
<div className="dialogRow">
|
|
<div className="fl1">
|
|
<SelectBoardComponent
|
|
availableBoards={availableBoards}
|
|
updatableFqbns={updatableFqbns}
|
|
onBoardSelect={onBoardSelect}
|
|
selectedBoard={selectedBoard}
|
|
busy={installFeedback === 'installing'}
|
|
/>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
className="theia-button secondary"
|
|
disabled={
|
|
selectedBoard === null ||
|
|
firmwaresFetching ||
|
|
installFeedback === 'installing'
|
|
}
|
|
onClick={fetchFirmwares}
|
|
>
|
|
{nls.localize('arduino/firmware/checkUpdates', 'Check Updates')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{availableFirmwares.length > 0 && (
|
|
<>
|
|
<div className="dialogSection">
|
|
<div className="dialogRow">
|
|
<label htmlFor="firmware-select" className="fl1">
|
|
{nls.localize(
|
|
'arduino/firmware/selectVersion',
|
|
'Select firmware version'
|
|
)}
|
|
</label>
|
|
<ArduinoSelect
|
|
id="firmware-select"
|
|
menuPosition="fixed"
|
|
isDisabled={
|
|
!selectedBoard ||
|
|
firmwaresFetching ||
|
|
installFeedback === 'installing'
|
|
}
|
|
options={firmwareOptions}
|
|
value={selectedFirmware}
|
|
tabSelectsValue={false}
|
|
onChange={(value) => {
|
|
if (value) {
|
|
setInstallFeedback(null);
|
|
setSelectedFirmware(value);
|
|
}
|
|
}}
|
|
/>
|
|
<button
|
|
type="button"
|
|
className="theia-button primary"
|
|
disabled={
|
|
selectedFirmware === null ||
|
|
firmwaresFetching ||
|
|
installFeedback === 'installing'
|
|
}
|
|
onClick={installFirmware}
|
|
>
|
|
{nls.localize('arduino/firmware/install', 'Install')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div className="dialogSection">
|
|
{installFeedback === null && (
|
|
<div className="dialogRow warn">
|
|
<i className="fa fa-exclamation status-icon" />
|
|
{nls.localize(
|
|
'arduino/firmware/overwriteSketch',
|
|
'Installation will overwrite the Sketch on the board.'
|
|
)}
|
|
</div>
|
|
)}
|
|
{installFeedback === 'installing' && (
|
|
<div className="dialogRow success">
|
|
<div className="spinner" />
|
|
{nls.localize(
|
|
'arduino/firmware/installingFirmware',
|
|
'Installing firmware.'
|
|
)}
|
|
</div>
|
|
)}
|
|
{installFeedback === 'ok' && (
|
|
<div className="dialogRow success">
|
|
<i className="fa fa-info status-icon" />
|
|
{nls.localize(
|
|
'arduino/firmware/successfullyInstalled',
|
|
'Firmware successfully installed.'
|
|
)}
|
|
</div>
|
|
)}
|
|
{installFeedback === 'fail' && (
|
|
<div className="dialogRow warn">
|
|
<i className="fa fa-exclamation status-icon" />
|
|
{nls.localize(
|
|
'arduino/firmware/failedInstall',
|
|
'Installation failed. Please try again.'
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
};
|