Skip to content

Commit

Permalink
Fix updating items in the quick-pick menu (#10065)
Browse files Browse the repository at this point in the history
Rework the quick-input API to use the $createOrUpdate method in the step of initialising the quick-pick instead of using a separate method $showCustomQuickPick
  • Loading branch information
vinokurig authored Sep 14, 2021
1 parent 8df74a7 commit 4924bc7
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 136 deletions.
4 changes: 4 additions & 0 deletions packages/core/src/browser/quick-input/quick-input-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ export interface QuickInputService {
Promise<(O extends { canPickMany: true } ? T[] : T) | undefined>;
showQuickPick<T extends QuickPickItem>(items: Array<T>, options?: QuickPickOptions<T>): Promise<T>;
hide(): void;
/**
* Provides raw access to the quick pick controller.
*/
createQuickPick<T extends QuickPickItem>(): QuickPick<T>;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions packages/monaco/src/browser/monaco-quick-input-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,12 @@ export class MonacoQuickInputService implements QuickInputService {
return item;
});
}

createQuickPick<T extends QuickPickItem>(): QuickPick<T> {
const quickPick = this.monacoService.createQuickPick<MonacoQuickPickItem<T>>();
return this.wrapQuickPick(quickPick);
}

wrapQuickPick<T extends QuickPickItem>(wrapped: monaco.quickInput.IQuickPick<MonacoQuickPickItem<T>>): QuickPick<T> {
return new MonacoQuickPick(wrapped, this.keybindingRegistry);
}
Expand Down
1 change: 0 additions & 1 deletion packages/plugin-ext/src/common/plugin-api-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,6 @@ export interface QuickOpenMain {

$hide(): void;
$showInputBox(options: TransferInputBox, validateInput: boolean): Promise<string | undefined>;
$showCustomQuickPick<T extends theia.QuickPickItem>(options: TransferQuickPick<T>): void;
}

