Skip to content

Commit 2fc3364

Browse files
author
Akos Kitta
committed
feat: new UX for the boards/library manager widget
Closes #19 Closes #781 Closes #1591 Closes #1607 Closes #1924 Signed-off-by: Akos Kitta <[email protected]>
1 parent 7721350 commit 2fc3364

27 files changed

+1261
-453
lines changed

Diff for: arduino-ide-extension/package.json

-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
"@types/p-queue": "^2.3.1",
5959
"@types/ps-tree": "^1.1.0",
6060
"@types/react-tabs": "^2.3.2",
61-
"@types/react-virtualized": "^9.21.21",
6261
"@types/temp": "^0.8.34",
6362
"@types/which": "^1.3.1",
6463
"@vscode/debugprotocol": "^1.51.0",
@@ -95,7 +94,6 @@
9594
"react-perfect-scrollbar": "^1.5.8",
9695
"react-select": "^5.6.0",
9796
"react-tabs": "^3.1.2",
98-
"react-virtualized": "^9.22.3",
9997
"react-window": "^1.8.6",
10098
"semver": "^7.3.2",
10199
"string-natural-compare": "^2.0.3",

Diff for: arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ import { ProblemManager as TheiaProblemManager } from '@theia/markers/lib/browse
7979
import { ProblemManager } from './theia/markers/problem-manager';
8080
import { BoardsAutoInstaller } from './boards/boards-auto-installer';
8181
import { ShellLayoutRestorer } from './theia/core/shell-layout-restorer';
82-
import { ListItemRenderer } from './widgets/component-list/list-item-renderer';
82+
import {
83+
ArduinoComponentContextMenuRenderer,
84+
ListItemRenderer,
85+
} from './widgets/component-list/list-item-renderer';
8386
import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution';
8487

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

10221025
bind(SidebarBottomMenuWidget).toSelf();
10231026
rebind(TheiaSidebarBottomMenuWidget).toService(SidebarBottomMenuWidget);
1027+
1028+
bind(ArduinoComponentContextMenuRenderer).toSelf().inSingletonScope();
10241029
});

Diff for: arduino-ide-extension/src/browser/boards/boards-auto-installer.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
174174
// CLI returns the packages already sorted with the deprecated ones at the end of the list
175175
// in order to ensure the new ones are preferred
176176
const candidates = packagesForBoard.filter(
177-
({ installable, installedVersion }) => installable && !installedVersion
177+
({ installedVersion }) => !installedVersion
178178
);
179179

180180
return candidates[0];

Diff for: arduino-ide-extension/src/browser/contributions/examples.ts

