Skip to content

Commit

Permalink
feat: simplify board and port handling
Browse files Browse the repository at this point in the history
Closes #1319

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
  • Loading branch information
Akos Kitta committed Jul 27, 2023
1 parent e17472e commit 8ee05ba
Show file tree
Hide file tree
Showing 52 changed files with 2,719 additions and 2,805 deletions.
14 changes: 9 additions & 5 deletions arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import { SketchesServiceClientImpl } from './sketches-service-client-impl';
import { CoreService, CoreServicePath } from '../common/protocol/core-service';
import { BoardsListWidget } from './boards/boards-list-widget';
import { BoardsListWidgetFrontendContribution } from './boards/boards-widget-frontend-contribution';
import { BoardsServiceProvider } from './boards/boards-service-provider';
import {
BoardListDumper,
BoardsServiceProvider,
} from './boards/boards-service-provider';
import { WorkspaceService as TheiaWorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { WorkspaceService } from './theia/workspace/workspace-service';
import { OutlineViewContribution as TheiaOutlineViewContribution } from '@theia/outline-view/lib/browser/outline-view-contribution';
Expand Down Expand Up @@ -61,7 +64,6 @@ import {
BoardsConfigDialog,
BoardsConfigDialogProps,
} from './boards/boards-config-dialog';
import { BoardsConfigDialogWidget } from './boards/boards-config-dialog-widget';
import { ScmContribution as TheiaScmContribution } from '@theia/scm/lib/browser/scm-contribution';
import { ScmContribution } from './theia/scm/scm-contribution';
import { SearchInWorkspaceFrontendContribution as TheiaSearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
Expand Down Expand Up @@ -358,7 +360,7 @@ import { UpdateArduinoState } from './contributions/update-arduino-state';
import { TerminalWidgetImpl } from './theia/terminal/terminal-widget-impl';
import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
import { TerminalFrontendContribution } from './theia/terminal/terminal-frontend-contribution';
import { TerminalFrontendContribution as TheiaTerminalFrontendContribution } from '@theia/terminal/lib/browser/terminal-frontend-contribution'
import { TerminalFrontendContribution as TheiaTerminalFrontendContribution } from '@theia/terminal/lib/browser/terminal-frontend-contribution';

// Hack to fix copy/cut/paste issue after electron version update in Theia.
// https://github.com/eclipse-theia/theia/issues/12487
Expand Down Expand Up @@ -447,6 +449,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(BoardsServiceProvider).toSelf().inSingletonScope();
bind(FrontendApplicationContribution).toService(BoardsServiceProvider);
bind(CommandContribution).toService(BoardsServiceProvider);
bind(BoardListDumper).toSelf().inSingletonScope();

// To be able to track, and update the menu based on the core settings (aka. board details) of the currently selected board.
bind(FrontendApplicationContribution)
Expand Down Expand Up @@ -480,7 +483,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(OpenHandler).toService(BoardsListWidgetFrontendContribution);

// Board select dialog
bind(BoardsConfigDialogWidget).toSelf().inSingletonScope();
bind(BoardsConfigDialog).toSelf().inSingletonScope();
bind(BoardsConfigDialogProps).toConstantValue({
title: nls.localize(
Expand Down Expand Up @@ -1034,5 +1036,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
// Patch terminal issues.
rebind(TerminalWidget).to(TerminalWidgetImpl).inTransientScope();
bind(TerminalFrontendContribution).toSelf().inSingletonScope();
rebind(TheiaTerminalFrontendContribution).toService(TerminalFrontendContribution);
rebind(TheiaTerminalFrontendContribution).toService(
TerminalFrontendContribution
);
});
80 changes: 25 additions & 55 deletions arduino-ide-extension/src/browser/boards/boards-auto-installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
BoardsService,
BoardsPackage,
Board,
Port,
isBoardIdentifierChangeEvent,
BoardIdentifier,
} from '../../common/protocol/boards-service';
import { BoardsServiceProvider } from './boards-service-provider';
import { Installable, ResponseServiceClient } from '../../common/protocol';
Expand All @@ -24,7 +25,7 @@ interface AutoInstallPromptAction {
type AutoInstallPromptActions = AutoInstallPromptAction[];

/**
* Listens on `BoardsConfig.Config` changes, if a board is selected which does not
* Listens on `BoardList` changes, if a board is selected which does not
* have the corresponding core installed, it proposes the user to install the core.
*/

Expand All @@ -44,7 +45,7 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
protected readonly boardsService: BoardsService;

@inject(BoardsServiceProvider)
protected readonly boardsServiceClient: BoardsServiceProvider;
protected readonly boardsServiceProvider: BoardsServiceProvider;

@inject(ResponseServiceClient)
protected readonly responseService: ResponseServiceClient;
Expand All @@ -53,34 +54,28 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
protected readonly boardsManagerFrontendContribution: BoardsListWidgetFrontendContribution;

// Workaround for https://github.com/eclipse-theia/theia/issues/9349
protected notifications: Board[] = [];
protected notifications: BoardIdentifier[] = [];

// * "refusal" meaning a "prompt action" not accepting the auto-install offer ("X" or "install manually")
// we can use "portSelectedOnLastRefusal" to deduce when a board is unplugged after a user has "refused"
// an auto-install prompt. Important to know as we do not want "an unplug" to trigger a "refused" prompt
// showing again
private portSelectedOnLastRefusal: Port | undefined;
// private portSelectedOnLastRefusal: PortIdentifier | undefined;
private lastRefusedPackageId: string | undefined;

onStart(): void {
const setEventListeners = () => {
this.boardsServiceClient.onBoardsConfigChanged((config) => {
const { selectedBoard, selectedPort } = config;

const boardWasUnplugged =
!selectedPort && this.portSelectedOnLastRefusal;

this.clearLastRefusedPromptInfo();

if (
boardWasUnplugged ||
!selectedBoard ||
this.promptAlreadyShowingForBoard(selectedBoard)
) {
this.boardsServiceProvider.onBoardsConfigDidChange((config) => {
if (!isBoardIdentifierChangeEvent(config)) {
return;
}
const { selectedBoard } = config;
const fqbn = selectedBoard?.fqbn;
if (!fqbn) {
return;
}

this.ensureCoreExists(selectedBoard, selectedPort);
this.ensureCoreExists(selectedBoard);
});

// we "clearRefusedPackageInfo" if a "refused" package is eventually
Expand All @@ -94,23 +89,16 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
});
};

// we should invoke this.ensureCoreExists only once we're sure
// everything has been reconciled
this.boardsServiceClient.reconciled.then(() => {
const { selectedBoard, selectedPort } =
this.boardsServiceClient.boardsConfig;

if (selectedBoard) {
this.ensureCoreExists(selectedBoard, selectedPort);
}

setEventListeners();
});
setEventListeners(); // TODO: after onDidStart
// });
}

private removeNotificationByBoard(selectedBoard: Board): void {
private removeNotificationByBoard(selectedBoard: BoardIdentifier): void {
const index = this.notifications.findIndex((notification) =>
Board.sameAs(notification, selectedBoard)
Board.sameAs(
{ name: notification.name, fqbn: notification.fqbn },
selectedBoard
)
);
if (index !== -1) {
this.notifications.splice(index, 1);
Expand All @@ -119,32 +107,15 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {

private clearLastRefusedPromptInfo(): void {
this.lastRefusedPackageId = undefined;
this.portSelectedOnLastRefusal = undefined;
}

private setLastRefusedPromptInfo(
packageId: string,
selectedPort?: Port
): void {
this.lastRefusedPackageId = packageId;
this.portSelectedOnLastRefusal = selectedPort;
}

private promptAlreadyShowingForBoard(board: Board): boolean {
return Boolean(
this.notifications.find((notification) =>
Board.sameAs(notification, board)
)
);
}

protected ensureCoreExists(selectedBoard: Board, selectedPort?: Port): void {
protected ensureCoreExists(selectedBoard: BoardIdentifier): void {
this.notifications.push(selectedBoard);
this.boardsService.search({}).then((packages) => {
const candidate = this.getInstallCandidate(packages, selectedBoard);

if (candidate) {
this.showAutoInstallPrompt(candidate, selectedBoard, selectedPort);
this.showAutoInstallPrompt(candidate, selectedBoard);
} else {
this.removeNotificationByBoard(selectedBoard);
}
Expand Down Expand Up @@ -182,8 +153,7 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {

private showAutoInstallPrompt(
candidate: BoardsPackage,
selectedBoard: Board,
selectedPort?: Port
selectedBoard: BoardIdentifier
): void {
const candidateName = candidate.name;
const version = candidate.availableVersions[0]
Expand All @@ -199,7 +169,7 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
const actions = this.createPromptActions(candidate);

const onRefuse = () => {
this.setLastRefusedPromptInfo(candidate.id, selectedPort);
// this.setLastRefusedPromptInfo(candidate.id, selectedPort); TODO: probably noop but let's revisit it.
};
const handleAction = this.createOnAnswerHandler(actions, onRefuse);

Expand Down
Loading

0 comments on commit 8ee05ba

Please sign in to comment.