mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-11-12 19:59:27 +00:00
Implemented filter and update all for libs/boards.
Closes #177 Closes #1188 Co-authored-by: Francesco Spissu <f.spissu@arduino.cc> Co-authored-by: Per Tillisch <p.tillisch@arduino.cc> Co-authored-by: Akos Kitta <a.kitta@arduino.cc> Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
@@ -314,7 +314,7 @@ import { FirstStartupInstaller } from './contributions/first-startup-installer';
|
||||
import { OpenSketchFiles } from './contributions/open-sketch-files';
|
||||
import { InoLanguage } from './contributions/ino-language';
|
||||
import { SelectedBoard } from './contributions/selected-board';
|
||||
import { CheckForUpdates } from './contributions/check-for-updates';
|
||||
import { CheckForIDEUpdates } from './contributions/check-for-ide-updates';
|
||||
import { OpenBoardsConfig } from './contributions/open-boards-config';
|
||||
import { SketchFilesTracker } from './contributions/sketch-files-tracker';
|
||||
import { MonacoThemeServiceIsReady } from './utils/window';
|
||||
@@ -323,6 +323,15 @@ import { StatusBarImpl } from './theia/core/status-bar';
|
||||
import { StatusBarImpl as TheiaStatusBarImpl } from '@theia/core/lib/browser';
|
||||
import { EditorMenuContribution } from './theia/editor/editor-file';
|
||||
import { EditorMenuContribution as TheiaEditorMenuContribution } from '@theia/editor/lib/browser/editor-menu';
|
||||
import { PreferencesEditorWidget as TheiaPreferencesEditorWidget } from '@theia/preferences/lib/browser/views/preference-editor-widget';
|
||||
import { PreferencesEditorWidget } from './theia/preferences/preference-editor-widget';
|
||||
import { PreferencesWidget } from '@theia/preferences/lib/browser/views/preference-widget';
|
||||
import { createPreferencesWidgetContainer } from '@theia/preferences/lib/browser/views/preference-widget-bindings';
|
||||
import {
|
||||
BoardsFilterRenderer,
|
||||
LibraryFilterRenderer,
|
||||
} from './widgets/component-list/filter-renderer';
|
||||
import { CheckForUpdates } from './contributions/check-for-updates';
|
||||
|
||||
const registerArduinoThemes = () => {
|
||||
const themes: MonacoThemeJson[] = [
|
||||
@@ -364,6 +373,8 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
|
||||
// Renderer for both the library and the core widgets.
|
||||
bind(ListItemRenderer).toSelf().inSingletonScope();
|
||||
bind(LibraryFilterRenderer).toSelf().inSingletonScope();
|
||||
bind(BoardsFilterRenderer).toSelf().inSingletonScope();
|
||||
|
||||
// Library service
|
||||
bind(LibraryService)
|
||||
@@ -737,9 +748,10 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
Contribution.configure(bind, OpenSketchFiles);
|
||||
Contribution.configure(bind, InoLanguage);
|
||||
Contribution.configure(bind, SelectedBoard);
|
||||
Contribution.configure(bind, CheckForUpdates);
|
||||
Contribution.configure(bind, CheckForIDEUpdates);
|
||||
Contribution.configure(bind, OpenBoardsConfig);
|
||||
Contribution.configure(bind, SketchFilesTracker);
|
||||
Contribution.configure(bind, CheckForUpdates);
|
||||
|
||||
// Disabled the quick-pick customization from Theia when multiple formatters are available.
|
||||
// Use the default VS Code behavior, and pick the first one. In the IDE2, clang-format has `exclusive` selectors.
|
||||
@@ -845,6 +857,18 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(DockPanelRenderer).toSelf();
|
||||
rebind(TheiaDockPanelRenderer).toService(DockPanelRenderer);
|
||||
|
||||
// Avoid running the "reset scroll" interval tasks until the preference editor opens.
|
||||
rebind(PreferencesWidget)
|
||||
.toDynamicValue(({ container }) => {
|
||||
const child = createPreferencesWidgetContainer(container);
|
||||
child.bind(PreferencesEditorWidget).toSelf().inSingletonScope();
|
||||
child
|
||||
.rebind(TheiaPreferencesEditorWidget)
|
||||
.toService(PreferencesEditorWidget);
|
||||
return child.get(PreferencesWidget);
|
||||
})
|
||||
.inSingletonScope();
|
||||
|
||||
// Preferences
|
||||
bindArduinoPreferences(bind);
|
||||
|
||||
|
||||
@@ -241,6 +241,14 @@ export const ArduinoConfigSchema: PreferenceSchema = {
|
||||
),
|
||||
default: false,
|
||||
},
|
||||
'arduino.checkForUpdates': {
|
||||
type: 'boolean',
|
||||
description: nls.localize(
|
||||
'arduino/preferences/checkForUpdate',
|
||||
"Receive notifications of available updates for the IDE, boards, and libraries. Requires an IDE restart after change. It's true by default."
|
||||
),
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -270,6 +278,7 @@ export interface ArduinoConfiguration {
|
||||
'arduino.auth.registerUri': string;
|
||||
'arduino.survey.notification': boolean;
|
||||
'arduino.cli.daemon.debug': boolean;
|
||||
'arduino.checkForUpdates': boolean;
|
||||
}
|
||||
|
||||
export const ArduinoPreferences = Symbol('ArduinoPreferences');
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Installable, ResponseServiceClient } from '../../common/protocol';
|
||||
import { BoardsListWidgetFrontendContribution } from './boards-widget-frontend-contribution';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import { InstallManually } from '../../common/nls';
|
||||
|
||||
interface AutoInstallPromptAction {
|
||||
// isAcceptance, whether or not the action indicates acceptance of auto-install proposal
|
||||
@@ -231,19 +232,18 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
|
||||
candidate: BoardsPackage
|
||||
): AutoInstallPromptActions {
|
||||
const yes = nls.localize('vscode/extensionsUtils/yes', 'Yes');
|
||||
const manualInstall = nls.localize(
|
||||
'arduino/board/installManually',
|
||||
'Install Manually'
|
||||
);
|
||||
|
||||
const actions: AutoInstallPromptActions = [
|
||||
{
|
||||
key: manualInstall,
|
||||
key: InstallManually,
|
||||
handler: () => {
|
||||
this.boardsManagerFrontendContribution
|
||||
.openView({ reveal: true })
|
||||
.then((widget) =>
|
||||
widget.refresh(candidate.name.toLocaleLowerCase())
|
||||
widget.refresh({
|
||||
query: candidate.name.toLocaleLowerCase(),
|
||||
type: 'All',
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -4,22 +4,24 @@ import {
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import {
|
||||
BoardSearch,
|
||||
BoardsPackage,
|
||||
BoardsService,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import { ListWidget } from '../widgets/component-list/list-widget';
|
||||
import { ListItemRenderer } from '../widgets/component-list/list-item-renderer';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { BoardsFilterRenderer } from '../widgets/component-list/filter-renderer';
|
||||
|
||||
@injectable()
|
||||
export class BoardsListWidget extends ListWidget<BoardsPackage> {
|
||||
export class BoardsListWidget extends ListWidget<BoardsPackage, BoardSearch> {
|
||||
static WIDGET_ID = 'boards-list-widget';
|
||||
static WIDGET_LABEL = nls.localize('arduino/boardsManager', 'Boards Manager');
|
||||
|
||||
constructor(
|
||||
@inject(BoardsService) protected service: BoardsService,
|
||||
@inject(ListItemRenderer)
|
||||
protected itemRenderer: ListItemRenderer<BoardsPackage>
|
||||
@inject(BoardsService) service: BoardsService,
|
||||
@inject(ListItemRenderer) itemRenderer: ListItemRenderer<BoardsPackage>,
|
||||
@inject(BoardsFilterRenderer) filterRenderer: BoardsFilterRenderer
|
||||
) {
|
||||
super({
|
||||
id: BoardsListWidget.WIDGET_ID,
|
||||
@@ -30,6 +32,8 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
|
||||
itemLabel: (item: BoardsPackage) => item.name,
|
||||
itemDeprecated: (item: BoardsPackage) => item.deprecated,
|
||||
itemRenderer,
|
||||
filterRenderer,
|
||||
defaultSearchOptions: { query: '', type: 'All' },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { BoardsListWidget } from './boards-list-widget';
|
||||
import { BoardsPackage } from '../../common/protocol/boards-service';
|
||||
import type {
|
||||
BoardSearch,
|
||||
BoardsPackage,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import { ListWidgetFrontendContribution } from '../widgets/component-list/list-widget-frontend-contribution';
|
||||
|
||||
@injectable()
|
||||
export class BoardsListWidgetFrontendContribution extends ListWidgetFrontendContribution<BoardsPackage> {
|
||||
export class BoardsListWidgetFrontendContribution extends ListWidgetFrontendContribution<
|
||||
BoardsPackage,
|
||||
BoardSearch
|
||||
> {
|
||||
constructor() {
|
||||
super({
|
||||
widgetId: BoardsListWidget.WIDGET_ID,
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
IDEUpdater,
|
||||
SKIP_IDE_VERSION,
|
||||
} from '../../common/protocol/ide-updater';
|
||||
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
||||
import { Contribution } from './contribution';
|
||||
|
||||
@injectable()
|
||||
export class CheckForIDEUpdates extends Contribution {
|
||||
@inject(IDEUpdater)
|
||||
private readonly updater: IDEUpdater;
|
||||
|
||||
@inject(IDEUpdaterDialog)
|
||||
private readonly updaterDialog: IDEUpdaterDialog;
|
||||
|
||||
@inject(LocalStorageService)
|
||||
private readonly localStorage: LocalStorageService;
|
||||
|
||||
override onStart(): void {
|
||||
this.preferences.onPreferenceChanged(
|
||||
({ preferenceName, newValue, oldValue }) => {
|
||||
if (newValue !== oldValue) {
|
||||
switch (preferenceName) {
|
||||
case 'arduino.ide.updateChannel':
|
||||
case 'arduino.ide.updateBaseUrl':
|
||||
this.updater.init(
|
||||
this.preferences.get('arduino.ide.updateChannel'),
|
||||
this.preferences.get('arduino.ide.updateBaseUrl')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
override onReady(): void {
|
||||
const checkForUpdates = this.preferences['arduino.checkForUpdates'];
|
||||
if (!checkForUpdates) {
|
||||
return;
|
||||
}
|
||||
this.updater
|
||||
.init(
|
||||
this.preferences.get('arduino.ide.updateChannel'),
|
||||
this.preferences.get('arduino.ide.updateBaseUrl')
|
||||
)
|
||||
.then(() => this.updater.checkForUpdates(true))
|
||||
.then(async (updateInfo) => {
|
||||
if (!updateInfo) return;
|
||||
const versionToSkip = await this.localStorage.getData<string>(
|
||||
SKIP_IDE_VERSION
|
||||
);
|
||||
if (versionToSkip === updateInfo.version) return;
|
||||
this.updaterDialog.open(updateInfo);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.messageService.error(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/errorCheckingForUpdates',
|
||||
'Error while checking for Arduino IDE updates.\n{0}',
|
||||
e.message
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,64 +1,221 @@
|
||||
import type { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { InstallManually, Later } from '../../common/nls';
|
||||
import {
|
||||
IDEUpdater,
|
||||
SKIP_IDE_VERSION,
|
||||
} from '../../common/protocol/ide-updater';
|
||||
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
||||
import { Contribution } from './contribution';
|
||||
ArduinoComponent,
|
||||
BoardsPackage,
|
||||
BoardsService,
|
||||
LibraryPackage,
|
||||
LibraryService,
|
||||
ResponseServiceClient,
|
||||
Searchable,
|
||||
} from '../../common/protocol';
|
||||
import { Installable } from '../../common/protocol/installable';
|
||||
import { ExecuteWithProgress } from '../../common/protocol/progressible';
|
||||
import { BoardsListWidgetFrontendContribution } from '../boards/boards-widget-frontend-contribution';
|
||||
import { LibraryListWidgetFrontendContribution } from '../library/library-widget-frontend-contribution';
|
||||
import { WindowServiceExt } from '../theia/core/window-service-ext';
|
||||
import type { ListWidget } from '../widgets/component-list/list-widget';
|
||||
import { Command, CommandRegistry, Contribution } from './contribution';
|
||||
|
||||
const NoUpdates = nls.localize(
|
||||
'arduino/checkForUpdates/noUpdates',
|
||||
'There are no recent updates available.'
|
||||
);
|
||||
const PromptUpdateBoards = nls.localize(
|
||||
'arduino/checkForUpdates/promptUpdateBoards',
|
||||
'Updates are available for some of your boards.'
|
||||
);
|
||||
const PromptUpdateLibraries = nls.localize(
|
||||
'arduino/checkForUpdates/promptUpdateLibraries',
|
||||
'Updates are available for some of your libraries.'
|
||||
);
|
||||
const UpdatingBoards = nls.localize(
|
||||
'arduino/checkForUpdates/updatingBoards',
|
||||
'Updating boards...'
|
||||
);
|
||||
const UpdatingLibraries = nls.localize(
|
||||
'arduino/checkForUpdates/updatingLibraries',
|
||||
'Updating libraries...'
|
||||
);
|
||||
const InstallAll = nls.localize(
|
||||
'arduino/checkForUpdates/installAll',
|
||||
'Install All'
|
||||
);
|
||||
|
||||
interface Task<T extends ArduinoComponent> {
|
||||
readonly run: () => Promise<void>;
|
||||
readonly item: T;
|
||||
}
|
||||
|
||||
const Updatable = { type: 'Updatable' } as const;
|
||||
|
||||
@injectable()
|
||||
export class CheckForUpdates extends Contribution {
|
||||
@inject(IDEUpdater)
|
||||
private readonly updater: IDEUpdater;
|
||||
@inject(WindowServiceExt)
|
||||
private readonly windowService: WindowServiceExt;
|
||||
@inject(ResponseServiceClient)
|
||||
private readonly responseService: ResponseServiceClient;
|
||||
@inject(BoardsService)
|
||||
private readonly boardsService: BoardsService;
|
||||
@inject(LibraryService)
|
||||
private readonly libraryService: LibraryService;
|
||||
@inject(BoardsListWidgetFrontendContribution)
|
||||
private readonly boardsContribution: BoardsListWidgetFrontendContribution;
|
||||
@inject(LibraryListWidgetFrontendContribution)
|
||||
private readonly librariesContribution: LibraryListWidgetFrontendContribution;
|
||||
|
||||
@inject(IDEUpdaterDialog)
|
||||
private readonly updaterDialog: IDEUpdaterDialog;
|
||||
|
||||
@inject(LocalStorageService)
|
||||
private readonly localStorage: LocalStorageService;
|
||||
|
||||
override onStart(): void {
|
||||
this.preferences.onPreferenceChanged(
|
||||
({ preferenceName, newValue, oldValue }) => {
|
||||
if (newValue !== oldValue) {
|
||||
switch (preferenceName) {
|
||||
case 'arduino.ide.updateChannel':
|
||||
case 'arduino.ide.updateBaseUrl':
|
||||
this.updater.init(
|
||||
this.preferences.get('arduino.ide.updateChannel'),
|
||||
this.preferences.get('arduino.ide.updateBaseUrl')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
override registerCommands(register: CommandRegistry): void {
|
||||
register.registerCommand(CheckForUpdates.Commands.CHECK_FOR_UPDATES, {
|
||||
execute: () => this.checkForUpdates(false),
|
||||
});
|
||||
}
|
||||
|
||||
override onReady(): void {
|
||||
this.updater
|
||||
.init(
|
||||
this.preferences.get('arduino.ide.updateChannel'),
|
||||
this.preferences.get('arduino.ide.updateBaseUrl')
|
||||
)
|
||||
.then(() => this.updater.checkForUpdates(true))
|
||||
.then(async (updateInfo) => {
|
||||
if (!updateInfo) return;
|
||||
const versionToSkip = await this.localStorage.getData<string>(
|
||||
SKIP_IDE_VERSION
|
||||
);
|
||||
if (versionToSkip === updateInfo.version) return;
|
||||
this.updaterDialog.open(updateInfo);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.messageService.error(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/errorCheckingForUpdates',
|
||||
'Error while checking for Arduino IDE updates.\n{0}',
|
||||
e.message
|
||||
)
|
||||
);
|
||||
override async onReady(): Promise<void> {
|
||||
const checkForUpdates = this.preferences['arduino.checkForUpdates'];
|
||||
if (checkForUpdates) {
|
||||
this.windowService.isFirstWindow().then((firstWindow) => {
|
||||
if (firstWindow) {
|
||||
this.checkForUpdates();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async checkForUpdates(silent = true) {
|
||||
const [boardsPackages, libraryPackages] = await Promise.all([
|
||||
this.boardsService.search(Updatable),
|
||||
this.libraryService.search(Updatable),
|
||||
]);
|
||||
this.promptUpdateBoards(boardsPackages);
|
||||
this.promptUpdateLibraries(libraryPackages);
|
||||
if (!libraryPackages.length && !boardsPackages.length && !silent) {
|
||||
this.messageService.info(NoUpdates);
|
||||
}
|
||||
}
|
||||
|
||||
private promptUpdateBoards(items: BoardsPackage[]): void {
|
||||
this.prompt({
|
||||
items,
|
||||
installable: this.boardsService,
|
||||
viewContribution: this.boardsContribution,
|
||||
viewSearchOptions: { query: '', ...Updatable },
|
||||
promptMessage: PromptUpdateBoards,
|
||||
updatingMessage: UpdatingBoards,
|
||||
});
|
||||
}
|
||||
|
||||
private promptUpdateLibraries(items: LibraryPackage[]): void {
|
||||
this.prompt({
|
||||
items,
|
||||
installable: this.libraryService,
|
||||
viewContribution: this.librariesContribution,
|
||||
viewSearchOptions: { query: '', topic: 'All', ...Updatable },
|
||||
promptMessage: PromptUpdateLibraries,
|
||||
updatingMessage: UpdatingLibraries,
|
||||
});
|
||||
}
|
||||
|
||||
private prompt<
|
||||
T extends ArduinoComponent,
|
||||
S extends Searchable.Options
|
||||
>(options: {
|
||||
items: T[];
|
||||
installable: Installable<T>;
|
||||
viewContribution: AbstractViewContribution<ListWidget<T, S>>;
|
||||
viewSearchOptions: S;
|
||||
promptMessage: string;
|
||||
updatingMessage: string;
|
||||
}): void {
|
||||
const {
|
||||
items,
|
||||
installable,
|
||||
viewContribution,
|
||||
promptMessage: message,
|
||||
viewSearchOptions,
|
||||
updatingMessage,
|
||||
} = options;
|
||||
|
||||
if (!items.length) {
|
||||
return;
|
||||
}
|
||||
this.messageService
|
||||
.info(message, Later, InstallManually, InstallAll)
|
||||
.then((answer) => {
|
||||
if (answer === InstallAll) {
|
||||
const tasks = items.map((item) =>
|
||||
this.createInstallTask(item, installable)
|
||||
);
|
||||
this.executeTasks(updatingMessage, tasks);
|
||||
} else if (answer === InstallManually) {
|
||||
viewContribution
|
||||
.openView({ reveal: true })
|
||||
.then((widget) => widget.refresh(viewSearchOptions));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async executeTasks(
|
||||
message: string,
|
||||
tasks: Task<ArduinoComponent>[]
|
||||
): Promise<void> {
|
||||
if (tasks.length) {
|
||||
return ExecuteWithProgress.withProgress(
|
||||
message,
|
||||
this.messageService,
|
||||
async (progress) => {
|
||||
try {
|
||||
const total = tasks.length;
|
||||
let count = 0;
|
||||
for (const { run, item } of tasks) {
|
||||
try {
|
||||
await run(); // runs update sequentially. // TODO: is parallel update desired?
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
this.messageService.error(
|
||||
`Failed to update ${item.name}. ${err}`
|
||||
);
|
||||
} finally {
|
||||
progress.report({ work: { total, done: ++count } });
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
progress.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private createInstallTask<T extends ArduinoComponent>(
|
||||
item: T,
|
||||
installable: Installable<T>
|
||||
): Task<T> {
|
||||
const latestVersion = item.availableVersions[0];
|
||||
return {
|
||||
item,
|
||||
run: () =>
|
||||
Installable.installWithProgress({
|
||||
installable,
|
||||
item,
|
||||
version: latestVersion,
|
||||
messageService: this.messageService,
|
||||
responseService: this.responseService,
|
||||
keepOutput: true,
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
export namespace CheckForUpdates {
|
||||
export namespace Commands {
|
||||
export const CHECK_FOR_UPDATES: Command = Command.toLocalizedCommand(
|
||||
{
|
||||
id: 'arduino-check-for-updates',
|
||||
label: 'Check for Arduino Updates',
|
||||
category: 'Arduino',
|
||||
},
|
||||
'arduino/checkForUpdates/checkForUpdates'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import type { EditorOpenerOptions } from '@theia/editor/lib/browser/editor-manager';
|
||||
import { Later } from '../../common/nls';
|
||||
import { SketchesError } from '../../common/protocol';
|
||||
import {
|
||||
Command,
|
||||
@@ -41,20 +42,18 @@ export class OpenSketchFiles extends SketchContribution {
|
||||
sketch.name
|
||||
);
|
||||
const yes = nls.localize('vscode/extensionsUtils/yes', 'Yes');
|
||||
this.messageService
|
||||
.info(message, nls.localize('arduino/common/later', 'Later'), yes)
|
||||
.then(async (answer) => {
|
||||
if (answer === yes) {
|
||||
this.commandService.executeCommand(
|
||||
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
|
||||
{
|
||||
execOnlyIfTemp: false,
|
||||
openAfterMove: true,
|
||||
wipeOriginal: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
this.messageService.info(message, Later, yes).then((answer) => {
|
||||
if (answer === yes) {
|
||||
this.commandService.executeCommand(
|
||||
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
|
||||
{
|
||||
execOnlyIfTemp: false,
|
||||
openAfterMove: true,
|
||||
wipeOriginal: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
if (SketchesError.NotFound.is(err)) {
|
||||
|
||||
@@ -54,8 +54,8 @@ export class IDEUpdaterCommands implements CommandContribution {
|
||||
export namespace IDEUpdaterCommands {
|
||||
export const CHECK_FOR_UPDATES: Command = Command.toLocalizedCommand(
|
||||
{
|
||||
id: 'arduino-ide-check-for-updates',
|
||||
label: 'Check for Arduino IDE updates',
|
||||
id: 'arduino-check-for-ide-updates',
|
||||
label: 'Check for Arduino IDE Updates',
|
||||
category: 'Arduino',
|
||||
},
|
||||
'arduino/ide-updater/checkForUpdates'
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
import { injectable, postConstruct, inject } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
injectable,
|
||||
postConstruct,
|
||||
inject,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { addEventListener } from '@theia/core/lib/browser/widgets/widget';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { AbstractDialog } from '../theia/dialogs/dialogs';
|
||||
import {
|
||||
LibraryPackage,
|
||||
LibrarySearch,
|
||||
LibraryService,
|
||||
} from '../../common/protocol/library-service';
|
||||
import { ListWidget } 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';
|
||||
import { LibraryFilterRenderer } from '../widgets/component-list/filter-renderer';
|
||||
|
||||
@injectable()
|
||||
export class LibraryListWidget extends ListWidget<LibraryPackage> {
|
||||
export class LibraryListWidget extends ListWidget<
|
||||
LibraryPackage,
|
||||
LibrarySearch
|
||||
> {
|
||||
static WIDGET_ID = 'library-list-widget';
|
||||
static WIDGET_LABEL = nls.localize(
|
||||
'arduino/library/title',
|
||||
@@ -21,9 +30,9 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
|
||||
);
|
||||
|
||||
constructor(
|
||||
@inject(LibraryService) protected service: LibraryService,
|
||||
@inject(ListItemRenderer)
|
||||
protected itemRenderer: ListItemRenderer<LibraryPackage>
|
||||
@inject(LibraryService) private service: LibraryService,
|
||||
@inject(ListItemRenderer) itemRenderer: ListItemRenderer<LibraryPackage>,
|
||||
@inject(LibraryFilterRenderer) filterRenderer: LibraryFilterRenderer
|
||||
) {
|
||||
super({
|
||||
id: LibraryListWidget.WIDGET_ID,
|
||||
@@ -34,6 +43,8 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
|
||||
itemLabel: (item: LibraryPackage) => item.name,
|
||||
itemDeprecated: (item: LibraryPackage) => item.deprecated,
|
||||
itemRenderer,
|
||||
filterRenderer,
|
||||
defaultSearchOptions: { query: '', type: 'All', topic: 'All' },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -41,7 +52,9 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
|
||||
protected override init(): void {
|
||||
super.init();
|
||||
this.toDispose.pushAll([
|
||||
this.notificationCenter.onLibraryDidInstall(() => this.refresh(undefined)),
|
||||
this.notificationCenter.onLibraryDidInstall(() =>
|
||||
this.refresh(undefined)
|
||||
),
|
||||
this.notificationCenter.onLibraryDidUninstall(() =>
|
||||
this.refresh(undefined)
|
||||
),
|
||||
|
||||
@@ -8,13 +8,35 @@
|
||||
}
|
||||
|
||||
.arduino-list-widget .search-bar {
|
||||
margin: 0px 10px 10px 15px;
|
||||
margin: 0px 10px 5px 15px;
|
||||
}
|
||||
|
||||
.arduino-list-widget .search-bar:focus {
|
||||
border-color: var(--theia-focusBorder);
|
||||
}
|
||||
|
||||
.arduino-list-widget .filter-bar {
|
||||
margin: 0px 10px 5px 15px;
|
||||
}
|
||||
|
||||
.arduino-list-widget .filter-bar > * {
|
||||
padding: 5px 5px 0px 0px;
|
||||
}
|
||||
|
||||
.arduino-list-widget .filter-bar .filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.arduino-list-widget .filter-bar .filter > select {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.arduino-list-widget .filter-bar .filter-label {
|
||||
display: flex;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.filterable-list-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -23,33 +45,24 @@
|
||||
}
|
||||
|
||||
.filterable-list-container .items-container {
|
||||
height: 100%; /* This has to be propagated down from the widget. */
|
||||
position: relative; /* To fix the `top` of the vertical toolbar. */
|
||||
padding-bottom: calc(2 * var(--theia-statusBar-height));
|
||||
}
|
||||
|
||||
.filterable-list-container .items-container > div:nth-child(odd) {
|
||||
.filterable-list-container .items-container > div > div:nth-child(odd) {
|
||||
background-color: var(--theia-sideBar-background);
|
||||
filter: contrast(105%);
|
||||
}
|
||||
|
||||
.filterable-list-container .items-container > div:nth-child(even) {
|
||||
.filterable-list-container .items-container > div > div:nth-child(even) {
|
||||
background-color: var(--theia-sideBar-background);
|
||||
filter: contrast(95%);
|
||||
}
|
||||
|
||||
.filterable-list-container .items-container > div:hover {
|
||||
.filterable-list-container .items-container > div > div:hover {
|
||||
background-color: var(--theia-sideBar-background);
|
||||
filter: contrast(90%);
|
||||
}
|
||||
|
||||
/* Perfect scrollbar does not like if we explicitly set the `background-color` of the contained elements.
|
||||
See above: `.filterable-list-container .items-container > div:nth-child(odd|event)`.
|
||||
We have to increase `z-index` of the scroll-bar thumb. Otherwise, the thumb is not visible.
|
||||
https://github.com/arduino/arduino-pro-ide/issues/82 */
|
||||
.arduino-list-widget .filterable-list-container .items-container .ps__rail-y {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.component-list-item {
|
||||
padding: 10px 10px 10px 15px;
|
||||
font-size: var(--theia-ui-font-size1);
|
||||
@@ -113,7 +126,7 @@ https://github.com/arduino/arduino-pro-ide/issues/82 */
|
||||
|
||||
.component-list-item[min-width~="170px"] .footer {
|
||||
padding: 5px 5px 0px 0px;
|
||||
min-height: 30px;
|
||||
min-height: 35px;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
@@ -122,10 +135,6 @@ https://github.com/arduino/arduino-pro-ide/issues/82 */
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.component-list-item .footer > * {
|
||||
display: none
|
||||
}
|
||||
|
||||
.component-list-item:hover .footer > * {
|
||||
display: inline-block;
|
||||
margin: 5px 0px 0px 10px;
|
||||
@@ -155,4 +164,4 @@ https://github.com/arduino/arduino-pro-ide/issues/82 */
|
||||
|
||||
.hc-black.hc-theia.theia-hc .component-list-item .header .installed:before {
|
||||
border: 1px solid var(--theia-button-border);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { PreferencesEditorWidget as TheiaPreferencesEditorWidget } from '@theia/preferences/lib/browser/views/preference-editor-widget';
|
||||
|
||||
@injectable()
|
||||
export class PreferencesEditorWidget extends TheiaPreferencesEditorWidget {
|
||||
protected override resetScroll(
|
||||
nodeIDToScrollTo?: string,
|
||||
filterWasCleared = false
|
||||
): void {
|
||||
if (this.scrollBar) {
|
||||
// Absent on widget creation
|
||||
this.doResetScroll(nodeIDToScrollTo, filterWasCleared);
|
||||
} else {
|
||||
// NOOP
|
||||
// Unlike Theia, IDE2 does not start multiple tasks to check if the scrollbar is ready to reset it.
|
||||
// If the "scroll reset" request arrived before the existence of the scrollbar, what to reset?
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,38 @@ export class ComponentListItem<
|
||||
)[0];
|
||||
this.state = {
|
||||
selectedVersion: version,
|
||||
focus: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected async install(item: T): Promise<void> {
|
||||
override componentDidUpdate(
|
||||
prevProps: ComponentListItem.Props<T>,
|
||||
prevState: ComponentListItem.State
|
||||
): void {
|
||||
if (this.state.focus !== prevState.focus) {
|
||||
this.props.onFocusDidChange();
|
||||
}
|
||||
}
|
||||
|
||||
override render(): React.ReactNode {
|
||||
const { item, itemRenderer } = this.props;
|
||||
return (
|
||||
<div
|
||||
onMouseEnter={() => this.setState({ focus: true })}
|
||||
onMouseLeave={() => this.setState({ focus: false })}
|
||||
>
|
||||
{itemRenderer.renderItem(
|
||||
Object.assign(this.state, { item }),
|
||||
this.install.bind(this),
|
||||
this.uninstall.bind(this),
|
||||
this.onVersionChange.bind(this)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private async install(item: T): Promise<void> {
|
||||
const toInstall = this.state.selectedVersion;
|
||||
const version = this.props.item.availableVersions.filter(
|
||||
(version) => version !== this.state.selectedVersion
|
||||
@@ -35,23 +62,13 @@ export class ComponentListItem<
|
||||
}
|
||||
}
|
||||
|
||||
protected async uninstall(item: T): Promise<void> {
|
||||
private async uninstall(item: T): Promise<void> {
|
||||
await this.props.uninstall(item);
|
||||
}
|
||||
|
||||
protected onVersionChange(version: Installable.Version) {
|
||||
private onVersionChange(version: Installable.Version): void {
|
||||
this.setState({ selectedVersion: version });
|
||||
}
|
||||
|
||||
override render(): React.ReactNode {
|
||||
const { item, itemRenderer } = this.props;
|
||||
return itemRenderer.renderItem(
|
||||
Object.assign(this.state, { item }),
|
||||
this.install.bind(this),
|
||||
this.uninstall.bind(this),
|
||||
this.onVersionChange.bind(this)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export namespace ComponentListItem {
|
||||
@@ -60,9 +77,11 @@ export namespace ComponentListItem {
|
||||
readonly install: (item: T, version?: Installable.Version) => Promise<void>;
|
||||
readonly uninstall: (item: T) => Promise<void>;
|
||||
readonly itemRenderer: ListItemRenderer<T>;
|
||||
readonly onFocusDidChange: () => void;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
selectedVersion?: Installable.Version;
|
||||
focus: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,141 @@
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import { Installable } from '../../../common/protocol/installable';
|
||||
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
|
||||
import {
|
||||
CellMeasurer,
|
||||
CellMeasurerCache,
|
||||
} from 'react-virtualized/dist/commonjs/CellMeasurer';
|
||||
import type {
|
||||
ListRowProps,
|
||||
ListRowRenderer,
|
||||
} from 'react-virtualized/dist/commonjs/List';
|
||||
import List from 'react-virtualized/dist/commonjs/List';
|
||||
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
|
||||
import { Installable } from '../../../common/protocol/installable';
|
||||
import { ComponentListItem } from './component-list-item';
|
||||
import { ListItemRenderer } from './list-item-renderer';
|
||||
|
||||
function sameAs<T>(left: T[], right: T[], key: (item: T) => string): boolean {
|
||||
if (left === right) {
|
||||
return true;
|
||||
}
|
||||
const leftLength = left.length;
|
||||
if (leftLength !== right.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < leftLength; i++) {
|
||||
const leftKey = key(left[i]);
|
||||
const rightKey = key(right[i]);
|
||||
if (leftKey !== rightKey) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export class ComponentList<T extends ArduinoComponent> extends React.Component<
|
||||
ComponentList.Props<T>
|
||||
> {
|
||||
protected container?: HTMLElement;
|
||||
private readonly cache: CellMeasurerCache;
|
||||
private resizeAllFlag: boolean;
|
||||
private list: List | undefined;
|
||||
private mostRecentWidth: number | undefined;
|
||||
|
||||
constructor(props: ComponentList.Props<T>) {
|
||||
super(props);
|
||||
this.cache = new CellMeasurerCache({
|
||||
defaultHeight: 300,
|
||||
fixedWidth: true,
|
||||
});
|
||||
}
|
||||
|
||||
override render(): React.ReactNode {
|
||||
return (
|
||||
<div className={'items-container'} ref={this.setRef}>
|
||||
{this.props.items.map((item) => this.createItem(item))}
|
||||
</div>
|
||||
<AutoSizer>
|
||||
{({ width, height }) => {
|
||||
if (this.mostRecentWidth && this.mostRecentWidth !== width) {
|
||||
this.resizeAllFlag = true;
|
||||
setTimeout(() => this.clearAll(), 0);
|
||||
}
|
||||
this.mostRecentWidth = width;
|
||||
return (
|
||||
<List
|
||||
className={'items-container'}
|
||||
rowRenderer={this.createItem}
|
||||
height={height}
|
||||
width={width}
|
||||
rowCount={this.props.items.length}
|
||||
rowHeight={this.cache.rowHeight}
|
||||
deferredMeasurementCache={this.cache}
|
||||
ref={this.setListRef}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</AutoSizer>
|
||||
);
|
||||
}
|
||||
|
||||
override componentDidMount(): void {
|
||||
if (this.container && this.props.resolveContainer) {
|
||||
this.props.resolveContainer(this.container);
|
||||
override componentDidUpdate(prevProps: ComponentList.Props<T>): void {
|
||||
if (
|
||||
this.resizeAllFlag ||
|
||||
!sameAs(this.props.items, prevProps.items, this.props.itemLabel)
|
||||
) {
|
||||
this.clearAll(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected setRef = (element: HTMLElement | null) => {
|
||||
this.container = element || undefined;
|
||||
private setListRef = (ref: List | null): void => {
|
||||
this.list = ref || undefined;
|
||||
};
|
||||
|
||||
protected createItem(item: T): React.ReactNode {
|
||||
return (
|
||||
<ComponentListItem<T>
|
||||
key={this.props.itemLabel(item)}
|
||||
item={item}
|
||||
itemRenderer={this.props.itemRenderer}
|
||||
install={this.props.install}
|
||||
uninstall={this.props.uninstall}
|
||||
/>
|
||||
);
|
||||
private clearAll(scrollToTop = false): void {
|
||||
this.resizeAllFlag = false;
|
||||
this.cache.clearAll();
|
||||
if (this.list) {
|
||||
this.list.recomputeRowHeights();
|
||||
if (scrollToTop) {
|
||||
this.list.scrollToPosition(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private clear(index: number): void {
|
||||
this.cache.clear(index, 0);
|
||||
this.list?.recomputeRowHeights(index);
|
||||
// Update the last item if the if the one before was updated
|
||||
if (index === this.props.items.length - 2) {
|
||||
this.cache.clear(index + 1, 0);
|
||||
this.list?.recomputeRowHeights(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private createItem: ListRowRenderer = ({
|
||||
index,
|
||||
parent,
|
||||
key,
|
||||
style,
|
||||
}: ListRowProps): React.ReactNode => {
|
||||
const item = this.props.items[index];
|
||||
return (
|
||||
<CellMeasurer
|
||||
cache={this.cache}
|
||||
columnIndex={0}
|
||||
key={key}
|
||||
rowIndex={index}
|
||||
parent={parent}
|
||||
>
|
||||
<div style={style}>
|
||||
<ComponentListItem<T>
|
||||
key={this.props.itemLabel(item)}
|
||||
item={item}
|
||||
itemRenderer={this.props.itemRenderer}
|
||||
install={this.props.install}
|
||||
uninstall={this.props.uninstall}
|
||||
onFocusDidChange={() => this.clear(index)}
|
||||
/>
|
||||
</div>
|
||||
</CellMeasurer>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export namespace ComponentList {
|
||||
@@ -48,6 +146,5 @@ export namespace ComponentList {
|
||||
readonly itemRenderer: ListItemRenderer<T>;
|
||||
readonly install: (item: T, version?: Installable.Version) => Promise<void>;
|
||||
readonly uninstall: (item: T) => Promise<void>;
|
||||
readonly resolveContainer: (element: HTMLElement) => void;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import {
|
||||
BoardSearch,
|
||||
LibrarySearch,
|
||||
Searchable,
|
||||
} from '../../../common/protocol';
|
||||
|
||||
@injectable()
|
||||
export abstract class FilterRenderer<S extends Searchable.Options> {
|
||||
render(
|
||||
options: S,
|
||||
handlePropChange: (prop: keyof S, value: S[keyof S]) => void
|
||||
): React.ReactNode {
|
||||
const props = this.props();
|
||||
return (
|
||||
<div className="filter-bar">
|
||||
{Object.entries(options)
|
||||
.filter(([prop]) => props.includes(prop as keyof S))
|
||||
.map(([prop, value]) => (
|
||||
<div key={prop} className="filter">
|
||||
<div className="filter-label">
|
||||
{`${this.propertyLabel(prop as keyof S)}:`}
|
||||
</div>
|
||||
<select
|
||||
className="theia-select"
|
||||
value={value}
|
||||
onChange={(event) =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
handlePropChange(prop as keyof S, event.target.value as any)
|
||||
}
|
||||
>
|
||||
{this.options(prop as keyof S).map((key) => (
|
||||
<option key={key} value={key}>
|
||||
{this.valueLabel(prop as keyof S, key)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
protected abstract props(): (keyof S)[];
|
||||
protected abstract options(prop: keyof S): string[];
|
||||
protected abstract valueLabel(prop: keyof S, key: string): string;
|
||||
protected abstract propertyLabel(prop: keyof S): string;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class BoardsFilterRenderer extends FilterRenderer<BoardSearch> {
|
||||
protected props(): (keyof BoardSearch)[] {
|
||||
return ['type'];
|
||||
}
|
||||
protected options(prop: keyof BoardSearch): string[] {
|
||||
switch (prop) {
|
||||
case 'type':
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return BoardSearch.TypeLiterals as any;
|
||||
default:
|
||||
throw new Error(`Unexpected prop: ${prop}`);
|
||||
}
|
||||
}
|
||||
protected valueLabel(prop: keyof BoardSearch, key: string): string {
|
||||
switch (prop) {
|
||||
case 'type':
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (BoardSearch.TypeLabels as any)[key];
|
||||
default:
|
||||
throw new Error(`Unexpected key: ${prop}`);
|
||||
}
|
||||
}
|
||||
protected propertyLabel(prop: keyof BoardSearch): string {
|
||||
switch (prop) {
|
||||
case 'type':
|
||||
return BoardSearch.PropertyLabels[prop];
|
||||
default:
|
||||
throw new Error(`Unexpected key: ${prop}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class LibraryFilterRenderer extends FilterRenderer<LibrarySearch> {
|
||||
protected props(): (keyof LibrarySearch)[] {
|
||||
return ['type', 'topic'];
|
||||
}
|
||||
protected options(prop: keyof LibrarySearch): string[] {
|
||||
switch (prop) {
|
||||
case 'type':
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return LibrarySearch.TypeLiterals as any;
|
||||
case 'topic':
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return LibrarySearch.TopicLiterals as any;
|
||||
default:
|
||||
throw new Error(`Unexpected prop: ${prop}`);
|
||||
}
|
||||
}
|
||||
protected propertyLabel(prop: keyof LibrarySearch): string {
|
||||
switch (prop) {
|
||||
case 'type':
|
||||
case 'topic':
|
||||
return LibrarySearch.PropertyLabels[prop];
|
||||
default:
|
||||
throw new Error(`Unexpected key: ${prop}`);
|
||||
}
|
||||
}
|
||||
protected valueLabel(prop: keyof LibrarySearch, key: string): string {
|
||||
switch (prop) {
|
||||
case 'type':
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (LibrarySearch.TypeLabels as any)[key] as any;
|
||||
case 'topic':
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (LibrarySearch.TopicLabels as any)[key] as any;
|
||||
default:
|
||||
throw new Error(`Unexpected prop: ${prop}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,30 @@ import { ComponentList } from './component-list';
|
||||
import { ListItemRenderer } from './list-item-renderer';
|
||||
import { ResponseServiceClient } from '../../../common/protocol';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { FilterRenderer } from './filter-renderer';
|
||||
|
||||
export class FilterableListContainer<
|
||||
T extends ArduinoComponent
|
||||
T extends ArduinoComponent,
|
||||
S extends Searchable.Options
|
||||
> extends React.Component<
|
||||
FilterableListContainer.Props<T>,
|
||||
FilterableListContainer.State<T>
|
||||
FilterableListContainer.Props<T, S>,
|
||||
FilterableListContainer.State<T, S>
|
||||
> {
|
||||
constructor(props: Readonly<FilterableListContainer.Props<T>>) {
|
||||
constructor(props: Readonly<FilterableListContainer.Props<T, S>>) {
|
||||
super(props);
|
||||
this.state = {
|
||||
filterText: '',
|
||||
searchOptions: props.defaultSearchOptions,
|
||||
items: [],
|
||||
};
|
||||
}
|
||||
|
||||
override componentDidMount(): void {
|
||||
this.search = debounce(this.search, 500);
|
||||
this.handleFilterTextChange('');
|
||||
this.props.filterTextChangeEvent(this.handleFilterTextChange.bind(this));
|
||||
this.search(this.state.searchOptions);
|
||||
this.props.searchOptionsDidChange((newSearchOptions) => {
|
||||
const { searchOptions } = this.state;
|
||||
this.setSearchOptionsAndUpdate({ ...searchOptions, ...newSearchOptions });
|
||||
});
|
||||
}
|
||||
|
||||
override componentDidUpdate(): void {
|
||||
@@ -44,30 +49,38 @@ export class FilterableListContainer<
|
||||
override render(): React.ReactNode {
|
||||
return (
|
||||
<div className={'filterable-list-container'}>
|
||||
{this.renderSearchFilter()}
|
||||
{this.renderSearchBar()}
|
||||
{this.renderSearchFilter()}
|
||||
{this.renderComponentList()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
protected renderSearchFilter(): React.ReactNode {
|
||||
return undefined;
|
||||
return (
|
||||
<>
|
||||
{this.props.filterRenderer.render(
|
||||
this.state.searchOptions,
|
||||
this.handlePropChange.bind(this)
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
protected renderSearchBar(): React.ReactNode {
|
||||
return (
|
||||
<SearchBar
|
||||
resolveFocus={this.props.resolveFocus}
|
||||
filterText={this.state.filterText}
|
||||
onFilterTextChanged={this.handleFilterTextChange}
|
||||
filterText={this.state.searchOptions.query ?? ''}
|
||||
onFilterTextChanged={(query) =>
|
||||
this.handlePropChange('query', query as S['query'])
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
protected renderComponentList(): React.ReactNode {
|
||||
const { itemLabel, itemDeprecated, resolveContainer, itemRenderer } =
|
||||
this.props;
|
||||
const { itemLabel, itemDeprecated, itemRenderer } = this.props;
|
||||
return (
|
||||
<ComponentList<T>
|
||||
items={this.state.items}
|
||||
@@ -76,22 +89,26 @@ export class FilterableListContainer<
|
||||
itemRenderer={itemRenderer}
|
||||
install={this.install.bind(this)}
|
||||
uninstall={this.uninstall.bind(this)}
|
||||
resolveContainer={resolveContainer}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
protected handleFilterTextChange = (
|
||||
filterText: string = this.state.filterText
|
||||
) => {
|
||||
this.setState({ filterText });
|
||||
this.search(filterText);
|
||||
protected handlePropChange = (prop: keyof S, value: S[keyof S]): void => {
|
||||
const searchOptions = {
|
||||
...this.state.searchOptions,
|
||||
[prop]: value,
|
||||
};
|
||||
this.setSearchOptionsAndUpdate(searchOptions);
|
||||
};
|
||||
|
||||
protected search(query: string): void {
|
||||
private setSearchOptionsAndUpdate(searchOptions: S) {
|
||||
this.setState({ searchOptions }, () => this.search(searchOptions));
|
||||
}
|
||||
|
||||
protected search(searchOptions: S): void {
|
||||
const { searchable } = this.props;
|
||||
searchable
|
||||
.search({ query: query.trim() })
|
||||
.search(searchOptions)
|
||||
.then((items) => this.setState({ items: this.sort(items) }));
|
||||
}
|
||||
|
||||
@@ -119,7 +136,7 @@ export class FilterableListContainer<
|
||||
` ${item.name}:${version}`,
|
||||
run: ({ progressId }) => install({ item, progressId, version }),
|
||||
});
|
||||
const items = await searchable.search({ query: this.state.filterText });
|
||||
const items = await searchable.search(this.state.searchOptions);
|
||||
this.setState({ items: this.sort(items) });
|
||||
}
|
||||
|
||||
@@ -147,21 +164,25 @@ export class FilterableListContainer<
|
||||
}`,
|
||||
run: ({ progressId }) => uninstall({ item, progressId }),
|
||||
});
|
||||
const items = await searchable.search({ query: this.state.filterText });
|
||||
const items = await searchable.search(this.state.searchOptions);
|
||||
this.setState({ items: this.sort(items) });
|
||||
}
|
||||
}
|
||||
|
||||
export namespace FilterableListContainer {
|
||||
export interface Props<T extends ArduinoComponent> {
|
||||
readonly container: ListWidget<T>;
|
||||
readonly searchable: Searchable<T>;
|
||||
export interface Props<
|
||||
T extends ArduinoComponent,
|
||||
S extends Searchable.Options
|
||||
> {
|
||||
readonly defaultSearchOptions: S;
|
||||
readonly container: ListWidget<T, S>;
|
||||
readonly searchable: Searchable<T, S>;
|
||||
readonly itemLabel: (item: T) => string;
|
||||
readonly itemDeprecated: (item: T) => boolean;
|
||||
readonly itemRenderer: ListItemRenderer<T>;
|
||||
readonly resolveContainer: (element: HTMLElement) => void;
|
||||
readonly filterRenderer: FilterRenderer<S>;
|
||||
readonly resolveFocus: (element: HTMLElement | undefined) => void;
|
||||
readonly filterTextChangeEvent: Event<string | undefined>;
|
||||
readonly searchOptionsDidChange: Event<Partial<S> | undefined>;
|
||||
readonly messageService: MessageService;
|
||||
readonly responseService: ResponseServiceClient;
|
||||
readonly install: ({
|
||||
@@ -183,8 +204,8 @@ export namespace FilterableListContainer {
|
||||
readonly commandService: CommandService;
|
||||
}
|
||||
|
||||
export interface State<T> {
|
||||
filterText: string;
|
||||
export interface State<T, S extends Searchable.Options> {
|
||||
searchOptions: S;
|
||||
items: T[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export class ListItemRenderer<T extends ArduinoComponent> {
|
||||
|
||||
protected onMoreInfoClick = (
|
||||
event: React.SyntheticEvent<HTMLAnchorElement, Event>
|
||||
) => {
|
||||
): void => {
|
||||
const { target } = event.nativeEvent;
|
||||
if (target instanceof HTMLAnchorElement) {
|
||||
this.windowService.openNewWindow(target.href, { external: true });
|
||||
@@ -28,7 +28,7 @@ export class ListItemRenderer<T extends ArduinoComponent> {
|
||||
uninstall: (item: T) => Promise<void>,
|
||||
onVersionChange: (version: Installable.Version) => void
|
||||
): React.ReactNode {
|
||||
const { item } = input;
|
||||
const { item, focus } = input;
|
||||
let nameAndAuthor: JSX.Element;
|
||||
if (item.name && item.author) {
|
||||
const name = <span className="name">{item.name}</span>;
|
||||
@@ -120,10 +120,12 @@ export class ListItemRenderer<T extends ArduinoComponent> {
|
||||
{description}
|
||||
</div>
|
||||
<div className="info">{moreInfo}</div>
|
||||
<div className="footer">
|
||||
{versions}
|
||||
{installButton}
|
||||
</div>
|
||||
{focus && (
|
||||
<div className="footer">
|
||||
{versions}
|
||||
{installButton}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,20 @@ import { FrontendApplicationContribution } from '@theia/core/lib/browser/fronten
|
||||
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
||||
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
|
||||
import { ListWidget } from './list-widget';
|
||||
import { Searchable } from '../../../common/protocol';
|
||||
|
||||
@injectable()
|
||||
export abstract class ListWidgetFrontendContribution<T extends ArduinoComponent>
|
||||
extends AbstractViewContribution<ListWidget<T>>
|
||||
export abstract class ListWidgetFrontendContribution<
|
||||
T extends ArduinoComponent,
|
||||
S extends Searchable.Options
|
||||
>
|
||||
extends AbstractViewContribution<ListWidget<T, S>>
|
||||
implements FrontendApplicationContribution
|
||||
{
|
||||
async initializeLayout(): Promise<void> {}
|
||||
async initializeLayout(): Promise<void> {
|
||||
// TS requires at least one method from `FrontendApplicationContribution`.
|
||||
// Expected to be empty.
|
||||
}
|
||||
|
||||
override registerMenus(): void {
|
||||
// NOOP
|
||||
|
||||
@@ -6,9 +6,7 @@ import {
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||
import { CommandService } from '@theia/core/lib/common/command';
|
||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
@@ -21,10 +19,12 @@ import {
|
||||
import { FilterableListContainer } from './filterable-list-container';
|
||||
import { ListItemRenderer } from './list-item-renderer';
|
||||
import { NotificationCenter } from '../../notification-center';
|
||||
import { FilterRenderer } from './filter-renderer';
|
||||
|
||||
@injectable()
|
||||
export abstract class ListWidget<
|
||||
T extends ArduinoComponent
|
||||
T extends ArduinoComponent,
|
||||
S extends Searchable.Options
|
||||
> extends ReactWidget {
|
||||
@inject(MessageService)
|
||||
protected readonly messageService: MessageService;
|
||||
@@ -42,9 +42,8 @@ export abstract class ListWidget<
|
||||
* Do not touch or use it. It is for setting the focus on the `input` after the widget activation.
|
||||
*/
|
||||
protected focusNode: HTMLElement | undefined;
|
||||
protected readonly deferredContainer = new Deferred<HTMLElement>();
|
||||
protected readonly filterTextChangeEmitter = new Emitter<
|
||||
string | undefined
|
||||
protected readonly searchOptionsChangeEmitter = new Emitter<
|
||||
Partial<S> | undefined
|
||||
>();
|
||||
/**
|
||||
* Instead of running an `update` from the `postConstruct` `init` method,
|
||||
@@ -52,7 +51,7 @@ export abstract class ListWidget<
|
||||
*/
|
||||
protected firstActivate = true;
|
||||
|
||||
constructor(protected options: ListWidget.Options<T>) {
|
||||
constructor(protected options: ListWidget.Options<T, S>) {
|
||||
super();
|
||||
const { id, label, iconClass } = options;
|
||||
this.id = id;
|
||||
@@ -62,10 +61,8 @@ export abstract class ListWidget<
|
||||
this.title.closable = true;
|
||||
this.addClass('arduino-list-widget');
|
||||
this.node.tabIndex = 0; // To be able to set the focus on the widget.
|
||||
this.scrollOptions = {
|
||||
suppressScrollX: true,
|
||||
};
|
||||
this.toDispose.push(this.filterTextChangeEmitter);
|
||||
this.scrollOptions = undefined;
|
||||
this.toDispose.push(this.searchOptionsChangeEmitter);
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
@@ -77,10 +74,6 @@ export abstract class ListWidget<
|
||||
]);
|
||||
}
|
||||
|
||||
protected override getScrollContainer(): MaybePromise<HTMLElement> {
|
||||
return this.deferredContainer.promise;
|
||||
}
|
||||
|
||||
protected override onAfterShow(message: Message): void {
|
||||
this.maybeUpdateOnFirstRender();
|
||||
super.onAfterShow(message);
|
||||
@@ -109,7 +102,7 @@ export abstract class ListWidget<
|
||||
this.updateScrollBar();
|
||||
}
|
||||
|
||||
protected onFocusResolved = (element: HTMLElement | undefined) => {
|
||||
protected onFocusResolved = (element: HTMLElement | undefined): void => {
|
||||
this.focusNode = element;
|
||||
};
|
||||
|
||||
@@ -137,9 +130,9 @@ export abstract class ListWidget<
|
||||
|
||||
render(): React.ReactNode {
|
||||
return (
|
||||
<FilterableListContainer<T>
|
||||
<FilterableListContainer<T, S>
|
||||
defaultSearchOptions={this.options.defaultSearchOptions}
|
||||
container={this}
|
||||
resolveContainer={this.deferredContainer.resolve}
|
||||
resolveFocus={this.onFocusResolved}
|
||||
searchable={this.options.searchable}
|
||||
install={this.install.bind(this)}
|
||||
@@ -147,7 +140,8 @@ export abstract class ListWidget<
|
||||
itemLabel={this.options.itemLabel}
|
||||
itemDeprecated={this.options.itemDeprecated}
|
||||
itemRenderer={this.options.itemRenderer}
|
||||
filterTextChangeEvent={this.filterTextChangeEmitter.event}
|
||||
filterRenderer={this.options.filterRenderer}
|
||||
searchOptionsDidChange={this.searchOptionsChangeEmitter.event}
|
||||
messageService={this.messageService}
|
||||
commandService={this.commandService}
|
||||
responseService={this.responseService}
|
||||
@@ -159,10 +153,8 @@ export abstract class ListWidget<
|
||||
* If `filterText` is defined, sets the filter text to the argument.
|
||||
* If it is `undefined`, updates the view state by re-running the search with the current `filterText` term.
|
||||
*/
|
||||
refresh(filterText: string | undefined): void {
|
||||
this.deferredContainer.promise.then(() =>
|
||||
this.filterTextChangeEmitter.fire(filterText)
|
||||
);
|
||||
refresh(searchOptions: Partial<S> | undefined): void {
|
||||
this.searchOptionsChangeEmitter.fire(searchOptions);
|
||||
}
|
||||
|
||||
updateScrollBar(): void {
|
||||
@@ -173,14 +165,19 @@ export abstract class ListWidget<
|
||||
}
|
||||
|
||||
export namespace ListWidget {
|
||||
export interface Options<T extends ArduinoComponent> {
|
||||
export interface Options<
|
||||
T extends ArduinoComponent,
|
||||
S extends Searchable.Options
|
||||
> {
|
||||
readonly id: string;
|
||||
readonly label: string;
|
||||
readonly iconClass: string;
|
||||
readonly installable: Installable<T>;
|
||||
readonly searchable: Searchable<T>;
|
||||
readonly searchable: Searchable<T, S>;
|
||||
readonly itemLabel: (item: T) => string;
|
||||
readonly itemDeprecated: (item: T) => boolean;
|
||||
readonly itemRenderer: ListItemRenderer<T>;
|
||||
readonly filterRenderer: FilterRenderer<S>;
|
||||
readonly defaultSearchOptions: S;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
|
||||
export const Unknown = nls.localize('arduino/common/unknown', 'Unknown');
|
||||
export const Later = nls.localize('arduino/common/later', 'Later');
|
||||
export const Updatable = nls.localize('arduino/common/updateable', 'Updatable');
|
||||
export const All = nls.localize('arduino/common/all', 'All');
|
||||
export const Type = nls.localize('arduino/common/type', 'Type');
|
||||
export const Partner = nls.localize('arduino/common/partner', 'Partner');
|
||||
export const Contributed = nls.localize(
|
||||
'arduino/common/contributed',
|
||||
'Contributed'
|
||||
);
|
||||
export const Recommended = nls.localize(
|
||||
'arduino/common/recommended',
|
||||
'Recommended'
|
||||
);
|
||||
export const Retired = nls.localize('arduino/common/retired', 'Retired');
|
||||
export const InstallManually = nls.localize(
|
||||
'arduino/common/installManually',
|
||||
'Install Manually'
|
||||
);
|
||||
|
||||
@@ -7,11 +7,13 @@ export interface ArduinoComponent {
|
||||
readonly summary: string;
|
||||
readonly description: string;
|
||||
readonly moreInfoLink?: string;
|
||||
|
||||
readonly availableVersions: Installable.Version[];
|
||||
readonly installable: boolean;
|
||||
|
||||
readonly installedVersion?: Installable.Version;
|
||||
/**
|
||||
* This is the `Type` in IDE (1.x) UI.
|
||||
*/
|
||||
readonly types: string[];
|
||||
}
|
||||
export namespace ArduinoComponent {
|
||||
export function is(arg: any): arg is ArduinoComponent {
|
||||
|
||||
@@ -2,6 +2,8 @@ import { naturalCompare } from './../utils';
|
||||
import { Searchable } from './searchable';
|
||||
import { Installable } from './installable';
|
||||
import { ArduinoComponent } from './arduino-component';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { All, Contributed, Partner, Type, Updatable } from '../nls';
|
||||
|
||||
export type AvailablePorts = Record<string, [Port, Array<Board>]>;
|
||||
export namespace AvailablePorts {
|
||||
@@ -131,7 +133,7 @@ export const BoardsServicePath = '/services/boards-service';
|
||||
export const BoardsService = Symbol('BoardsService');
|
||||
export interface BoardsService
|
||||
extends Installable<BoardsPackage>,
|
||||
Searchable<BoardsPackage> {
|
||||
Searchable<BoardsPackage, BoardSearch> {
|
||||
getState(): Promise<AvailablePorts>;
|
||||
getBoardDetails(options: { fqbn: string }): Promise<BoardDetails | undefined>;
|
||||
getBoardPackage(options: { id: string }): Promise<BoardsPackage | undefined>;
|
||||
@@ -145,6 +147,40 @@ export interface BoardsService
|
||||
}): Promise<BoardUserField[]>;
|
||||
}
|
||||
|
||||
export interface BoardSearch extends Searchable.Options {
|
||||
readonly type?: BoardSearch.Type;
|
||||
}
|
||||
export namespace BoardSearch {
|
||||
export const TypeLiterals = [
|
||||
'All',
|
||||
'Updatable',
|
||||
'Arduino',
|
||||
'Contributed',
|
||||
'Arduino Certified',
|
||||
'Partner',
|
||||
'Arduino@Heart',
|
||||
] as const;
|
||||
export type Type = typeof TypeLiterals[number];
|
||||
export const TypeLabels: Record<Type, string> = {
|
||||
All: All,
|
||||
Updatable: Updatable,
|
||||
Arduino: 'Arduino',
|
||||
Contributed: Contributed,
|
||||
'Arduino Certified': nls.localize(
|
||||
'arduino/boardsType/arduinoCertified',
|
||||
'Arduino Certified'
|
||||
),
|
||||
Partner: Partner,
|
||||
'Arduino@Heart': 'Arduino@Heart',
|
||||
};
|
||||
export const PropertyLabels: Record<
|
||||
keyof Omit<BoardSearch, 'query'>,
|
||||
string
|
||||
> = {
|
||||
type: Type,
|
||||
};
|
||||
}
|
||||
|
||||
export interface Port {
|
||||
readonly address: string;
|
||||
readonly addressLabel: string;
|
||||
|
||||
@@ -36,6 +36,31 @@ export namespace Installable {
|
||||
};
|
||||
}
|
||||
|
||||
export const Installed = <T extends ArduinoComponent>({
|
||||
installedVersion,
|
||||
}: T): boolean => {
|
||||
return !!installedVersion;
|
||||
};
|
||||
|
||||
export const Updateable = <T extends ArduinoComponent>(item: T): boolean => {
|
||||
const { installedVersion } = item;
|
||||
if (!installedVersion) {
|
||||
return false;
|
||||
}
|
||||
const latestVersion = item.availableVersions[0];
|
||||
if (!latestVersion) {
|
||||
console.warn(
|
||||
`Installed version ${installedVersion} is available for ${item.name}, but no available versions were available. Skipping.`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
const result = Installable.Version.COMPARATOR(
|
||||
latestVersion,
|
||||
installedVersion
|
||||
);
|
||||
return result > 0;
|
||||
};
|
||||
|
||||
export async function installWithProgress<
|
||||
T extends ArduinoComponent
|
||||
>(options: {
|
||||
@@ -44,6 +69,7 @@ export namespace Installable {
|
||||
responseService: ResponseServiceClient;
|
||||
item: T;
|
||||
version: Installable.Version;
|
||||
keepOutput?: boolean;
|
||||
}): Promise<void> {
|
||||
const { item, version } = options;
|
||||
return ExecuteWithProgress.doWithProgress({
|
||||
@@ -65,6 +91,7 @@ export namespace Installable {
|
||||
messageService: MessageService;
|
||||
responseService: ResponseServiceClient;
|
||||
item: T;
|
||||
keepOutput?: boolean;
|
||||
}): Promise<void> {
|
||||
const { item } = options;
|
||||
return ExecuteWithProgress.doWithProgress({
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
import { Searchable } from './searchable';
|
||||
import { Installable } from './installable';
|
||||
import { ArduinoComponent } from './arduino-component';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import {
|
||||
All,
|
||||
Contributed,
|
||||
Partner,
|
||||
Recommended,
|
||||
Retired,
|
||||
Type,
|
||||
Updatable,
|
||||
} from '../nls';
|
||||
|
||||
export const LibraryServicePath = '/services/library-service';
|
||||
export const LibraryService = Symbol('LibraryService');
|
||||
export interface LibraryService
|
||||
extends Installable<LibraryPackage>,
|
||||
Searchable<LibraryPackage> {
|
||||
Searchable<LibraryPackage, LibrarySearch> {
|
||||
list(options: LibraryService.List.Options): Promise<LibraryPackage[]>;
|
||||
search(options: LibrarySearch): Promise<LibraryPackage[]>;
|
||||
/**
|
||||
* When `installDependencies` is not set, it is `true` by default. If you want to skip the installation of required dependencies, set it to `false`.
|
||||
*/
|
||||
@@ -38,6 +49,86 @@ export interface LibraryService
|
||||
}): Promise<LibraryDependency[]>;
|
||||
}
|
||||
|
||||
export interface LibrarySearch extends Searchable.Options {
|
||||
readonly type?: LibrarySearch.Type;
|
||||
readonly topic?: LibrarySearch.Topic;
|
||||
}
|
||||
export namespace LibrarySearch {
|
||||
export const TypeLiterals = [
|
||||
'All',
|
||||
'Updatable',
|
||||
'Installed',
|
||||
'Arduino',
|
||||
'Partner',
|
||||
'Recommended',
|
||||
'Contributed',
|
||||
'Retired',
|
||||
] as const;
|
||||
export type Type = typeof TypeLiterals[number];
|
||||
export const TypeLabels: Record<Type, string> = {
|
||||
All: All,
|
||||
Updatable: Updatable,
|
||||
Installed: nls.localize('arduino/libraryType/installed', 'Installed'),
|
||||
Arduino: 'Arduino',
|
||||
Partner: Partner,
|
||||
Recommended: Recommended,
|
||||
Contributed: Contributed,
|
||||
Retired: Retired,
|
||||
};
|
||||
export const TopicLiterals = [
|
||||
'All',
|
||||
'Communication',
|
||||
'Data Processing',
|
||||
'Data Storage',
|
||||
'Device Control',
|
||||
'Display',
|
||||
'Other',
|
||||
'Sensors',
|
||||
'Signal Input/Output',
|
||||
'Timing',
|
||||
'Uncategorized',
|
||||
] as const;
|
||||
export type Topic = typeof TopicLiterals[number];
|
||||
export const TopicLabels: Record<Topic, string> = {
|
||||
All: All,
|
||||
Communication: nls.localize(
|
||||
'arduino/libraryTopic/communication',
|
||||
'Communication'
|
||||
),
|
||||
'Data Processing': nls.localize(
|
||||
'arduino/libraryTopic/dataProcessing',
|
||||
'Data Processing'
|
||||
),
|
||||
'Data Storage': nls.localize(
|
||||
'arduino/libraryTopic/dataStorage',
|
||||
'Data Storage'
|
||||
),
|
||||
'Device Control': nls.localize(
|
||||
'arduino/libraryTopic/deviceControl',
|
||||
'Device Control'
|
||||
),
|
||||
Display: nls.localize('arduino/libraryTopic/display', 'Display'),
|
||||
Other: nls.localize('arduino/libraryTopic/other', 'Other'),
|
||||
Sensors: nls.localize('arduino/libraryTopic/sensors', 'Sensors'),
|
||||
'Signal Input/Output': nls.localize(
|
||||
'arduino/libraryTopic/signalInputOutput',
|
||||
'Signal Input/Output'
|
||||
),
|
||||
Timing: nls.localize('arduino/libraryTopic/timing', 'Timing'),
|
||||
Uncategorized: nls.localize(
|
||||
'arduino/libraryTopic/uncategorized',
|
||||
'Uncategorized'
|
||||
),
|
||||
};
|
||||
export const PropertyLabels: Record<
|
||||
keyof Omit<LibrarySearch, 'query'>,
|
||||
string
|
||||
> = {
|
||||
topic: nls.localize('arduino/librarySearchProperty/topic', 'Topic'),
|
||||
type: Type,
|
||||
};
|
||||
}
|
||||
|
||||
export namespace LibraryService {
|
||||
export namespace List {
|
||||
export interface Options {
|
||||
@@ -85,6 +176,10 @@ export interface LibraryPackage extends ArduinoComponent {
|
||||
readonly exampleUris: string[];
|
||||
readonly location: LibraryLocation;
|
||||
readonly installDirUri?: string;
|
||||
/**
|
||||
* This is the `Topic` in the IDE (1.x) UI.
|
||||
*/
|
||||
readonly category: string;
|
||||
}
|
||||
export namespace LibraryPackage {
|
||||
export function is(arg: any): arg is LibraryPackage {
|
||||
|
||||
@@ -39,7 +39,7 @@ export namespace ExecuteWithProgress {
|
||||
);
|
||||
}
|
||||
|
||||
async function withProgress<T>(
|
||||
export async function withProgress<T>(
|
||||
text: string,
|
||||
messageService: MessageService,
|
||||
cb: (progress: Progress, token: CancellationToken) => Promise<T>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface Searchable<T> {
|
||||
search(options: Searchable.Options): Promise<T[]>;
|
||||
export interface Searchable<T, O extends Searchable.Options> {
|
||||
search(options: O): Promise<T[]>;
|
||||
}
|
||||
export namespace Searchable {
|
||||
export interface Options {
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
AvailablePorts,
|
||||
BoardWithPackage,
|
||||
BoardUserField,
|
||||
BoardSearch,
|
||||
} from '../common/protocol';
|
||||
import {
|
||||
PlatformInstallRequest,
|
||||
@@ -264,7 +265,7 @@ export class BoardsServiceImpl
|
||||
}));
|
||||
}
|
||||
|
||||
async search(options: { query?: string }): Promise<BoardsPackage[]> {
|
||||
async search(options: BoardSearch): Promise<BoardsPackage[]> {
|
||||
const coreClient = await this.coreClient;
|
||||
const { client, instance } = coreClient;
|
||||
|
||||
@@ -310,6 +311,7 @@ export class BoardsServiceImpl
|
||||
.map((b) => b.getName())
|
||||
.join(', '),
|
||||
installable: true,
|
||||
types: platform.getTypeList(),
|
||||
deprecated: platform.getDeprecated(),
|
||||
summary: nls.localize(
|
||||
'arduino/component/boardsIncluded',
|
||||
@@ -380,7 +382,29 @@ export class BoardsServiceImpl
|
||||
}
|
||||
}
|
||||
|
||||
return [...packages.values()];
|
||||
const filter = this.typePredicate(options);
|
||||
return [...packages.values()].filter(filter);
|
||||
}
|
||||
|
||||
private typePredicate(
|
||||
options: BoardSearch
|
||||
): (item: BoardsPackage) => boolean {
|
||||
const { type } = options;
|
||||
if (!type || type === 'All') {
|
||||
return () => true;
|
||||
}
|
||||
switch (options.type) {
|
||||
case 'Updatable':
|
||||
return Installable.Updateable;
|
||||
case 'Arduino':
|
||||
case 'Partner':
|
||||
case 'Arduino@Heart':
|
||||
case 'Contributed':
|
||||
case 'Arduino Certified':
|
||||
return ({ types }: BoardsPackage) => !!types && types?.includes(type);
|
||||
default:
|
||||
throw new Error(`Unhandled type: ${options.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
async install(options: {
|
||||
|
||||
@@ -49,6 +49,7 @@ interface IArduinoCoreServiceService extends grpc.ServiceDefinition<grpc.Untyped
|
||||
platformList: IArduinoCoreServiceService_IPlatformList;
|
||||
libraryDownload: IArduinoCoreServiceService_ILibraryDownload;
|
||||
libraryInstall: IArduinoCoreServiceService_ILibraryInstall;
|
||||
libraryUpgrade: IArduinoCoreServiceService_ILibraryUpgrade;
|
||||
zipLibraryInstall: IArduinoCoreServiceService_IZipLibraryInstall;
|
||||
gitLibraryInstall: IArduinoCoreServiceService_IGitLibraryInstall;
|
||||
libraryUninstall: IArduinoCoreServiceService_ILibraryUninstall;
|
||||
@@ -348,6 +349,15 @@ interface IArduinoCoreServiceService_ILibraryInstall extends grpc.MethodDefiniti
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
|
||||
}
|
||||
interface IArduinoCoreServiceService_ILibraryUpgrade extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse> {
|
||||
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryUpgrade";
|
||||
requestStream: false;
|
||||
responseStream: true;
|
||||
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest>;
|
||||
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest>;
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse>;
|
||||
}
|
||||
interface IArduinoCoreServiceService_IZipLibraryInstall extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse> {
|
||||
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/ZipLibraryInstall";
|
||||
requestStream: false;
|
||||
@@ -465,6 +475,7 @@ export interface IArduinoCoreServiceServer {
|
||||
platformList: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, cc_arduino_cli_commands_v1_core_pb.PlatformListResponse>;
|
||||
libraryDownload: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
|
||||
libraryInstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
|
||||
libraryUpgrade: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse>;
|
||||
zipLibraryInstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
|
||||
gitLibraryInstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
|
||||
libraryUninstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse>;
|
||||
@@ -557,6 +568,8 @@ export interface IArduinoCoreServiceClient {
|
||||
libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
|
||||
libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
|
||||
libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
|
||||
libraryUpgrade(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse>;
|
||||
libraryUpgrade(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse>;
|
||||
zipLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
|
||||
zipLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
|
||||
gitLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
|
||||
@@ -663,6 +676,8 @@ export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCor
|
||||
public libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
|
||||
public libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
|
||||
public libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
|
||||
public libraryUpgrade(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse>;
|
||||
public libraryUpgrade(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse>;
|
||||
public zipLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
|
||||
public zipLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
|
||||
public gitLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
|
||||
|
||||
@@ -489,6 +489,28 @@ function deserialize_cc_arduino_cli_commands_v1_LibraryUpgradeAllResponse(buffer
|
||||
return cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_LibraryUpgradeRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.LibraryUpgradeRequest');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_LibraryUpgradeRequest(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_LibraryUpgradeResponse(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.LibraryUpgradeResponse');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_LibraryUpgradeResponse(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_ListProgrammersAvailableForUploadRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest');
|
||||
@@ -1325,6 +1347,18 @@ libraryInstall: {
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_LibraryInstallResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_LibraryInstallResponse,
|
||||
},
|
||||
// Upgrade a library to the newest version available.
|
||||
libraryUpgrade: {
|
||||
path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryUpgrade',
|
||||
requestStream: false,
|
||||
responseStream: true,
|
||||
requestType: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest,
|
||||
responseType: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse,
|
||||
requestSerialize: serialize_cc_arduino_cli_commands_v1_LibraryUpgradeRequest,
|
||||
requestDeserialize: deserialize_cc_arduino_cli_commands_v1_LibraryUpgradeRequest,
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_LibraryUpgradeResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_LibraryUpgradeResponse,
|
||||
},
|
||||
// Install a library from a Zip File
|
||||
zipLibraryInstall: {
|
||||
path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/ZipLibraryInstall',
|
||||
|
||||
@@ -159,6 +159,11 @@ export class Platform extends jspb.Message {
|
||||
getDeprecated(): boolean;
|
||||
setDeprecated(value: boolean): Platform;
|
||||
|
||||
clearTypeList(): void;
|
||||
getTypeList(): Array<string>;
|
||||
setTypeList(value: Array<string>): Platform;
|
||||
addType(value: string, index?: number): string;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Platform.AsObject;
|
||||
@@ -182,6 +187,7 @@ export namespace Platform {
|
||||
boardsList: Array<Board.AsObject>,
|
||||
manuallyInstalled: boolean,
|
||||
deprecated: boolean,
|
||||
typeList: Array<string>,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -987,7 +987,7 @@ proto.cc.arduino.cli.commands.v1.Programmer.prototype.setName = function(value)
|
||||
* @private {!Array<number>}
|
||||
* @const
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.Platform.repeatedFields_ = [8];
|
||||
proto.cc.arduino.cli.commands.v1.Platform.repeatedFields_ = [8,11];
|
||||
|
||||
|
||||
|
||||
@@ -1030,7 +1030,8 @@ proto.cc.arduino.cli.commands.v1.Platform.toObject = function(includeInstance, m
|
||||
boardsList: jspb.Message.toObjectList(msg.getBoardsList(),
|
||||
proto.cc.arduino.cli.commands.v1.Board.toObject, includeInstance),
|
||||
manuallyInstalled: jspb.Message.getBooleanFieldWithDefault(msg, 9, false),
|
||||
deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 10, false)
|
||||
deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 10, false),
|
||||
typeList: (f = jspb.Message.getRepeatedField(msg, 11)) == null ? undefined : f
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@@ -1108,6 +1109,10 @@ proto.cc.arduino.cli.commands.v1.Platform.deserializeBinaryFromReader = function
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setDeprecated(value);
|
||||
break;
|
||||
case 11:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.addType(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
@@ -1208,6 +1213,13 @@ proto.cc.arduino.cli.commands.v1.Platform.serializeBinaryToWriter = function(mes
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getTypeList();
|
||||
if (f.length > 0) {
|
||||
writer.writeRepeatedString(
|
||||
11,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1411,6 +1423,43 @@ proto.cc.arduino.cli.commands.v1.Platform.prototype.setDeprecated = function(val
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* repeated string type = 11;
|
||||
* @return {!Array<string>}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.Platform.prototype.getTypeList = function() {
|
||||
return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 11));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Array<string>} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.Platform.prototype.setTypeList = function(value) {
|
||||
return jspb.Message.setField(this, 11, value || []);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @param {number=} opt_index
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.Platform.prototype.addType = function(value, opt_index) {
|
||||
return jspb.Message.addToRepeatedField(this, 11, value, opt_index);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the list making it empty but non-null.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.Platform.prototype.clearTypeList = function() {
|
||||
return this.setTypeList([]);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -134,6 +134,69 @@ export namespace LibraryInstallResponse {
|
||||
}
|
||||
}
|
||||
|
||||
export class LibraryUpgradeRequest extends jspb.Message {
|
||||
|
||||
hasInstance(): boolean;
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibraryUpgradeRequest;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): LibraryUpgradeRequest;
|
||||
|
||||
getNoDeps(): boolean;
|
||||
setNoDeps(value: boolean): LibraryUpgradeRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryUpgradeRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryUpgradeRequest): LibraryUpgradeRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: LibraryUpgradeRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): LibraryUpgradeRequest;
|
||||
static deserializeBinaryFromReader(message: LibraryUpgradeRequest, reader: jspb.BinaryReader): LibraryUpgradeRequest;
|
||||
}
|
||||
|
||||
export namespace LibraryUpgradeRequest {
|
||||
export type AsObject = {
|
||||
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
|
||||
name: string,
|
||||
noDeps: boolean,
|
||||
}
|
||||
}
|
||||
|
||||
export class LibraryUpgradeResponse extends jspb.Message {
|
||||
|
||||
hasProgress(): boolean;
|
||||
clearProgress(): void;
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): LibraryUpgradeResponse;
|
||||
|
||||
|
||||
hasTaskProgress(): boolean;
|
||||
clearTaskProgress(): void;
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): LibraryUpgradeResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryUpgradeResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryUpgradeResponse): LibraryUpgradeResponse.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: LibraryUpgradeResponse, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): LibraryUpgradeResponse;
|
||||
static deserializeBinaryFromReader(message: LibraryUpgradeResponse, reader: jspb.BinaryReader): LibraryUpgradeResponse;
|
||||
}
|
||||
|
||||
export namespace LibraryUpgradeResponse {
|
||||
export type AsObject = {
|
||||
progress?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress.AsObject,
|
||||
taskProgress?: cc_arduino_cli_commands_v1_common_pb.TaskProgress.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
export class LibraryUninstallRequest extends jspb.Message {
|
||||
|
||||
hasInstance(): boolean;
|
||||
|
||||
@@ -42,6 +42,8 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LibraryUninstallRequest', nu
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LibraryUninstallResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LibraryUpgradeAllRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LibraryUpgradeAllResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SearchedLibrary', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.ZipLibraryInstallRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.ZipLibraryInstallResponse', null, global);
|
||||
@@ -129,6 +131,48 @@ if (goog.DEBUG && !COMPILED) {
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryInstallResponse.displayName = 'proto.cc.arduino.cli.commands.v1.LibraryInstallResponse';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.displayName = 'proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.displayName = 'proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
@@ -1408,6 +1452,419 @@ proto.cc.arduino.cli.commands.v1.LibraryInstallResponse.prototype.hasTaskProgres
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
|
||||
name: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
noDeps: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest;
|
||||
return proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.Instance;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Instance.deserializeBinaryFromReader);
|
||||
msg.setInstance(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setName(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setNoDeps(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getInstance();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
1,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.Instance.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getName();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getNoDeps();
|
||||
if (f) {
|
||||
writer.writeBool(
|
||||
3,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional Instance instance = 1;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.Instance}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.getInstance = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.Instance} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Instance, 1));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.Instance|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.setInstance = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.clearInstance = function() {
|
||||
return this.setInstance(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.hasInstance = function() {
|
||||
return jspb.Message.getField(this, 1) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string name = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.getName = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.setName = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional bool no_deps = 3;
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.getNoDeps = function() {
|
||||
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeRequest.prototype.setNoDeps = function(value) {
|
||||
return jspb.Message.setProto3BooleanField(this, 3, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
progress: (f = msg.getProgress()) && cc_arduino_cli_commands_v1_common_pb.DownloadProgress.toObject(includeInstance, f),
|
||||
taskProgress: (f = msg.getTaskProgress()) && cc_arduino_cli_commands_v1_common_pb.TaskProgress.toObject(includeInstance, f)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse;
|
||||
return proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.DownloadProgress;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.DownloadProgress.deserializeBinaryFromReader);
|
||||
msg.setProgress(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.TaskProgress;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.TaskProgress.deserializeBinaryFromReader);
|
||||
msg.setTaskProgress(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getProgress();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
1,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.DownloadProgress.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getTaskProgress();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
2,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.TaskProgress.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional DownloadProgress progress = 1;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.DownloadProgress}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.getProgress = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.DownloadProgress} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.DownloadProgress, 1));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.DownloadProgress|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.setProgress = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.clearProgress = function() {
|
||||
return this.setProgress(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.hasProgress = function() {
|
||||
return jspb.Message.getField(this, 1) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional TaskProgress task_progress = 2;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.TaskProgress}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.getTaskProgress = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.TaskProgress} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.TaskProgress, 2));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.TaskProgress|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.setTaskProgress = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.clearTaskProgress = function() {
|
||||
return this.setTaskProgress(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibraryUpgradeResponse.prototype.hasTaskProgress = function() {
|
||||
return jspb.Message.getField(this, 2) != null;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
LibraryDependency,
|
||||
LibraryLocation,
|
||||
LibraryPackage,
|
||||
LibrarySearch,
|
||||
LibraryService,
|
||||
} from '../common/protocol/library-service';
|
||||
import { CoreClientAware } from './core-client-provider';
|
||||
@@ -26,6 +27,7 @@ import { ILogger, notEmpty } from '@theia/core';
|
||||
import { FileUri } from '@theia/core/lib/node';
|
||||
import { ResponseService, NotificationServiceServer } from '../common/protocol';
|
||||
import { ExecuteWithProgress } from './grpc-progressible';
|
||||
import { duration } from '../common/decorators';
|
||||
|
||||
@injectable()
|
||||
export class LibraryServiceImpl
|
||||
@@ -44,7 +46,8 @@ export class LibraryServiceImpl
|
||||
@inject(NotificationServiceServer)
|
||||
protected readonly notificationServer: NotificationServiceServer;
|
||||
|
||||
async search(options: { query?: string }): Promise<LibraryPackage[]> {
|
||||
@duration()
|
||||
async search(options: LibrarySearch): Promise<LibraryPackage[]> {
|
||||
const coreClient = await this.coreClient;
|
||||
const { client, instance } = coreClient;
|
||||
|
||||
@@ -78,7 +81,6 @@ export class LibraryServiceImpl
|
||||
const items = resp
|
||||
.getLibrariesList()
|
||||
.filter((item) => !!item.getLatest())
|
||||
.slice(0, 50)
|
||||
.map((item) => {
|
||||
// TODO: This seems to contain only the latest item instead of all of the items.
|
||||
const availableVersions = item
|
||||
@@ -103,7 +105,42 @@ export class LibraryServiceImpl
|
||||
);
|
||||
});
|
||||
|
||||
return items;
|
||||
const typePredicate = this.typePredicate(options);
|
||||
const topicPredicate = this.topicPredicate(options);
|
||||
return items.filter((item) => typePredicate(item) && topicPredicate(item));
|
||||
}
|
||||
|
||||
private typePredicate(
|
||||
options: LibrarySearch
|
||||
): (item: LibraryPackage) => boolean {
|
||||
const { type } = options;
|
||||
if (!type || type === 'All') {
|
||||
return () => true;
|
||||
}
|
||||
switch (options.type) {
|
||||
case 'Installed':
|
||||
return Installable.Installed;
|
||||
case 'Updatable':
|
||||
return Installable.Updateable;
|
||||
case 'Arduino':
|
||||
case 'Partner':
|
||||
case 'Recommended':
|
||||
case 'Contributed':
|
||||
case 'Retired':
|
||||
return ({ types }: LibraryPackage) => !!types && types.includes(type);
|
||||
default:
|
||||
throw new Error(`Unhandled type: ${options.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
private topicPredicate(
|
||||
options: LibrarySearch
|
||||
): (item: LibraryPackage) => boolean {
|
||||
const { topic } = options;
|
||||
if (!topic || topic === 'All') {
|
||||
return () => true;
|
||||
}
|
||||
return (item: LibraryPackage) => item.category === topic;
|
||||
}
|
||||
|
||||
async list({
|
||||
@@ -408,5 +445,7 @@ function toLibrary(
|
||||
description: lib.getSentence(),
|
||||
moreInfoLink: lib.getWebsite(),
|
||||
summary: lib.getParagraph(),
|
||||
category: lib.getCategory(),
|
||||
types: lib.getTypesList(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ export const aPackage: BoardsPackage = {
|
||||
moreInfoLink: 'http://www.some-url.lol/',
|
||||
name: 'Some Arduino Package',
|
||||
summary: 'Boards included in this package:',
|
||||
types: ['Arduino'],
|
||||
};
|
||||
|
||||
export const anInstalledPackage: BoardsPackage = {
|
||||
|
||||
Reference in New Issue
Block a user