Skip to content

Commit

Permalink
feat: new UX for the boards/library manager widgets
Browse files Browse the repository at this point in the history
Closes #19
Closes #781
Closes #1591
Closes #1607
Closes #1697
Closes #1707
Closes #1924
Closes #1941

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
  • Loading branch information
Akos Kitta committed Mar 13, 2023
1 parent ec24b68 commit edceb7e
Show file tree
Hide file tree
Showing 29 changed files with 1,385 additions and 480 deletions.
2 changes: 0 additions & 2 deletions arduino-ide-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"@types/p-queue": "^2.3.1",
"@types/ps-tree": "^1.1.0",
"@types/react-tabs": "^2.3.2",
"@types/react-virtualized": "^9.21.21",
"@types/temp": "^0.8.34",
"@types/which": "^1.3.1",
"@vscode/debugprotocol": "^1.51.0",
Expand Down Expand Up @@ -96,7 +95,6 @@
"react-perfect-scrollbar": "^1.5.8",
"react-select": "^5.6.0",
"react-tabs": "^3.1.2",
"react-virtualized": "^9.22.3",
"react-window": "^1.8.6",
"semver": "^7.3.2",
"string-natural-compare": "^2.0.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ import { ProblemManager as TheiaProblemManager } from '@theia/markers/lib/browse
import { ProblemManager } from './theia/markers/problem-manager';
import { BoardsAutoInstaller } from './boards/boards-auto-installer';
import { ShellLayoutRestorer } from './theia/core/shell-layout-restorer';
import { ListItemRenderer } from './widgets/component-list/list-item-renderer';
import {
ArduinoComponentContextMenuRenderer,
ListItemRenderer,
} from './widgets/component-list/list-item-renderer';
import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution';

import {
Expand Down Expand Up @@ -1021,4 +1024,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {

bind(SidebarBottomMenuWidget).toSelf();
rebind(TheiaSidebarBottomMenuWidget).toService(SidebarBottomMenuWidget);

bind(ArduinoComponentContextMenuRenderer).toSelf().inSingletonScope();
});
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
// CLI returns the packages already sorted with the deprecated ones at the end of the list
// in order to ensure the new ones are preferred
const candidates = packagesForBoard.filter(
({ installable, installedVersion }) => installable && !installedVersion
({ installedVersion }) => !installedVersion
);