export interface WorkspaceMain {
Expand Down
161 changes: 53 additions & 108 deletions packages/plugin-ext/src/main/browser/quick-open-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,25 @@
********************************************************************************/
/* eslint-disable @typescript-eslint/no-explicit-any */

import { InputBoxOptions, QuickPickItem as QuickPickItemExt } from '@theia/plugin';
import { InputBoxOptions } from '@theia/plugin';
import { interfaces } from '@theia/core/shared/inversify';
import { RPCProtocol } from '../../common/rpc-protocol';
import {
QuickOpenExt,
QuickOpenMain,
MAIN_RPC_CONTEXT,
TransferInputBox,
TransferQuickPick,
TransferQuickPickItems,
TransferQuickInput,
TransferQuickInputButton
} from '../../common/plugin-api-rpc';
import {
InputOptions, PickOptions, QuickInputButton, QuickInputService, QuickPickItem, QuickPickValue
InputOptions,
PickOptions,
QuickInputButton,
QuickInputButtonHandle,
QuickInputService
} from '@theia/core/lib/browser';
import { QuickPickService } from '@theia/core/lib/common/quick-pick-service';
import { DisposableCollection, Disposable } from '@theia/core/lib/common/disposable';
import { CancellationToken } from '@theia/core/lib/common/cancellation';
import { MonacoQuickInputService } from '@theia/monaco/lib/browser/monaco-quick-input-service';
Expand All @@ -47,7 +49,6 @@ export interface QuickInputSession {
export class QuickOpenMainImpl implements QuickOpenMain, Disposable {

private quickInputService: QuickInputService;
private quickPickService: QuickPickService;
private proxy: QuickOpenExt;
private delegate: MonacoQuickInputService;
private readonly items: Record<number, {
Expand All @@ -61,7 +62,6 @@ export class QuickOpenMainImpl implements QuickOpenMain, Disposable {
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.QUICK_OPEN_EXT);
this.delegate = container.get(MonacoQuickInputService);
this.quickInputService = container.get(QuickInputService);
this.quickPickService = container.get(QuickPickService);
}

dispose(): void {
Expand Down Expand Up @@ -196,52 +196,53 @@ export class QuickOpenMainImpl implements QuickOpenMain, Disposable {

$createOrUpdate<T extends theia.QuickPickItem>(params: TransferQuickInput<T>): Promise<void> {
const sessionId = params.id;
const session = this.sessions.get(sessionId);
// if (!session) {
// if (params.type === 'quickPick') {
// const quickPick = this.quickInputService.createQuickPick();
// quickPick.onDidAccept(() => {
// this.proxy.$acceptOnDidAccept(sessionId);
// });
// quickPick.onDidChangeActive((items: Array<monaco.quickInput.IQuickPickItem>) => {
// this.proxy.$onDidChangeActive(sessionId, items.map(item => (item as TransferQuickPickItems).handle));
// });
// quickPick.onDidChangeSelection((items: Array<monaco.quickInput.IQuickPickItem>) => {
// this.proxy.$onDidChangeSelection(sessionId, items.map(item => (item as TransferQuickPickItems).handle));
// });
// quickPick.onDidTriggerButton((button: QuickInputButtonHandle) => {
// this.proxy.$acceptOnDidTriggerButton(sessionId, button);
// });
// quickPick.onDidChangeValue((value: string) => {
// this.proxy.$acceptDidChangeValue(sessionId, value);
// });
// quickPick.onDidHide(() => {
// this.proxy.$acceptOnDidHide(sessionId);
// });
// session = {
// input: quickPick,
// handlesToItems: new Map()
// };
// } else {
// const inputBox = this.quickInputService.createInputBox();
// inputBox.onDidAccept(() => {
// this.proxy.$acceptOnDidAccept(sessionId);
// });
// inputBox.onDidTriggerButton((button: QuickInputButtonHandle) => {
// this.proxy.$acceptOnDidTriggerButton(sessionId, button);
// });
// inputBox.onDidChangeValue((value: string) => {
// this.proxy.$acceptDidChangeValue(sessionId, value);
// });
// inputBox.onDidHide(() => {
// this.proxy.$acceptOnDidHide(sessionId);
// });
// session = {
// input: inputBox,
// handlesToItems: new Map()
// };
// }
// }
let session = this.sessions.get(sessionId);
if (!session) {
if (params.type === 'quickPick') {
const quickPick = this.quickInputService.createQuickPick();
quickPick.onDidAccept(() => {
this.proxy.$acceptOnDidAccept(sessionId);
});
quickPick.onDidChangeActive((items: Array<monaco.quickInput.IQuickPickItem>) => {
this.proxy.$onDidChangeActive(sessionId, items.map(item => (item as TransferQuickPickItems).handle));
});
quickPick.onDidChangeSelection((items: Array<monaco.quickInput.IQuickPickItem>) => {
this.proxy.$onDidChangeSelection(sessionId, items.map(item => (item as TransferQuickPickItems).handle));
});
quickPick.onDidTriggerButton((button: QuickInputButtonHandle) => {
this.proxy.$acceptOnDidTriggerButton(sessionId, button);
});
quickPick.onDidChangeValue((value: string) => {
this.proxy.$acceptDidChangeValue(sessionId, value);
});
quickPick.onDidHide(() => {
this.proxy.$acceptOnDidHide(sessionId);
});
session = {
input: quickPick,
handlesToItems: new Map()
};
} else {
const inputBox = this.quickInputService.createInputBox();
inputBox.onDidAccept(() => {
this.proxy.$acceptOnDidAccept(sessionId);
});
inputBox.onDidTriggerButton((button: QuickInputButtonHandle) => {
this.proxy.$acceptOnDidTriggerButton(sessionId, button);
});
inputBox.onDidChangeValue((value: string) => {
this.proxy.$acceptDidChangeValue(sessionId, value);
});
inputBox.onDidHide(() => {
this.proxy.$acceptOnDidHide(sessionId);
});
session = {
input: inputBox,
handlesToItems: new Map()
};
}
this.sessions.set(sessionId, session);
}
if (session) {
const { input, handlesToItems } = session;
for (const param in params) {
Expand Down Expand Up @@ -297,47 +298,6 @@ export class QuickOpenMainImpl implements QuickOpenMain, Disposable {
return Promise.resolve(undefined);
}

async $showCustomQuickPick<T extends QuickPickItemExt>(options: TransferQuickPick<T>): Promise<void> {
const sessionId = options.id;
const toDispose = new DisposableCollection();

toDispose.push(this.quickPickService.onDidAccept(() => {
this.proxy.$acceptOnDidAccept(sessionId);
}));
toDispose.push(this.quickPickService.onDidChangeActive((e: { quickPick: any, activeItems: Array<QuickPickValue<number>> }) => {
this.proxy.$onDidChangeActive(sessionId, e.activeItems.map(item => item.value!));
}));
toDispose.push(this.quickPickService.onDidChangeSelection((e: { quickPick: any, selectedItems: Array<QuickPickValue<number>> }) => {
this.proxy.$onDidChangeSelection(sessionId, e.selectedItems.map(item => item.value!));
}));
toDispose.push(this.quickPickService.onDidChangeValue((e: { quickPick: any, filter: string }) => {
this.proxy.$acceptDidChangeValue(sessionId, e.filter);
}));
toDispose.push(this.quickPickService.onDidTriggerButton(button => {
this.proxy.$acceptOnDidTriggerButton(sessionId, button);
}));
toDispose.push(this.quickPickService.onDidHide(() => {
this.proxy.$acceptOnDidHide(sessionId);
if (!toDispose.disposed) {
toDispose.dispose();
}
}));
this.toDispose.push(toDispose);

this.quickPickService.show(this.convertToQuickPickItem(options.items), {
buttons: options.buttons ? this.convertToQuickInputButtons(options.buttons) : [],
placeholder: options.placeholder,
matchOnDescription: options.matchOnDescription,
step: options.step,
title: options.title,
totalSteps: options.totalSteps,
ignoreFocusOut: options.ignoreFocusOut,
value: options.value,
matchOnLabel: true,
runIfSingle: false,
});
}

$hide(): void {
this.delegate.hide();
}
Expand All @@ -351,21 +311,6 @@ export class QuickOpenMainImpl implements QuickOpenMain, Disposable {
return Promise.resolve(undefined);
}

private convertToQuickPickItem(items: TransferQuickPickItems[] | undefined): Array<QuickPickItem> {
const convertedItems: QuickPickValue<number>[] = [];
if (items) {
for (const i of items) {
convertedItems.push({
label: i.label,
description: i.description,
detail: i.detail,
value: i.handle
});
}
}
return convertedItems;
}

private convertToQuickInputButtons(buttons: Array<TransferQuickInputButton>): Array<QuickInputButton> {
return buttons.map((button, i) => ({
iconPath: getIconUris(button.iconPath),
Expand Down
30 changes: 3 additions & 27 deletions packages/plugin-ext/src/plugin/quick-open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
QuickOpenExt, PLUGIN_RPC_CONTEXT as Ext, QuickOpenMain, TransferInputBox, Plugin,
Item, TransferQuickInputButton, TransferQuickPickItems, TransferQuickInput, TransferQuickPick
Item, TransferQuickInputButton, TransferQuickPickItems, TransferQuickInput
} from '../common/plugin-api-rpc';
import * as theia from '@theia/plugin';
import { QuickPickItem, InputBoxOptions, InputBox, QuickPick, QuickInput } from '@theia/plugin';
Expand Down Expand Up @@ -178,10 +178,6 @@ export class QuickOpenExtImpl implements QuickOpenExt {
return session;
}

showCustomQuickPick<T extends QuickPickItem>(options: TransferQuickPick<T>): void {
this.proxy.$showCustomQuickPick(options);
}

hide(): void {
this.proxy.$hide();
}
Expand Down Expand Up @@ -389,6 +385,7 @@ export class QuickInputExt implements QuickInput {
this._fireHide();
this.disposableCollection.dispose();
this._onDidDispose();
this.quickOpenMain.$dispose(this._id);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -616,6 +613,7 @@ export class QuickPickExt<T extends theia.QuickPickItem> extends QuickInputExt i
this._handlesToItems.set(i, item);
this._itemsToHandles.set(item, i);
});
items.forEach((item, i) => Object.assign(item, { handle: i }));
this.update({
items
});
Expand Down Expand Up @@ -690,26 +688,4 @@ export class QuickPickExt<T extends theia.QuickPickItem> extends QuickInputExt i
this._selectedItems = items;
this._onDidChangeSelectionEmitter.fire(items);
}

show(): void {
super.show();
this.quickOpen.showCustomQuickPick({
id: this._id,
title: this.title,
step: this.step,
totalSteps: this.totalSteps,
enabled: this.enabled,
busy: this.busy,
ignoreFocusOut: this.ignoreFocusOut,
value: this.value,
placeholder: this.placeholder,
buttons: this.buttons,
items: convertToTransferQuickPickItems(this.items),
canSelectMany: this.canSelectMany,
matchOnDescription: this.matchOnDescription,
matchOnDetail: this.matchOnDetail,
activeItems: this.activeItems,
selectedItems: this.selectedItems
});
}
}

0 comments on commit 4924bc7

Please sign in to comment.