+91-39
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as PQueue from 'p-queue';
22
import { inject, injectable } from '@theia/core/shared/inversify';
3-
import { CommandHandler } from '@theia/core/lib/common/command';
3+
import { CommandHandler, CommandService } from '@theia/core/lib/common/command';
44
import {
55
MenuPath,
66
CompositeMenuNode,
@@ -11,7 +11,11 @@ import {
1111
DisposableCollection,
1212
} from '@theia/core/lib/common/disposable';
1313
import { OpenSketch } from './open-sketch';
14-
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
14+
import {
15+
ArduinoMenus,
16+
examplesLabel,
17+
PlaceholderMenuNode,
18+
} from '../menu/arduino-menus';
1519
import { BoardsServiceProvider } from '../boards/boards-service-provider';
1620
import { ExamplesService } from '../../common/protocol/examples-service';
1721
import {
@@ -25,11 +29,73 @@ import {
2529
SketchRef,
2630
SketchContainer,
2731
SketchesError,
28-
Sketch,
2932
CoreService,
33+
SketchesService,
34+
Sketch,
3035
} from '../../common/protocol';
31-
import { nls } from '@theia/core/lib/common';
36+
import { nls } from '@theia/core/lib/common/nls';
3237
import { unregisterSubmenu } from '../menu/arduino-menus';
38+
import { MaybePromise } from '@theia/core/lib/common/types';
39+
import { ApplicationError } from '@theia/core/lib/common/application-error';
40+
41+
/**
42+
* Creates a cloned copy of the example sketch and opens it in a new window.
43+
*/
44+
export async function openClonedExample(
45+
uri: string,
46+
services: {
47+
sketchesService: SketchesService;
48+
commandService: CommandService;
49+
},
50+
onError: {
51+
onDidFailClone?: (
52+
err: ApplicationError<
53+
number,
54+
{
55+
uri: string;
56+
}
57+
>,
58+
uri: string
59+
) => MaybePromise<unknown>;
60+
onDidFailOpen?: (
61+
err: ApplicationError<
62+
number,
63+
{
64+
uri: string;
65+
}
66+
>,
67+
sketch: Sketch
68+
) => MaybePromise<unknown>;
69+
} = {}
70+
): Promise<void> {
71+
const { sketchesService, commandService } = services;
72+
const { onDidFailClone, onDidFailOpen } = onError;
73+
try {
74+
const sketch = await sketchesService.cloneExample(uri);
75+
try {
76+
await commandService.executeCommand(
77+
OpenSketch.Commands.OPEN_SKETCH.id,
78+
sketch
79+
);
80+
} catch (openError) {
81+
if (SketchesError.NotFound.is(openError)) {
82+
if (onDidFailOpen) {
83+
await onDidFailOpen(openError, sketch);
84+
return;
85+
}
86+
}
87+
throw openError;
88+
}
89+
} catch (cloneError) {
90+
if (SketchesError.NotFound.is(cloneError)) {
91+
if (onDidFailClone) {
92+
await onDidFailClone(cloneError, uri);
93+
return;
94+
}
95+
}
96+
throw cloneError;
97+
}
98+
}
3399

34100
@injectable()
35101
export abstract class Examples extends SketchContribution {
@@ -94,7 +160,7 @@ export abstract class Examples extends SketchContribution {
94160
// TODO: unregister submenu? https://github.com/eclipse-theia/theia/issues/7300
95161
registry.registerSubmenu(
96162
ArduinoMenus.FILE__EXAMPLES_SUBMENU,
97-
nls.localize('arduino/examples/menu', 'Examples'),
163+
examplesLabel,
98164
{
99165
order: '4',
100166
}
@@ -174,47 +240,33 @@ export abstract class Examples extends SketchContribution {
174240
}
175241

176242
protected createHandler(uri: string): CommandHandler {
243+
const forceRefresh = () =>
244+
this.update({
245+
board: this.boardsServiceClient.boardsConfig.selectedBoard,
246+
forceRefresh: true,
247+
});
177248
return {
178249
execute: async () => {
179-
const sketch = await this.clone(uri);
180-
if (sketch) {
181-
try {
182-
return this.commandService.executeCommand(
183-
OpenSketch.Commands.OPEN_SKETCH.id,
184-
sketch
185-
);
186-
} catch (err) {
187-
if (SketchesError.NotFound.is(err)) {
250+
await openClonedExample(
251+
uri,
252+
{
253+
sketchesService: this.sketchesService,
254+
commandService: this.commandRegistry,
255+
},
256+
{
257+
onDidFailClone: () => {
188258
// Do not toast the error message. It's handled by the `Open Sketch` command.
189-
this.update({
190-
board: this.boardsServiceClient.boardsConfig.selectedBoard,
191-
forceRefresh: true,
192-
});
193-
} else {
194-
throw err;
195-
}
259+
forceRefresh();
260+
},
261+
onDidFailOpen: (err) => {
262+
this.messageService.error(err.message);
263+
forceRefresh();
264+
},
196265
}
197-
}
266+
);
198267
},
199268
};
200269
}
201-
202-
private async clone(uri: string): Promise<Sketch | undefined> {
203-
try {
204-
const sketch = await this.sketchesService.cloneExample(uri);
205-
return sketch;
206-
} catch (err) {
207-
if (SketchesError.NotFound.is(err)) {
208-
this.messageService.error(err.message);
209-
this.update({
210-
board: this.boardsServiceClient.boardsConfig.selectedBoard,
211-
forceRefresh: true,
212-
});
213-
} else {
214-
throw err;
215-
}
216-
}
217-
}
218270
}
219271

220272
@injectable()

Diff for: arduino-ide-extension/src/browser/menu/arduino-menus.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { isOSX } from '@theia/core/lib/common/os';
21
import { CommonMenus } from '@theia/core/lib/browser/common-frontend-contribution';
32
import {
43
MAIN_MENU_BAR,
@@ -7,6 +6,8 @@ import {
76
MenuPath,
87
SubMenuOptions,
98
} from '@theia/core/lib/common/menu';
9+
import { nls } from '@theia/core/lib/common/nls';
10+
import { isOSX } from '@theia/core/lib/common/os';
1011

1112
export namespace ArduinoMenus {
1213
// Main menu
@@ -173,6 +174,17 @@ export namespace ArduinoMenus {
173174
'3_sign_out',
174175
];
175176

177+
// Context menu from the library and boards manager widget
178+
export const ARDUINO_COMPONENT__CONTEXT = ['arduino-component--context'];
179+
export const ARDUINO_COMPONENT__CONTEXT__INFO_GROUP = [
180+
...ARDUINO_COMPONENT__CONTEXT,
181+
'0_info',
182+
];
183+
export const ARDUINO_COMPONENT__CONTEXT__ACTION_GROUP = [
184+
...ARDUINO_COMPONENT__CONTEXT,
185+
'1_action',
186+
];
187+
176188
// -- ROOT SSL CERTIFICATES
177189
export const ROOT_CERTIFICATES__CONTEXT = [
178190
'arduino-root-certificates--context',
@@ -230,3 +242,5 @@ export class PlaceholderMenuNode implements MenuNode {
230242
return [...this.menuPath, 'placeholder'].join('-');
231243
}
232244
}
245+
246+
export const examplesLabel = nls.localize('arduino/examples/menu', 'Examples');

Diff for: arduino-ide-extension/src/browser/style/boards-config-dialog.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ div#select-board-dialog .selectBoardContainer .list .item.selected i {
165165
border: 1px solid var(--theia-arduino-toolbar-dropdown-border);
166166
display: flex;
167167
gap: 10px;
168-
height: 28px;
168+
height: var(--arduino-button-height);
169169
margin: 0 4px;
170170
overflow: hidden;
171171
padding: 0 10px;

Diff for: arduino-ide-extension/src/browser/style/dialogs.css

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
min-width: 424px;
1414
max-height: 560px;
15-
padding: 0 28px;
15+
padding: 0 var(--arduino-button-height);
1616
}
1717

1818
.p-Widget.dialogOverlay .dialogBlock .dialogTitle {
@@ -35,15 +35,15 @@
3535
}
3636

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

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

4545
.p-Widget.dialogOverlay .dialogBlock .dialogContent .dialogSection {
46-
margin-top: 28px;
46+
margin-top: var(--arduino-button-height);
4747
}
4848
.p-Widget.dialogOverlay .dialogBlock .dialogContent .dialogSection:first-child {
4949
margin-top: 0;

Diff for: arduino-ide-extension/src/browser/style/ide-updater-dialog.css

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
}
1616

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

2121
.ide-updater-dialog--logo {
@@ -76,7 +76,7 @@
7676
.ide-updater-dialog .buttons-container {
7777
display: flex;
7878
justify-content: flex-end;
79-
margin-top: 28px;
79+
margin-top: var(--arduino-button-height);
8080
}
8181

8282
.ide-updater-dialog .buttons-container a.theia-button {

Diff for: arduino-ide-extension/src/browser/style/index.css

+7-7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
@import './progress-bar.css';
2121
@import './settings-step-input.css';
2222

23+
:root {
24+
--arduino-button-height: 28px;
25+
}
26+
2327
/* Revive of the `--theia-icon-loading`. The variable has been removed from Theia while IDE2 still uses is. */
2428
/* The SVG icons are still part of Theia (1.31.1) */
2529
/* https://github.com/arduino/arduino-ide/pull/1662#issuecomment-1324997134 */
@@ -64,9 +68,9 @@ body.theia-dark {
6468

6569
/* Makes the sidepanel a bit wider when opening the widget */
6670
.p-DockPanel-widget {
67-
min-width: 200px;
71+
min-width: 220px;
6872
min-height: 20px;
69-
height: 200px;
73+
height: 220px;
7074
}
7175

7276
/* Overrule the default Theia CSS button styles. */
@@ -95,7 +99,7 @@ button.theia-button,
9599
}
96100

97101
button.theia-button {
98-
height: 28px;
102+
height: var(--arduino-button-height);
99103
max-width: none;
100104
}
101105

@@ -154,10 +158,6 @@ button.theia-button.message-box-dialog-button {
154158
font-size: 14px;
155159
}
156160

157-
.uppercase {
158-
text-transform: uppercase;
159-
}
160-
161161
/* High Contrast Theme rules */
162162
/* TODO: Remove it when the Theia version is upgraded to 1.27.0 and use Theia APIs to implement it*/
163163
.hc-black.hc-theia.theia-hc button.theia-button:hover,

0 commit comments

Comments
 (0)