return candidates[0];
Expand Down
130 changes: 91 additions & 39 deletions arduino-ide-extension/src/browser/contributions/examples.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as PQueue from 'p-queue';
import { inject, injectable } from '@theia/core/shared/inversify';
import { CommandHandler } from '@theia/core/lib/common/command';
import { CommandHandler, CommandService } from '@theia/core/lib/common/command';
import {
MenuPath,
CompositeMenuNode,
Expand All @@ -11,7 +11,11 @@ import {
DisposableCollection,
} from '@theia/core/lib/common/disposable';
import { OpenSketch } from './open-sketch';
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
import {
ArduinoMenus,
examplesLabel,
PlaceholderMenuNode,
} from '../menu/arduino-menus';
import { BoardsServiceProvider } from '../boards/boards-service-provider';
import { ExamplesService } from '../../common/protocol/examples-service';
import {
Expand All @@ -25,11 +29,73 @@ import {
SketchRef,
SketchContainer,
SketchesError,
Sketch,
CoreService,
SketchesService,
Sketch,
} from '../../common/protocol';
import { nls } from '@theia/core/lib/common';
import { nls } from '@theia/core/lib/common/nls';
import { unregisterSubmenu } from '../menu/arduino-menus';
import { MaybePromise } from '@theia/core/lib/common/types';
import { ApplicationError } from '@theia/core/lib/common/application-error';

/**
* Creates a cloned copy of the example sketch and opens it in a new window.
*/
export async function openClonedExample(
uri: string,
services: {
sketchesService: SketchesService;
commandService: CommandService;
},
onError: {
onDidFailClone?: (
err: ApplicationError<
number,
{
uri: string;
}
>,
uri: string
) => MaybePromise<unknown>;
onDidFailOpen?: (
err: ApplicationError<
number,
{
uri: string;
}
>,
sketch: Sketch
) => MaybePromise<unknown>;
} = {}
): Promise<void> {
const { sketchesService, commandService } = services;
const { onDidFailClone, onDidFailOpen } = onError;
try {
const sketch = await sketchesService.cloneExample(uri);
try {
await commandService.executeCommand(
OpenSketch.Commands.OPEN_SKETCH.id,
sketch
);
} catch (openError) {
if (SketchesError.NotFound.is(openError)) {
if (onDidFailOpen) {
await onDidFailOpen(openError, sketch);
return;
}
}
throw openError;
}
} catch (cloneError) {
if (SketchesError.NotFound.is(cloneError)) {
if (onDidFailClone) {
await onDidFailClone(cloneError, uri);
return;
}
}
throw cloneError;
}
}

@injectable()
export abstract class Examples extends SketchContribution {
Expand Down Expand Up @@ -94,7 +160,7 @@ export abstract class Examples extends SketchContribution {
// TODO: unregister submenu? https://github.com/eclipse-theia/theia/issues/7300
registry.registerSubmenu(
ArduinoMenus.FILE__EXAMPLES_SUBMENU,
nls.localize('arduino/examples/menu', 'Examples'),
examplesLabel,
{
order: '4',
}
Expand Down Expand Up @@ -174,47 +240,33 @@ export abstract class Examples extends SketchContribution {
}

protected createHandler(uri: string): CommandHandler {
const forceUpdate = () =>
this.update({
board: this.boardsServiceClient.boardsConfig.selectedBoard,
forceRefresh: true,
});
return {
execute: async () => {
const sketch = await this.clone(uri);
if (sketch) {
try {
return this.commandService.executeCommand(
OpenSketch.Commands.OPEN_SKETCH.id,
sketch
);
} catch (err) {
if (SketchesError.NotFound.is(err)) {
await openClonedExample(
uri,
{
sketchesService: this.sketchesService,
commandService: this.commandRegistry,
},
{
onDidFailClone: () => {
// Do not toast the error message. It's handled by the `Open Sketch` command.
this.update({
board: this.boardsServiceClient.boardsConfig.selectedBoard,
forceRefresh: true,
});
} else {
throw err;
}
forceUpdate();
},
onDidFailOpen: (err) => {
this.messageService.error(err.message);
forceUpdate();
},
}
}
);
},
};
}

private async clone(uri: string): Promise<Sketch | undefined> {
try {
const sketch = await this.sketchesService.cloneExample(uri);
return sketch;
} catch (err) {
if (SketchesError.NotFound.is(err)) {
this.messageService.error(err.message);
this.update({
board: this.boardsServiceClient.boardsConfig.selectedBoard,
forceRefresh: true,
});
} else {
throw err;
}
}
}
}

@injectable()
Expand Down
22 changes: 21 additions & 1 deletion arduino-ide-extension/src/browser/library/library-list-widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import {
LibrarySearch,
LibraryService,
} from '../../common/protocol/library-service';
import { ListWidget } from '../widgets/component-list/list-widget';
import {
ListWidget,
UserAbortError,
} from '../widgets/component-list/list-widget';
import { Installable } from '../../common/protocol';
import { ListItemRenderer } from '../widgets/component-list/list-item-renderer';
import { nls } from '@theia/core/lib/common';
Expand Down Expand Up @@ -141,6 +144,8 @@ export class LibraryListWidget extends ListWidget<
// All
installDependencies = true;
}
} else {
throw new UserAbortError();
}
} else {
// The lib does not have any dependencies.
Expand Down Expand Up @@ -235,6 +240,21 @@ class MessageBoxDialog extends AbstractDialog<MessageBoxDialog.Result> {
this.response = 0;
super.handleEnter(event);
}

protected override onAfterAttach(message: Message): void {
super.onAfterAttach(message);
let buttonToFocus: HTMLButtonElement | undefined = undefined;
for (const child of Array.from(this.controlPanel.children)) {
if (child instanceof HTMLButtonElement) {
if (child.classList.contains('main')) {
buttonToFocus = child;
break;
}
buttonToFocus = child;
}
}
buttonToFocus?.focus();
}
}
export namespace MessageBoxDialog {
export interface Options extends DialogProps {
Expand Down
16 changes: 15 additions & 1 deletion arduino-ide-extension/src/browser/menu/arduino-menus.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { isOSX } from '@theia/core/lib/common/os';
import { CommonMenus } from '@theia/core/lib/browser/common-frontend-contribution';
import {
MAIN_MENU_BAR,
Expand All @@ -7,6 +6,8 @@ import {
MenuPath,
SubMenuOptions,
} from '@theia/core/lib/common/menu';
import { nls } from '@theia/core/lib/common/nls';
import { isOSX } from '@theia/core/lib/common/os';

export namespace ArduinoMenus {
// Main menu
Expand Down Expand Up @@ -173,6 +174,17 @@ export namespace ArduinoMenus {
'3_sign_out',
];

// Context menu from the library and boards manager widget
export const ARDUINO_COMPONENT__CONTEXT = ['arduino-component--context'];
export const ARDUINO_COMPONENT__CONTEXT__INFO_GROUP = [
...ARDUINO_COMPONENT__CONTEXT,
'0_info',
];
export const ARDUINO_COMPONENT__CONTEXT__ACTION_GROUP = [
...ARDUINO_COMPONENT__CONTEXT,
'1_action',
];

// -- ROOT SSL CERTIFICATES
export const ROOT_CERTIFICATES__CONTEXT = [
'arduino-root-certificates--context',
Expand Down Expand Up @@ -230,3 +242,5 @@ export class PlaceholderMenuNode implements MenuNode {
return [...this.menuPath, 'placeholder'].join('-');
}
}

export const examplesLabel = nls.localize('arduino/examples/menu', 'Examples');
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ div#select-board-dialog .selectBoardContainer .list .item.selected i {
border: 1px solid var(--theia-arduino-toolbar-dropdown-border);
display: flex;
gap: 10px;
height: 28px;
height: var(--arduino-button-height);
margin: 0 4px;
overflow: hidden;
padding: 0 10px;
Expand Down
6 changes: 3 additions & 3 deletions arduino-ide-extension/src/browser/style/dialogs.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

min-width: 424px;
max-height: 560px;
padding: 0 28px;
padding: 0 var(--arduino-button-height);
}

.p-Widget.dialogOverlay .dialogBlock .dialogTitle {
Expand All @@ -35,15 +35,15 @@
}

.p-Widget.dialogOverlay .dialogBlock .dialogContent > input {
margin-bottom: 28px;
margin-bottom: var(--arduino-button-height);
}

.p-Widget.dialogOverlay .dialogBlock .dialogContent > div {
padding: 0 0 12px;
}

.p-Widget.dialogOverlay .dialogBlock .dialogContent .dialogSection {
margin-top: 28px;
margin-top: var(--arduino-button-height);
}
.p-Widget.dialogOverlay .dialogBlock .dialogContent .dialogSection:first-child {
margin-top: 0;
Expand Down
5 changes: 5 additions & 0 deletions arduino-ide-extension/src/browser/style/fonts.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
@font-face {
font-family: 'Open Sans';
src: url('fonts/OpenSans-Regular-webfont.woff') format('woff');
}

@font-face {
font-family: 'Open Sans Bold';
src: url('fonts/OpenSans-Bold-webfont.woff') format('woff');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}

.ide-updater-dialog--logo-container {
margin-right: 28px;
margin-right: var(--arduino-button-height);
}

.ide-updater-dialog--logo {
Expand Down Expand Up @@ -76,7 +76,7 @@
.ide-updater-dialog .buttons-container {
display: flex;
justify-content: flex-end;
margin-top: 28px;
margin-top: var(--arduino-button-height);
}

.ide-updater-dialog .buttons-container a.theia-button {
Expand Down
Loading

0 comments on commit edceb7e

Please sign in to comment.