Wait until the boards config has been reset

from the local storage, then start the monitor connection.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
Akos Kitta 2019-12-05 17:14:54 +01:00
parent 8c49c04359
commit 557ec2ae42
5 changed files with 38 additions and 28 deletions

View File

@ -119,6 +119,7 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un
}).inSingletonScope(); }).inSingletonScope();
// Boards service client to receive and delegate notifications from the backend. // Boards service client to receive and delegate notifications from the backend.
bind(BoardsServiceClientImpl).toSelf().inSingletonScope(); bind(BoardsServiceClientImpl).toSelf().inSingletonScope();
bind(FrontendApplicationContribution).toService(BoardsServiceClientImpl);
bind(BoardsServiceClient).toDynamicValue(context => { bind(BoardsServiceClient).toDynamicValue(context => {
const client = context.container.get(BoardsServiceClientImpl); const client = context.container.get(BoardsServiceClientImpl);
WebSocketConnectionProvider.createProxy(context.container, BoardsServicePath, client); WebSocketConnectionProvider.createProxy(context.container, BoardsServicePath, client);

View File

@ -1,14 +1,15 @@
import { injectable, inject, postConstruct } from 'inversify'; import { injectable, inject } from 'inversify';
import { Emitter } from '@theia/core/lib/common/event'; import { Emitter } from '@theia/core/lib/common/event';
import { ILogger } from '@theia/core/lib/common/logger'; import { ILogger } from '@theia/core/lib/common/logger';
import { MessageService } from '@theia/core/lib/common/message-service';
import { LocalStorageService } from '@theia/core/lib/browser/storage-service'; import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
import { RecursiveRequired } from '../../common/types'; import { RecursiveRequired } from '../../common/types';
import { BoardsServiceClient, AttachedBoardsChangeEvent, BoardInstalledEvent, AttachedSerialBoard, Board, Port, BoardUninstalledEvent } from '../../common/protocol/boards-service'; import { BoardsServiceClient, AttachedBoardsChangeEvent, BoardInstalledEvent, AttachedSerialBoard, Board, Port, BoardUninstalledEvent } from '../../common/protocol/boards-service';
import { BoardsConfig } from './boards-config'; import { BoardsConfig } from './boards-config';
import { MessageService } from '@theia/core';
@injectable() @injectable()
export class BoardsServiceClientImpl implements BoardsServiceClient { export class BoardsServiceClientImpl implements BoardsServiceClient, FrontendApplicationContribution {
@inject(ILogger) @inject(ILogger)
protected logger: ILogger; protected logger: ILogger;
@ -39,9 +40,8 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
readonly onBoardUninstalled = this.onBoardUninstalledEmitter.event; readonly onBoardUninstalled = this.onBoardUninstalledEmitter.event;
readonly onBoardsConfigChanged = this.onSelectedBoardsConfigChangedEmitter.event; readonly onBoardsConfigChanged = this.onSelectedBoardsConfigChangedEmitter.event;
@postConstruct() async onStart(): Promise<void> {
protected init(): void { return this.loadState();
this.loadState();
} }
notifyAttachedBoardsChanged(event: AttachedBoardsChangeEvent): void { notifyAttachedBoardsChanged(event: AttachedBoardsChangeEvent): void {
@ -124,7 +124,7 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
if (!config.selectedBoard) { if (!config.selectedBoard) {
if (!options.silent) { if (!options.silent) {
this.messageService.warn('No boards selected.'); this.messageService.warn('No boards selected.', { timeout: 3000 });
} }
return false; return false;
} }
@ -146,14 +146,14 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
const { name } = config.selectedBoard; const { name } = config.selectedBoard;
if (!config.selectedPort) { if (!config.selectedPort) {
if (!options.silent) { if (!options.silent) {
this.messageService.warn(`No ports selected for board: '${name}'.`); this.messageService.warn(`No ports selected for board: '${name}'.`, { timeout: 3000 });
} }
return false; return false;
} }
if (!config.selectedBoard.fqbn) { if (!config.selectedBoard.fqbn) {
if (!options.silent) { if (!options.silent) {
this.messageService.warn(`The FQBN is not available for the selected board ${name}. Do you have the corresponding core installed?`); this.messageService.warn(`The FQBN is not available for the selected board ${name}. Do you have the corresponding core installed?`, { timeout: 3000 });
} }
return false; return false;
} }
@ -169,6 +169,9 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
const storedValidBoardsConfig = await this.storageService.getData<RecursiveRequired<BoardsConfig.Config>>('latest-valid-boards-config'); const storedValidBoardsConfig = await this.storageService.getData<RecursiveRequired<BoardsConfig.Config>>('latest-valid-boards-config');
if (storedValidBoardsConfig) { if (storedValidBoardsConfig) {
this.latestValidBoardsConfig = storedValidBoardsConfig; this.latestValidBoardsConfig = storedValidBoardsConfig;
if (this.canUploadTo(this.latestValidBoardsConfig)) {
this.boardsConfig = this.latestValidBoardsConfig;
}
} }
} }

View File

@ -2,6 +2,7 @@ import { injectable, inject, postConstruct } from 'inversify';
import { Emitter, Event } from '@theia/core/lib/common/event'; import { Emitter, Event } from '@theia/core/lib/common/event';
// import { ConnectionStatusService } from '@theia/core/lib/browser/connection-status-service'; // import { ConnectionStatusService } from '@theia/core/lib/browser/connection-status-service';
import { MessageService } from '@theia/core/lib/common/message-service'; import { MessageService } from '@theia/core/lib/common/message-service';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { MonitorService, MonitorConfig, MonitorError, Status } from '../../common/protocol/monitor-service'; import { MonitorService, MonitorConfig, MonitorError, Status } from '../../common/protocol/monitor-service';
import { BoardsServiceClientImpl } from '../boards/boards-service-client-impl'; import { BoardsServiceClientImpl } from '../boards/boards-service-client-impl';
import { Port, Board, BoardsService, AttachedSerialBoard, AttachedBoardsChangeEvent } from '../../common/protocol/boards-service'; import { Port, Board, BoardsService, AttachedSerialBoard, AttachedBoardsChangeEvent } from '../../common/protocol/boards-service';
@ -33,6 +34,9 @@ export class MonitorConnection {
// @inject(ConnectionStatusService) // @inject(ConnectionStatusService)
// protected readonly connectionStatusService: ConnectionStatusService; // protected readonly connectionStatusService: ConnectionStatusService;
@inject(FrontendApplicationStateService)
protected readonly applicationState: FrontendApplicationStateService;
protected state: MonitorConnection.State | undefined; protected state: MonitorConnection.State | undefined;
/** /**
* Note: The idea is to toggle this property from the UI (`Monitor` view) * Note: The idea is to toggle this property from the UI (`Monitor` view)
@ -120,8 +124,12 @@ export class MonitorConnection {
this._autoConnect = value; this._autoConnect = value;
// When we enable the auto-connect, we have to connect // When we enable the auto-connect, we have to connect
if (!oldValue && value) { if (!oldValue && value) {
const { boardsConfig } = this.boardsServiceClient; // We have to make sure the previous boards config has been restored.
this.handleBoardConfigChange(boardsConfig); // Otherwise, we might start the auto-connection without configured boards.
this.applicationState.reachedState('started_contributions').then(() => {
const { boardsConfig } = this.boardsServiceClient;
this.handleBoardConfigChange(boardsConfig);
});
} }
} }

View File

@ -59,13 +59,13 @@ export class MonitorViewContribution extends AbstractViewContribution<MonitorWid
id: 'monitor-autoscroll', id: 'monitor-autoscroll',
render: () => this.renderAutoScrollButton(), render: () => this.renderAutoScrollButton(),
isVisible: widget => widget instanceof MonitorWidget, isVisible: widget => widget instanceof MonitorWidget,
onDidChange: this.model.onChange as any // TODO: https://github.com/eclipse-theia/theia/pull/6696/ onDidChange: this.model.onChange as any // XXX: it's a hack. See: https://github.com/eclipse-theia/theia/pull/6696/
}); });
registry.registerItem({ registry.registerItem({
id: 'monitor-timestamp', id: 'monitor-timestamp',
render: () => this.renderTimestampButton(), render: () => this.renderTimestampButton(),
isVisible: widget => widget instanceof MonitorWidget, isVisible: widget => widget instanceof MonitorWidget,
onDidChange: this.model.onChange as any // TODO: https://github.com/eclipse-theia/theia/pull/6696/ onDidChange: this.model.onChange as any // XXX: it's a hack. See: https://github.com/eclipse-theia/theia/pull/6696/
}); });
registry.registerItem({ registry.registerItem({
id: SerialMonitor.Commands.CLEAR_OUTPUT.id, id: SerialMonitor.Commands.CLEAR_OUTPUT.id,

View File

@ -169,7 +169,7 @@ export namespace SerialMonitorSendInput {
readonly resolveFocus: (element: HTMLElement | undefined) => void; readonly resolveFocus: (element: HTMLElement | undefined) => void;
} }
export interface State { export interface State {
value: string; text: string;
} }
} }
@ -177,23 +177,21 @@ export class SerialMonitorSendInput extends React.Component<SerialMonitorSendInp
constructor(props: Readonly<SerialMonitorSendInput.Props>) { constructor(props: Readonly<SerialMonitorSendInput.Props>) {
super(props); super(props);
this.state = { value: '' }; this.state = { text: '' };
this.onChange = this.onChange.bind(this); this.onChange = this.onChange.bind(this);
this.onSend = this.onSend.bind(this); this.onSend = this.onSend.bind(this);
this.onKeyDown = this.onKeyDown.bind(this); this.onKeyDown = this.onKeyDown.bind(this);
} }
render(): React.ReactNode { render(): React.ReactNode {
return <React.Fragment> return <input
<input ref={this.setRef}
ref={this.setRef} type='text'
type='text' className={this.props.monitorConfig ? '' : 'not-connected'}
className={this.props.monitorConfig ? '' : 'not-connected'} placeholder={this.placeholder}
placeholder={this.placeholder} value={this.state.text}
value={this.state.value} onChange={this.onChange}
onChange={this.onChange} onKeyDown={this.onKeyDown} />
onKeyDown={this.onKeyDown} />
</React.Fragment>
} }
protected get placeholder(): string { protected get placeholder(): string {
@ -212,12 +210,12 @@ export class SerialMonitorSendInput extends React.Component<SerialMonitorSendInp
} }
protected onChange(event: React.ChangeEvent<HTMLInputElement>): void { protected onChange(event: React.ChangeEvent<HTMLInputElement>): void {
this.setState({ value: event.target.value }); this.setState({ text: event.target.value });
} }
protected onSend(): void { protected onSend(): void {
this.props.onSend(this.state.value); this.props.onSend(this.state.text);
this.setState({ value: '' }); this.setState({ text: '' });
} }
protected onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void { protected onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {