Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6a73507

Browse files
author
Akos Kitta
committed
Added progress for install/uninstall.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
1 parent 3fc1ffc commit 6a73507

23 files changed

+378
-211
lines changed

‎arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import { WorkspaceService } from './theia/workspace/workspace-service';
4444
import { ArduinoToolbar } from './toolbar/arduino-toolbar';
4545
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
4646
import { FileService } from '@theia/filesystem/lib/browser/file-service';
47-
import { OutputService } from '../common/protocol/output-service';
47+
import { ResponseService } from '../common/protocol/response-service';
4848
import { ArduinoPreferences } from './arduino-preferences';
4949
import { SketchesServiceClientImpl } from '../common/protocol/sketches-service-client-impl';
5050
import { SaveAsSketch } from './contributions/save-as-sketch';
@@ -151,8 +151,8 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
151151
@inject(ExecutableService)
152152
protected executableService: ExecutableService;
153153

154-
@inject(OutputService)
155-
protected readonly outputService: OutputService;
154+
@inject(ResponseService)
155+
protected readonly responseService: ResponseService;
156156

157157
@inject(ArduinoPreferences)
158158
protected readonly arduinoPreferences: ArduinoPreferences;

‎arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ import { OutputChannelRegistryMainImpl as TheiaOutputChannelRegistryMainImpl, Ou
120120
import { ExecutableService, ExecutableServicePath } from '../common/protocol';
121121
import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
122122
import { MonacoTextModelService } from './theia/monaco/monaco-text-model-service';
123-
import { OutputServiceImpl } from './output-service-impl';
124-
import { OutputServicePath,OutputService } from '../common/protocol/output-service';
123+
import { ResponseServiceImpl } from './response-service-impl';
124+
import { ResponseServicePath,ResponseService } from '../common/protocol/response-service';
125125
import { NotificationCenter } from './notification-center';
126126
import { NotificationServicePath, NotificationServiceServer } from '../common/protocol';
127127
import { About } from './contributions/about';
@@ -159,6 +159,8 @@ import { MonacoEditorProvider as TheiaMonacoEditorProvider } from '@theia/monaco
159159
import { DebugEditorModel } from './theia/debug/debug-editor-model';
160160
import { DebugEditorModelFactory } from '@theia/debug/lib/browser/editor/debug-editor-model';
161161
import { StorageWrapper } from './storage-wrapper';
162+
import { NotificationManager } from './theia/messages/notifications-manager';
163+
import { NotificationManager as TheiaNotificationManager } from '@theia/messages/lib/browser/notifications-manager';
162164

163165
const ElementQueries = require('css-element-queries/src/ElementQueries');
164166

@@ -383,11 +385,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
383385
Contribution.configure(bind, ArchiveSketch);
384386
Contribution.configure(bind, AddZipLibrary);
385387

386-
bind(OutputServiceImpl).toSelf().inSingletonScope().onActivation(({ container }, outputService) => {
387-
WebSocketConnectionProvider.createProxy(container, OutputServicePath,outputService);
388-
return outputService;
388+
bind(ResponseServiceImpl).toSelf().inSingletonScope().onActivation(({ container }, responseService) => {
389+
WebSocketConnectionProvider.createProxy(container, ResponseServicePath,responseService);
390+
return responseService;
389391
});
390-
bind(OutputService).toService(OutputServiceImpl);
392+
bind(ResponseService).toService(ResponseServiceImpl);
391393

392394
bind(NotificationCenter).toSelf().inSingletonScope();
393395
bind(FrontendApplicationContribution).toService(NotificationCenter);
@@ -439,4 +441,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
439441

440442
bind(StorageWrapper).toSelf().inSingletonScope();
441443
bind(CommandContribution).toService(StorageWrapper);
444+
445+
bind(NotificationManager).toSelf().inSingletonScope();
446+
rebind(TheiaNotificationManager).toService(NotificationManager);
442447
});

‎arduino-ide-extension/src/browser/boards/boards-auto-installer.ts‎

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import { FrontendApplicationContribution } from '@theia/core/lib/browser/fronten
44
import { BoardsService, BoardsPackage } from '../../common/protocol/boards-service';
55
import { BoardsServiceProvider } from './boards-service-provider';
66
import { BoardsListWidgetFrontendContribution } from './boards-widget-frontend-contribution';
7-
import { InstallationProgressDialog } from '../widgets/progress-dialog';
87
import { BoardsConfig } from './boards-config';
8+
import { Installable } from '../../common/protocol';
9+
import { ResponseServiceImpl } from '../response-service-impl';
910

1011
/**
1112
* Listens on `BoardsConfig.Config` changes, if a board is selected which does not
@@ -23,6 +24,9 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
2324
@inject(BoardsServiceProvider)
2425
protected readonly boardsServiceClient: BoardsServiceProvider;
2526

27+
@inject(ResponseServiceImpl)
28+
protected readonly responseService: ResponseServiceImpl;
29+
2630
@inject(BoardsListWidgetFrontendContribution)
2731
protected readonly boardsManagerFrontendContribution: BoardsListWidgetFrontendContribution;
2832

@@ -42,13 +46,13 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
4246
// tslint:disable-next-line:max-line-length
4347
this.messageService.info(`The \`"${candidate.name}"\` core has to be installed for the currently selected \`"${selectedBoard.name}"\` board. Do you want to install it now?`, 'Install Manually', 'Yes').then(async answer => {
4448
if (answer === 'Yes') {
45-
constdialog=newInstallationProgressDialog(candidate.name,candidate.availableVersions[0]);
46-
dialog.open();
47-
try{
48-
await this.boardsService.install({item: candidate});
49-
}finally{
50-
dialog.close();
51-
}
49+
awaitInstallable.installWithProgress({
50+
installable: this.boardsService,
51+
item: candidate,
52+
messageService: this.messageService,
53+
responseService: this.responseService,
54+
version: candidate.availableVersions[0]
55+
});
5256
}
5357
if (answer) {
5458
this.boardsManagerFrontendContribution.openView({ reveal: true }).then(widget => widget.refresh(candidate.name.toLocaleLowerCase()));

‎arduino-ide-extension/src/browser/boards/boards-list-widget.ts‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
3333
]);
3434
}
3535

36-
async install({ item, version }: { item: BoardsPackage; version: string; }): Promise<void> {
37-
await super.install({ item, version });
38-
this.messageService.info(`Successfully installed platform ${item.name}:${version}.`, { timeout: 3000 });
36+
protected async install({ item, progressId, version }: { item: BoardsPackage, progressId: string, version: string; }): Promise<void> {
37+
await super.install({ item, progressId, version });
38+
this.messageService.info(`Successfully installed platform ${item.name}:${version}`, { timeout: 3000 });
39+
}
40+
41+
protected async uninstall({ item, progressId }: { item: BoardsPackage, progressId: string }): Promise<void> {
42+
await super.uninstall({ item, progressId });
43+
this.messageService.info(`Successfully uninstalled platform ${item.name}:${item.installedVersion}`, { timeout: 3000 });
3944
}
4045

4146
}

‎arduino-ide-extension/src/browser/contributions/add-zip-library.ts‎

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
import { inject, injectable } from 'inversify';
22
import { remote } from 'electron';
3+
import URI from '@theia/core/lib/common/uri';
4+
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
5+
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
36
import { ArduinoMenus } from '../menu/arduino-menus';
7+
import { ResponseServiceImpl } from '../response-service-impl';
8+
import { Installable, LibraryService } from '../../common/protocol';
49
import { SketchContribution, Command, CommandRegistry, MenuModelRegistry } from './contribution';
5-
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
6-
import URI from '@theia/core/lib/common/uri';
7-
import { InstallationProgressDialog } from '../widgets/progress-dialog';
8-
import { LibraryService } from '../../common/protocol';
9-
import { ConfirmDialog } from '@theia/core/lib/browser';
1010

1111
@injectable()
1212
export class AddZipLibrary extends SketchContribution {
1313

1414
@inject(EnvVariablesServer)
1515
protected readonly envVariableServer: EnvVariablesServer;
1616

17+
@inject(ResponseServiceImpl)
18+
protected readonly responseService: ResponseServiceImpl;
19+
1720
@inject(LibraryService)
1821
protected readonly libraryService: LibraryService;
1922

@@ -69,11 +72,14 @@ export class AddZipLibrary extends SketchContribution {
6972
}
7073

7174
private async doInstall(zipUri: string, overwrite?: boolean): Promise<void> {
72-
const dialog = new InstallationProgressDialog('Installing library', 'zip');
7375
try {
74-
this.outputChannelManager.getChannel('Arduino').clear();
75-
dialog.open();
76-
await this.libraryService.installZip({ zipUri, overwrite });
76+
await Installable.doWithProgress({
77+
messageService: this.messageService,
78+
progressText: `Processing ${new URI(zipUri).path.base}`,
79+
responseService: this.responseService,
80+
run: () => this.libraryService.installZip({ zipUri, overwrite })
81+
});
82+
this.messageService.info(`Successfully installed library from ${new URI(zipUri).path.base} archive`, { timeout: 3000 });
7783
} catch (error) {
7884
if (error instanceof Error) {
7985
const match = error.message.match(/library(.*?)alreadyinstalled/);
@@ -88,8 +94,6 @@ export class AddZipLibrary extends SketchContribution {
8894
}
8995
this.messageService.error(error.toString());
9096
throw error;
91-
} finally {
92-
dialog.close();
9397
}
9498
}
9599

‎arduino-ide-extension/src/browser/library/library-list-widget.ts‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
3737
]);
3838
}
3939

40-
protected async install({ item, version }: { item: LibraryPackage, version: Installable.Version }): Promise<void> {
40+
protected async install({ item, progressId,version }: { item: LibraryPackage,progressId: string, version: Installable.Version }): Promise<void> {
4141
const dependencies = await this.service.listDependencies({ item, version, filterSelf: true });
4242
let installDependencies: boolean | undefined = undefined;
4343
if (dependencies.length) {
@@ -84,11 +84,16 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
8484
}
8585

8686
if (typeof installDependencies === 'boolean') {
87-
await this.service.install({ item, version, installDependencies });
88-
this.messageService.info(`Successfully installed library ${item.name}:${version}.`, { timeout: 3000 });
87+
await this.service.install({ item, version, progressId,installDependencies });
88+
this.messageService.info(`Successfully installed library ${item.name}:${version}`, { timeout: 3000 });
8989
}
9090
}
9191

92+
protected async uninstall({ item, progressId }: { item: LibraryPackage, progressId: string }): Promise<void> {
93+
await super.uninstall({ item, progressId });
94+
this.messageService.info(`Successfully uninstalled library ${item.name}:${item.installedVersion}`, { timeout: 3000 });
95+
}
96+
9297
}
9398

9499
class MessageBoxDialog extends AbstractDialog<MessageBoxDialog.Result> {

‎arduino-ide-extension/src/browser/output-service-impl.ts‎

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { inject, injectable } from 'inversify';
2+
import { Emitter } from '@theia/core/lib/common/event';
3+
import { OutputContribution } from '@theia/output/lib/browser/output-contribution';
4+
import { OutputChannelManager } from '@theia/output/lib/common/output-channel';
5+
import { ResponseService, OutputMessage, ProgressMessage } from '../common/protocol/response-service';
6+
7+
@injectable()
8+
export class ResponseServiceImpl implements ResponseService {
9+
10+
@inject(OutputContribution)
11+
protected outputContribution: OutputContribution;
12+
13+
@inject(OutputChannelManager)
14+
protected outputChannelManager: OutputChannelManager;
15+
16+
protected readonly progressDidChangeEmitter = new Emitter<ProgressMessage>();
17+
readonly onProgressDidChange = this.progressDidChangeEmitter.event;
18+
19+
appendToOutput(message: OutputMessage): void {
20+
const { chunk } = message;
21+
const channel = this.outputChannelManager.getChannel('Arduino');
22+
channel.show({ preserveFocus: true });
23+
channel.append(chunk);
24+
}
25+
26+
clearArduinoChannel(): void {
27+
this.outputChannelManager.getChannel('Arduino').clear();
28+
}
29+
30+
reportProgress(progress: ProgressMessage): void {
31+
this.progressDidChangeEmitter.fire(progress);
32+
}
33+
34+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { injectable } from 'inversify';
2+
import { CancellationToken } from '@theia/core/lib/common/cancellation';
3+
import { ProgressMessage, ProgressUpdate } from '@theia/core/lib/common/message-service-protocol';
4+
import { NotificationManager as TheiaNotificationManager } from '@theia/messages/lib/browser/notifications-manager';
5+
6+
@injectable()
7+
export class NotificationManager extends TheiaNotificationManager {
8+
9+
async reportProgress(messageId: string, update: ProgressUpdate, originalMessage: ProgressMessage, cancellationToken: CancellationToken): Promise<void> {
10+
const notification = this.find(messageId);
11+
if (!notification) {
12+
return;
13+
}
14+
if (cancellationToken.isCancellationRequested) {
15+
this.clear(messageId);
16+
} else {
17+
notification.message = originalMessage.text && update.message ? `${originalMessage.text}: ${update.message}` :
18+
originalMessage.text || update?.message || notification.message;
19+
20+
// Unlike in Theia, we allow resetting the progress monitor to zero.
21+
const candidate = this.toPlainProgress(update);
22+
notification.progress = typeof candidate === 'number' ? candidate : notification.progress;
23+
}
24+
this.fireUpdatedEvent();
25+
}
26+
27+
}

‎arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx‎

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ import debounce = require('lodash.debounce');
33
import { Event } from '@theia/core/lib/common/event';
44
import { CommandService } from '@theia/core/lib/common/command';
55
import { MessageService } from '@theia/core/lib/common/message-service';
6-
import { OutputCommands } from '@theia/output/lib/browser/output-commands';
76
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
87
import { Searchable } from '../../../common/protocol/searchable';
98
import { Installable } from '../../../common/protocol/installable';
109
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
11-
import { InstallationProgressDialog, UninstallationProgressDialog } from '../progress-dialog';
1210
import { SearchBar } from './search-bar';
1311
import { ListWidget } from './list-widget';
1412
import { ComponentList } from './component-list';
1513
import { ListItemRenderer } from './list-item-renderer';
14+
import { ResponseServiceImpl } from '../../response-service-impl';
1615

1716
export class FilterableListContainer<T extends ArduinoComponent> extends React.Component<FilterableListContainer.Props<T>, FilterableListContainer.State<T>> {
1817

@@ -84,20 +83,14 @@ export class FilterableListContainer<T extends ArduinoComponent> extends React.C
8483
}
8584

8685
protected async install(item: T, version: Installable.Version): Promise<void> {
87-
const { install, searchable, itemLabel } = this.props;
88-
const dialog = new InstallationProgressDialog(itemLabel(item), version);
89-
try {
90-
dialog.open();
91-
await this.clearArduinoChannel();
92-
await install({ item, version });
93-
const items = await searchable.search({ query: this.state.filterText });
94-
this.setState({ items: this.sort(items) });
95-
} catch (error) {
96-
this.props.messageService.error(error instanceof Error ? error.message : String(error));
97-
throw error;
98-
} finally {
99-
dialog.close();
100-
}
86+
const { install, searchable } = this.props;
87+
await Installable.doWithProgress({
88+
...this.props,
89+
progressText: `Processing ${item.name}:${version}`,
90+
run: ({ progressId }) => install({ item, progressId, version })
91+
});
92+
const items = await searchable.search({ query: this.state.filterText });
93+
this.setState({ items: this.sort(items) });
10194
}
10295

10396
protected async uninstall(item: T): Promise<void> {
@@ -110,21 +103,14 @@ export class FilterableListContainer<T extends ArduinoComponent> extends React.C
110103
if (!ok) {
111104
return;
112105
}
113-
const { uninstall, searchable, itemLabel } = this.props;
114-
const dialog = new UninstallationProgressDialog(itemLabel(item));
115-
try {
116-
await this.clearArduinoChannel();
117-
dialog.open();
118-
await uninstall({ item });
119-
const items = await searchable.search({ query: this.state.filterText });
120-
this.setState({ items: this.sort(items) });
121-
} finally {
122-
dialog.close();
123-
}
124-
}
125-
126-
private async clearArduinoChannel(): Promise<void> {
127-
return this.props.commandService.executeCommand(OutputCommands.CLEAR.id, { name: 'Arduino' });
106+
const { uninstall, searchable } = this.props;
107+
await Installable.doWithProgress({
108+
...this.props,
109+
progressText: `Processing ${item.name}${item.installedVersion ? `:${item.installedVersion}` : ''}`,
110+
run: ({ progressId }) => uninstall({ item, progressId })
111+
});
112+
const items = await searchable.search({ query: this.state.filterText });
113+
this.setState({ items: this.sort(items) });
128114
}
129115

130116
}
@@ -139,9 +125,10 @@ export namespace FilterableListContainer {
139125
readonly resolveContainer: (element: HTMLElement) => void;
140126
readonly resolveFocus: (element: HTMLElement | undefined) => void;
141127
readonly filterTextChangeEvent: Event<string | undefined>;
142-
readonly install: ({ item, version }: { item: T, version: Installable.Version }) => Promise<void>;
143-
readonly uninstall: ({ item }: { item: T }) => Promise<void>;
144128
readonly messageService: MessageService;
129+
readonly responseService: ResponseServiceImpl;
130+
readonly install: ({ item, progressId, version }: { item: T, progressId: string, version: Installable.Version }) => Promise<void>;
131+
readonly uninstall: ({ item, progressId }: { item: T, progressId: string }) => Promise<void>;
145132
readonly commandService: CommandService;
146133
}
147134

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /